Introduce
Curve secp256k1
The elliptic curve domain parameters over associated with a Koblitz curve secp256k1
are specified by the sextuple where the finite field is defined by:
p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
=
The curve over is defined by:
a = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007
The base point in compressed form is:
G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
and in uncompressed form is:
G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798
483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8
Finally the order of and the cofactor are:
n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
h = 01
Pub key to Addr
Private key to Addr
Java Code
public class BTCAddressGenerator {
public static void main(String[] args) {
String keyHex = "F1A679C2DFF382267856E40066F083ED8A78D6F02DDD6CA8C30B27AC691F0109";
ECNamedCurveParameterSpec ecn = ECNamedCurveTable.getParameterSpec("secp256k1");
BigInteger k = new BigInteger(1, Bytes.fromHex(keyHex).bytes());
ECPoint pubK = ecn.getG().multiply(k).normalize();
System.out.println("X: " + Bytes.from(pubK.getAffineXCoord().getEncoded()).asHex());
System.out.println("Y: " + Bytes.from(pubK.getAffineYCoord().getEncoded()).asHex());
Bytes ripemd160sha256 = Bytes.from(pubK.getEncoded(false)).digest(Digests.sha256()).digest(Digests.ripemd160());
Bytes addr1 = Bytes.fromHex("00").concat(ripemd160sha256);
Bytes addr1sha256sha256 = addr1.digest(Digests.sha256()).digest(Digests.sha256());
Bytes finalAddr = addr1.concat(addr1sha256sha256.head(4));
System.out.println("ADDR: " + finalAddr.asBase58());
{
Bytes extended = Bytes.fromHex("80").concat(Bytes.fromHex(keyHex));
Bytes checksum = extended.digest(Digests.sha256()).digest(Digests.sha256()).head(4);
System.out.println("WIF: " + extended.concat(checksum).asBase58());
}
{
Bytes extended = Bytes.fromHex("80").concat(Bytes.fromHex(keyHex)).concat(Bytes.fromHex("01"));
Bytes checksum = extended.digest(Digests.sha256()).digest(Digests.sha256()).head(4);
System.out.println("WIF (compressed): " + extended.concat(checksum).asBase58());
}
}
}
Outputs:
X: 71e035f316b8bd48071060c397c1aa3c916a63f0ad6250f1250e03b7864bd8d4
Y: de40c5becb54be8ea34b0b7579c2b1e1ec9e4d987561cdce871798a9975ccfa4
ADDR: 1JxtdVzeksoDDLBtcRSdsuDGBrKWptdSmc
WIF: 5KeiDN58eVgkn9BoeTemHeHC32hFDf8pmCP2UGkVu5UaPaPabhk
WIF (compressed): L5KSua1EkVcUEF8gtLdgUTYThxUdksKXp5EDVNWzYrkiNCwqu2P8
Rust Code
BTC address implemention in Rust: h