Curve secp256k1

The elliptic curve domain parameters over $$$F_p$$$ associated with a Koblitz curve secp256k1 are specified by the sextuple $$$T = (p,a,b,G,n,h)$$$ where the finite field $$$F_p$$$ is defined by:

p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F
= $$$2^{256} - 2^{32} - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1$$$

The curve $$$E: y^2 = x^3+ax+b$$$ over $$$F_p$$$ is defined by:

a = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007

The base point $$$G$$$ 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 $$$n$$$ of $$$G$$$ and the cofactor are:

n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
h = 01

Pub key to Addr



Private key to Addr

$$$\text{Extneded} = \text{0x80}\, ||\, \overbrace{\text{Private\, Key}}^{256\,bit}\, ||\, \text{01}\\
\text{Checksum} = \text{SHA256(SHA256(Extended)).subBytes(0, 4)}\\
\text{Private\, WIF} = \text{Base58(Extened\, ||\, Checksum)}
$$$

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