So erhalten Sie einen komprimierten öffentlichen Schlüssel mit ECKey

Hier etwas Java-Code. Was muss ich ändern, um eine komprimierte öffentliche Adresse in getPublicAddress zu erhalten?

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();
    }

}
Diese Frage ist ein bisschen "nicht logisch". Normalerweise konvertiert man nicht zwischen unkomprimierten und komprimierten Pubkeys. Die Gefahr besteht darin, unverbrauchbare Ausgaben zu erzeugen. Stattdessen würde man komprimierte oder unkomprimierte Pubkeys aus den entsprechenden privaten Schlüsseln ableiten (man spricht hier manchmal von komprimierten oder unkomprimierten WIF-Schlüsseln). Zu WIF-Schlüsseln gab es hier nur einen Thread: bitcoin.stackexchange.com/questions/68065/…
Warum nicht logisch? Das ist die Frage - komprimierten Pubkey (in getPublicAddress?) Aus dem entsprechenden privaten Schlüssel von createAddress abzuleiten.
Sie müssen „neue Eckey“ mit komprimierter Markierung abrufen, dann komprimierter öffentlicher WIF-Schlüssel in getPublicAddress.
ah, habe das nicht aus der Frage verstanden :-) Um zum komprimierten Pubkey zu gelangen, benötigen Sie einen "komprimierten WIF" -Schlüssel. Dies wird vom privaten Schlüssel mit einem Hexadezimalzeichen „01“ am Ende abgeleitet und base58-codiert. Ich programmiere nicht in Java und habe keine ECKey-Bibliotheksdetails, zumal ich keine base58-Codierung sehe - also gibt ECKey createAddress() Ihren Schlüssel zurück, von dem ich annehme, dass er das 32-Byte-Hex-Schlüsselformat ist. Dann scheint die Funktion address.getPubKey() einen Standard-Pubkey (unkomprimiert) abzuleiten. Vielleicht hat die Bibliothek address.getCompressedPubKey() ?
Nein, Bullshit ... habe noch einmal nachgelesen. Der WIF-c-Schlüssel wird nur benötigt, um das Wallet zu „raten“, Privkeys im komprimierten Format zu erstellen. Am Ende, wenn ein unkomprimierter Pubkey erstellt wird, ist seine Hex-Darstellung "04" + "x" + "y". Ein komprimierter Pubkey ist dann ein „02“ (für gerades y) oder „03“ (ungerades) + „x“. Ich überlasse es den JAVA-Experten dieser Bibliotheken, wo sie den richtigen Code finden ...

Antworten (4)

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

wobei dk der deterministische Schlüssel ist

oder

key.decompress().getPubKey();

wobei Schlüssel der ECKey ist

Falls jemand Komprimierung in seinem Code implementieren möchte:

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();

LegacyAddress verwenden:

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();
}