Как получить сжатый открытый ключ с помощью ECKey

Вот некоторый код Java. Что мне нужно изменить, чтобы получить сжатый публичный адрес в getPublicAddress?

import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.ECKey;
import com.google.bitcoin.params.MainNetParams;
import org.spongycastle.crypto.digests.RIPEMD160Digest;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class DigestUtil {

    public static byte[] RIPEMD160(byte[] input) {
        RIPEMD160Digest d = new RIPEMD160Digest();

        d.update(input, 0, input.length);

        byte[] o = new byte[d.getDigestSize()];

        d.doFinal(o, 0);

        return o;
    }

    public static byte[] SHA256(byte[] input) {
        byte[] hash = null;

        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(input);
            hash = md.digest();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return hash;
    }

    public static ECKey createAddress(byte[] secret) {
        byte[] hash = SHA256(secret);

        ECKey key = new ECKey(hash, null);

        return key;
    }

    public static String getPublicAddress(String input) {
        ECKey address = createAddress(input.getBytes());

        byte[] hash160 = RIPEMD160(SHA256(address.getPubKey()));

        Address addr = new Address(MainNetParams.get(), hash160);

        return addr.toString();
    }

}
этот вопрос немного "нелогичен". Обычно никто не конвертирует между несжатыми и сжатыми публичными ключами. Опасность заключается в создании нерасходуемых продуктов. Вместо этого можно было бы получить сжатые или несжатые открытые ключи из соответствующих закрытых ключей (здесь люди иногда говорят о сжатых или несжатых ключах WIF). О ключах WIF здесь была только ветка: bitcoin.stackexchange.com/questions/68065/…
Почему без логики? Вот в чем вопрос - получить сжатый публичный ключ (в getPublicAddress?) из соответствующего приватного ключа из createAddress.
Нужно получить «новый Eckey» со сжатым маркером, затем сжатый открытый ключ WIF в getPublicAddress.
ах, не понял этого из вопроса :-) Чтобы получить сжатый публичный ключ, вам нужен «сжатый ключ WIF». Это получено из закрытого ключа с шестнадцатеричным «01» в конце и закодировано в base58. Я не программирую на Java, и у меня нет сведений о библиотеке ECKey, тем более что я не вижу какой-либо кодировки base58, поэтому ECKey createAddress() возвращает ваш ключ, который, как я полагаю, представляет собой 32-байтовый шестнадцатеричный формат ключа. Затем функция address.getPubKey(), кажется, выводит стандартный публичный ключ (несжатый). Может быть, в библиотеке есть address.getCompressedPubKey()?
нет, бред... перечитал. Ключ WIF-c нужен только для «советования» кошельку, для создания приватных ключей в сжатом формате. В конце, когда создается несжатый публичный ключ, его шестнадцатеричное представление будет «04» + «x» + «y». Сжатый открытый ключ — это «02» (для четного y) или «03» (нечетный) + «x». Я оставляю это экспертам JAVA этих библиотек, где найти правильный код ...

Ответы (4)

Address address = new Address(params, dk.decompress().getPubKeyHash());

где dk — детерминированный ключ

или

key.decompress().getPubKey();

где ключ - это ECKey

Если кто-то хочет реализовать сжатие в своем коде:

private static final String EVEN = "02";
private static final String ODD = "03";

public String compressPublicKey(String toCompress) {
    if (Integer.parseInt(toCompress.substring(128, 130), 16) % 2 == 0)
        return  EVEN + toCompress.substring(2, 66);
    return ODD + toCompress.substring(2, 66);
} 
private static final String EVEN = "02";
private static final String ODD = "03";

public String compressPublicKey(String toCompress) {
    if (Integer.parseInt(toCompress.substring(128, 130), 16) % 2 == 0)
        return  EVEN + toCompress.substring(2, 66);
    return ODD + toCompress.substring(2, 66);
} 1
โหวต
Address address = new Address(params, dk.decompress().getPubKeyHash())key.decompress().getPubKey();

использовать устаревший адрес:

public static String getPublicAddress(String input) {
    ECKey address = createAddress(input.getBytes());

    byte[] hash160 = RIPEMD160(SHA256(address.getPubKey()));

    LegacyAddress legacyAddress = LegacyAddress.fromPubKeyHash(MainNetParams.get(), hash160);
    return legacyAddress.toBase58();
}