![JAR search and dependency download from the Maven repository](/logo.png)
bip.com.unbound.common.crypto.BIP32 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
package com.unbound.common.crypto;
import com.unbound.common.Base58;
import com.unbound.common.Converter;
import com.unbound.common.HEX;
import java.math.BigInteger;
import java.util.Arrays;
public class BIP32
{
private final EC.Curve curve;
private EC.Point pub = null;
private final byte level;
private final int childNumber;
private byte[] parentFingerprint = new byte[4];
private byte[] K = null;
private byte[] C = new byte[32];
public EC.Point getPublicKey()
{
if (pub==null) pub = curve.generator.mul(getPrivateKey());
return pub;
}
public int getChildNumber() { return childNumber; }
public byte getLevel() { return level; }
public byte[] getParentFingerprint() { return parentFingerprint; }
public byte[] getChainCode() { return C; }
public BigInteger getPrivateKey()
{
if (K==null) throw new IllegalArgumentException("Private key is absent");
return new BigInteger(1, K);
}
private BIP32(EC.Curve curve, byte level, int childNumber)
{
this.childNumber = childNumber;
this.level = level;
this.curve = curve;
}
public static BIP32 deriveFromMaster(EC.Curve curve, byte[] seed)
{
String hmacSeed;
if (curve==EC.P256) hmacSeed = "Nist256p1 seed";
else if (curve==EC.P256k) hmacSeed = "Bitcoin seed";
else throw new IllegalArgumentException("Curve not supported");
BIP32 result = new BIP32(curve, (byte)0, 0);
byte[] I = HMAC.SHA512.hmac(hmacSeed.getBytes(), seed);
BigInteger key = Converter.binToBigNum(I, 0, 32).mod(curve.order);
result.K = Converter.bigNumToBin(key, 32);
result.C = Arrays.copyOfRange(I, 32, 64);
return result;
}
public BIP32 derive(boolean hardened, int index)
{
if (index<0) throw new IllegalArgumentException("Negative index");
BigInteger oldK = getPrivateKey();
EC.Point point = getPublicKey();
byte[] pointOct = point.toCompressedOct();
byte[] I;
byte[] indexBuf = new byte[4];
if (hardened)
{
index|=0x80000000;
Converter.setBE4(indexBuf, 0, index);
I = new HMAC.SHA512(C).update((byte)0).update(K).update(indexBuf).end();
}
else
{
Converter.setBE4(indexBuf, 0, index);
I = new HMAC.SHA512(C).update(pointOct).update(indexBuf).end();
}
BigInteger delta = Converter.binToBigNum(I,0, 32);
BigInteger newK = oldK.add(delta).mod(curve.order);
BIP32 derived = new BIP32(curve, (byte)(level+1), index);
derived.K = Converter.bigNumToBin(newK, 32);
derived.C = Arrays.copyOfRange(I, 32, 64);
byte[] h = Ripemd160.hash(SHA256.hash(pointOct));
derived.parentFingerprint = Arrays.copyOfRange(h, 0, 4);
return derived;
}
public BIP32 derivePub(int index)
{
if (index<0) throw new IllegalArgumentException("Negative index");
EC.Point point = getPublicKey();
byte[] pointOct = point.toCompressedOct();
byte[] I;
byte[] indexBuf = new byte[4];
Converter.setBE4(indexBuf, 0, index);
I = new HMAC.SHA512(C).update(pointOct).update(indexBuf).end();
BigInteger delta = Converter.binToBigNum(I,0, 32);
BIP32 derived = new BIP32(curve, (byte)(level+1), index);
derived.C = Arrays.copyOfRange(I, 32, 64);
derived.pub = pub.add(curve.generator.mul(delta));
byte[] h = Ripemd160.hash(SHA256.hash(pointOct));
derived.parentFingerprint = Arrays.copyOfRange(h, 0, 4);
return derived;
}
private static String encodeBase58Check(byte[] bin)
{
byte[] hh = SHA256.hash(SHA256.hash(bin));
byte[] buf = new byte[bin.length+4];
System.arraycopy(bin, 0, buf, 0, bin.length);
System.arraycopy(hh, 0, buf, bin.length, 4);
return Base58.encode(buf);
}
private String serialize(int version, byte[] buf)
{
byte[] out = new byte[78];
Converter.setBE4(out, 0, version);
out[4] = level;
System.arraycopy(parentFingerprint, 0, out, 5, 4);
Converter.setBE4(out, 9, childNumber);
System.arraycopy(C, 0, out, 13, 32);
System.arraycopy(buf, 0, out, 78-buf.length, buf.length);
return encodeBase58Check(out);
}
public String serializePub()
{
return serializePub(true);
}
public String serializePub(boolean main)
{
EC.Point point = getPublicKey();
byte[] pointOct = point.toCompressedOct();
int version = main ? 0x0488B21E : 0x043587CF;
return serialize(version, pointOct);
}
public String serializePrv()
{
return serializePrv(true);
}
public String serializePrv(boolean main)
{
int version = main ? 0x0488ADE4 : 0x04358394;
return serialize(version, K);
}
/*
static class Test
{
public static void main(String[] args)
{
test_secp256k1();
test_secp256r1();
}
private static void test_bip_secp256r1(String seed, String path, String fingerprint, String chainCode, String prv, String pub)
{
byte[] seedBin = HEX.from(seed);
int p = 0;
int index = 0;
boolean hardened = false;
BIP32 node = null;
boolean has_node = false;
for (int i=0; i='0' && c<='9')
{
has_node = false;
hardened = false;
index = index * 10 + c-'0';
}
else
{
assert(false);
}
}
if (!has_node)
{
node = node.derive(hardened, index);
}
if (fingerprint!=null && !fingerprint.isEmpty())
{
byte[] f = HEX.from(fingerprint);
assert(Arrays.equals(f,node.getParentFingerprint()));
}
if (chainCode!=null && !chainCode.isEmpty())
{
byte[] c_par = HEX.from(chainCode);
assert(Arrays.equals(c_par,node.getChainCode()));
}
if (prv!=null && !prv.isEmpty())
{
if (prv.charAt(0)!='x')
{
byte[] prvBin = HEX.from(prv);
BigInteger x = new BigInteger(1, prvBin);
assert(x.equals(node.getPrivateKey()));
}
else
{
String s = node.serializePrv();
assert(s.equals(prv));
}
}
if (pub!=null && !pub.isEmpty())
{
if (pub.charAt(0)!='x')
{
byte[] pubBin = HEX.from(pub);
EC.Point point = EC.Point.fromOct(EC.P256, pubBin);
assert(point.equals(node.getPublicKey()));
}
else
{
String s = node.serializePub();
assert(s.equals(pub));
}
}
}
private static void test_secp256r1()
{
//https://github.com/satoshilabs/slips/blob/master/slip-0010.md
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m",
"00000000",
"beeb672fe4621673f722f38529c07392fecaa61015c80c34f29ce8b41b3cb6ea",
"612091aaa12e22dd2abef664f8a01a82cae99ad7441b7ef8110424915c268bc2",
"0266874dc6ade47b3ecd096745ca09bcd29638dd52c2c12117b11ed3e458cfa9e8");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'",
"be6105b5",
"3460cea53e6a6bb5fb391eeef3237ffd8724bf0a40e94943c98b83825342ee11",
"6939694369114c67917a182c59ddb8cafc3004e63ca5d3b84403ba8613debc0c",
"0384610f5ecffe8fda089363a41f56a5c7ffc1d81b59a612d0d649b2d22355590c");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'/1",
"9b02312f",
"4187afff1aafa8445010097fb99d23aee9f599450c7bd140b6826ac22ba21d0c",
"284e9d38d07d21e4e281b645089a94f4cf5a5a81369acf151a1c3a57f18b2129",
"03526c63f8d0b4bbbf9c80df553fe66742df4676b241dabefdef67733e070f6844");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'/1/2'",
"b98005c1",
"98c7514f562e64e74170cc3cf304ee1ce54d6b6da4f880f313e8204c2a185318",
"694596e8a54f252c960eb771a3c41e7e32496d03b954aeb90f61635b8e092aa7",
"0359cf160040778a4b14c5f4d7b76e327ccc8c4a6086dd9451b7482b5a4972dda0");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'/1/2'/2",
"0e9f3274",
"ba96f776a5c3907d7fd48bde5620ee374d4acfd540378476019eab70790c63a0",
"5996c37fd3dd2679039b23ed6f70b506c6b56b3cb5e424681fb0fa64caf82aaa",
"029f871f4cb9e1c97f9f4de9ccd0d4a2f2a171110c61178f84430062230833ff20");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'/1/2'/2/1000000000",
"8b2b5c4b",
"b9b7b82d326bb9cb5b5b121066feea4eb93d5241103c9e7a18aad40f1dde8059",
"21c4f269ef0a5fd1badf47eeacebeeaa3de22eb8e5b0adcd0f27dd99d34d0119",
"02216cd26d31147f72427a453c443ed2cde8a1e53c9cc44e5ddf739725413fe3f4");
test_bip_secp256r1(
"fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
"m",
"00000000",
"96cd4465a9644e31528eda3592aa35eb39a9527769ce1855beafc1b81055e75d",
"eaa31c2e46ca2962227cf21d73a7ef0ce8b31c756897521eb6c7b39796633357",
"02c9e16154474b3ed5b38218bb0463e008f89ee03e62d22fdcc8014beab25b48fa");
test_bip_secp256r1(
"fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
"m/0",
"607f628f",
"84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a",
"d7d065f63a62624888500cdb4f88b6d59c2927fee9e6d0cdff9cad555884df6e",
"039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc");
test_bip_secp256r1(
"fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
"m/0/2147483647'",
"946d2a54",
"f235b2bc5c04606ca9c30027a84f353acf4e4683edbd11f635d0dcc1cd106ea6",
"96d2ec9316746a75e7793684ed01e3d51194d81a42a3276858a5b7376d4b94b9",
"02f89c5deb1cae4fedc9905f98ae6cbf6cbab120d8cb85d5bd9a91a72f4c068c76");
test_bip_secp256r1(
"fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
"m/0/2147483647'/1",
"218182d8",
"7c0b833106235e452eba79d2bdd58d4086e663bc8cc55e9773d2b5eeda313f3b",
"974f9096ea6873a915910e82b29d7c338542ccde39d2064d1cc228f371542bbc",
"03abe0ad54c97c1d654c1852dfdc32d6d3e487e75fa16f0fd6304b9ceae4220c64");
test_bip_secp256r1(
"fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
"m/0/2147483647'/1/2147483646'",
"931223e4",
"5794e616eadaf33413aa309318a26ee0fd5163b70466de7a4512fd4b1a5c9e6a",
"da29649bbfaff095cd43819eda9a7be74236539a29094cd8336b07ed8d4eff63",
"03cb8cb067d248691808cd6b5a5a06b48e34ebac4d965cba33e6dc46fe13d9b933");
test_bip_secp256r1(
"fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542",
"m/0/2147483647'/1/2147483646'/2",
"956c4629",
"3bfb29ee8ac4484f09db09c2079b520ea5616df7820f071a20320366fbe226a7",
"bb0a77ba01cc31d77205d51d08bd313b979a71ef4de9b062f8958297e746bd67",
"020ee02e18967237cf62672983b253ee62fa4dd431f8243bfeccdf39dbe181387f");
//https://github.com/backslash47/hdkey-secp256r1/blob/master/test/fixtures/hdkey.json
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m",
"", "",
"xprv9s21ZrQH143K3xbxu53vDH2NWbLKw5edQ3BCSX12Pknr1EA7QjAZPnd2jYvGvZ9RSwbcfeCZ5v2qZTTESRMTiAizzfQ1GUDeMWPyaXGcMfF",
"xpub661MyMwAqRbcGSgS16avaQy74dApLYNUmG6oEuQdx6Kpt2VFxGUowawWaozRLQSe46f7nbyC5ZY8Tvvnc32WSiL3LSxFNvPgG84QVAyvBAw");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'",
"", "",
"xprv9vJJjmzMMcPT7vuRQ3RUihF5SFms7a4j1CPuxok5NYqMd5dWjwXnmLTh8CzdBZJwHUybU3gSkKEAm86C27yde9ziL2PmahvMQSPhWSVAyVb",
"xpub69Hf9HXFBywkLQytW4xV5qBozHcMX2naNRKWmC9gvtNLVsxfHUr3K8nAyWB6SFgSTJXtSoNqVPBjy5qeMcEb1EZhuPwUd7Sy2tSprcR3bN5");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'/1",
"", "",
"xprv9wvN2XR2jhXFtoRvikiU4HhtMgFanjvmmMhRHj5KMKtHi2PN9aZPjAVWDLrjUbi5qejuMeQ3jH4ysGCVjVMMgERS3zCpv9DgbSEeHBnmR5k",
"xpub6AuiS2wva55Z7HWPpnFURRecui65CCed8ad267UvufRGapiWh7seGxoz4e9nu9G1aBYqGsEV5RjhqLAjNWm294RZTgU8UgQ821iaPY5tazr");
test_bip_secp256r1(
"000102030405060708090a0b0c0d0e0f",
"m/0'/1/2'",
"", "",
"xprv9z2VpTyrSEs4AL8C9v1YLnB1eH8nJZHD3Je2xDsr6ZCkKPbuuJTQHNevwSHHzswEQqojkg9RnGZPFTwUA4e9q83KCKiCu7cFr7T2gWLtdcu",
"xpub6D1rDyWkGcRMNpCfFwYYhv7kCJyGi214QXZdkcHTetjjCBw4SqmeqAyQnj8zdxbg7xNC4JjE25XwWqxxEMKdx3vafV7J2FKJ6XEEi4hp3WE");
}
private static void test_secp256k1()
{
{
String seed_hex = "000102030405060708090a0b0c0d0e0f";
byte[] seed = HEX.from(seed_hex);
BIP32 m = BIP32.deriveFromMaster(EC.P256k, seed);
BIP32 m_0H = m.derive(true, 0);
BIP32 m_0H_1 = m_0H.derive(false, 1);
BIP32 m_0H_1_2H = m_0H_1.derive(true, 2);
BIP32 m_0H_1_2H_2 = m_0H_1_2H.derive(false, 2);
BIP32 m_0H_1_2H_2_1000000000 = m_0H_1_2H_2.derive(false, 1000000000);
assert(m_0H_1_2H_2_1000000000.getPublicKey().equals(m_0H_1_2H_2.derivePub(1000000000).getPublicKey()));
assert(m.serializePub().equals("xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"));
assert(m.serializePrv().equals("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"));
assert(m_0H.serializePub().equals("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw"));
assert(m_0H.serializePrv().equals("xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7"));
assert(m_0H_1.serializePub().equals("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ"));
assert(m_0H_1.serializePrv().equals("xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs"));
assert(m_0H_1_2H.serializePub().equals("xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5"));
assert(m_0H_1_2H.serializePrv().equals("xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM"));
assert(m_0H_1_2H_2.serializePub().equals("xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV"));
assert(m_0H_1_2H_2.serializePrv().equals("xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334"));
assert(m_0H_1_2H_2_1000000000.serializePub().equals("xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"));
assert(m_0H_1_2H_2_1000000000.serializePrv().equals("xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76"));
}
{
String seed_hex = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542";
byte[] seed = HEX.from(seed_hex);
BIP32 m = BIP32.deriveFromMaster(EC.P256k, seed);
BIP32 m_0 = m.derive(false, 0);
BIP32 m_0_2147483647H = m_0.derive(true, 2147483647);
BIP32 m_0_2147483647H_1 = m_0_2147483647H.derive(false, 1);
BIP32 m_0_2147483647H_1_2147483646H = m_0_2147483647H_1.derive(true, 2147483646);
BIP32 m_0_2147483647H_1_2147483646H_2 = m_0_2147483647H_1_2147483646H.derive(false, 2);
assert(m_0_2147483647H_1_2147483646H_2.getPublicKey().equals(m_0_2147483647H_1_2147483646H.derivePub(2).getPublicKey()));
assert(m.serializePub().equals("xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"));
assert(m.serializePrv().equals("xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U"));
assert(m_0.serializePub().equals("xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"));
assert(m_0.serializePrv().equals("xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt"));
assert(m_0_2147483647H.serializePub().equals("xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a"));
assert(m_0_2147483647H.serializePrv().equals("xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9"));
assert(m_0_2147483647H_1.serializePub().equals("xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon"));
assert(m_0_2147483647H_1.serializePrv().equals("xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef"));
assert(m_0_2147483647H_1_2147483646H.serializePub().equals("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"));
assert(m_0_2147483647H_1_2147483646H.serializePrv().equals("xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc"));
assert(m_0_2147483647H_1_2147483646H_2.serializePub().equals("xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt"));
assert(m_0_2147483647H_1_2147483646H_2.serializePrv().equals("xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j"));
}
{
String seed_hex = "4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be";
byte[] seed = HEX.from(seed_hex);
BIP32 m = BIP32.deriveFromMaster(EC.P256k, seed);
BIP32 m_0H = m.derive(true, 0);
assert(m.serializePub().equals("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13"));
assert(m.serializePrv().equals("xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6"));
assert(m_0H.serializePub().equals("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y"));
assert(m_0H.serializePrv().equals("xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L"));
}
}
}*/
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy