Skip to content

Instantly share code, notes, and snippets.

@etotheipi
Created April 27, 2012 21:19
Show Gist options
  • Save etotheipi/2513316 to your computer and use it in GitHub Desktop.
Save etotheipi/2513316 to your computer and use it in GitHub Desktop.
Child Key Derivation Test Vector(s)
Following is the test code I used. Generate the same sequences in both
private key space and public key space, make sure they generate the same
addresses.
Extended Keys are a triplet of (Priv, Pub, Chain). For extended public
keys, Priv is empty. When Priv is populated, Pub is computed.
-----------------------------------------------------------------------------------------------
// Confirm endianness of integer-to-binary
cout << endl;
cout << "Display two numbers in both LE and BE. Confirm byte-order:" << endl;
cout << " LE (5): " << BtcUtils::uint32ToBinaryLE(5).toHexStr() << endl;
cout << " LE (4095): " << BtcUtils::uint32ToBinaryLE(4095).toHexStr() << endl;
cout << " BE (5): " << BtcUtils::uint32ToBinaryBE(5).toHexStr() << endl;
cout << " BE (4095): " << BtcUtils::uint32ToBinaryBE(4095).toHexStr() << endl;
// Test Child Key Derivation (CKD).
BinaryData ckdTestVectors[] = {
BinaryData::CreateFromHex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
BinaryData::CreateFromHex("04"
"6a04ab98d9e4774ad806e302dddeb63b"
"ea16b5cb5f223ee77478e861bb583eb3"
"36b6fbcb60b5b3d4f1551ac45e5ffc49"
"36466e7d98f6c7c0ec736539f74691a6"),
BinaryData::CreateFromHex("dddddddddddddddddddddddddddddddd"
"dddddddddddddddddddddddddddddddd")
};
for(uint32_t i=0; i<1; i++)
{
SecureBinaryData priv( ckdTestVectors[3*i+0] );
SecureBinaryData pub( ckdTestVectors[3*i+1] );
SecureBinaryData chain( ckdTestVectors[3*i+2] );
//////////////////////////////////////////////////////////////////////////
// Start with an extended PRIVATE key
ExtendedKey ekprv = ExtendedKey().CreateFromPrivate(priv, chain);
// Create two accounts
ExtendedKey ekprv_0 = HDWalletCrypto().ChildKeyDeriv(ekprv, 0);
ExtendedKey ekprv_1 = HDWalletCrypto().ChildKeyDeriv(ekprv, 1);
// Create internal and external chain on Account 0
ExtendedKey ekprv_0_EX = HDWalletCrypto().ChildKeyDeriv(ekprv_0, HDW_CHAIN_EXTERNAL);
ExtendedKey ekprv_0_IN = HDWalletCrypto().ChildKeyDeriv(ekprv_0, HDW_CHAIN_INTERNAL);
// Create three addresses on external chain
ExtendedKey ekprv_0_EX_0 = HDWalletCrypto().ChildKeyDeriv(ekprv_0_EX, 0);
ExtendedKey ekprv_0_EX_1 = HDWalletCrypto().ChildKeyDeriv(ekprv_0_EX, 1);
ExtendedKey ekprv_0_EX_2 = HDWalletCrypto().ChildKeyDeriv(ekprv_0_EX, 2);
// Create three addresses on internal chain
ExtendedKey ekprv_0_IN_0 = HDWalletCrypto().ChildKeyDeriv(ekprv_0_IN, 0);
ExtendedKey ekprv_0_IN_1 = HDWalletCrypto().ChildKeyDeriv(ekprv_0_IN, 1);
ExtendedKey ekprv_0_IN_2 = HDWalletCrypto().ChildKeyDeriv(ekprv_0_IN, 2);
// Now add a few more addresses with very large indices
ExtendedKey ekprv_1_IN = HDWalletCrypto().ChildKeyDeriv(ekprv_1, HDW_CHAIN_INTERNAL);
ExtendedKey ekprv_1_IN_4095 = HDWalletCrypto().ChildKeyDeriv(ekprv_1_IN, 4095);
ExtendedKey ekprv_1_IN_4bil = HDWalletCrypto().ChildKeyDeriv(ekprv_1_IN, UINT32_MAX);
//////////////////////////////////////////////////////////////////////////
// Repeat the above with PUBLIC key
ExtendedKey ekpub = ExtendedKey().CreateFromPublic(pub, chain);
// Create two accounts
ExtendedKey ekpub_0 = HDWalletCrypto().ChildKeyDeriv(ekpub, 0);
ExtendedKey ekpub_1 = HDWalletCrypto().ChildKeyDeriv(ekpub, 1);
// Create internal and external chain on Account 0
ExtendedKey ekpub_0_EX = HDWalletCrypto().ChildKeyDeriv(ekpub_0, HDW_CHAIN_EXTERNAL);
ExtendedKey ekpub_0_IN = HDWalletCrypto().ChildKeyDeriv(ekpub_0, HDW_CHAIN_INTERNAL);
// Create three addresses on external chain
ExtendedKey ekpub_0_EX_0 = HDWalletCrypto().ChildKeyDeriv(ekpub_0_EX, 0);
ExtendedKey ekpub_0_EX_1 = HDWalletCrypto().ChildKeyDeriv(ekpub_0_EX, 1);
ExtendedKey ekpub_0_EX_2 = HDWalletCrypto().ChildKeyDeriv(ekpub_0_EX, 2);
// Create three addresses on internal chain
ExtendedKey ekpub_0_IN_0 = HDWalletCrypto().ChildKeyDeriv(ekpub_0_IN, 0);
ExtendedKey ekpub_0_IN_1 = HDWalletCrypto().ChildKeyDeriv(ekpub_0_IN, 1);
ExtendedKey ekpub_0_IN_2 = HDWalletCrypto().ChildKeyDeriv(ekpub_0_IN, 2);
// Now add a few more addresses with very large indices
ExtendedKey ekpub_1_IN = HDWalletCrypto().ChildKeyDeriv(ekpub_1, HDW_CHAIN_INTERNAL);
ExtendedKey ekpub_1_IN_4095 = HDWalletCrypto().ChildKeyDeriv(ekpub_1_IN, 4095);
ExtendedKey ekpub_1_IN_4bil = HDWalletCrypto().ChildKeyDeriv(ekpub_1_IN, UINT32_MAX);
cout << endl << endl;
cout << "Private-Public Tree Equality Tests:" << endl;
cout << " " << (ekprv.getPub()==
ekpub.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0.getPub()==
ekpub_0.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_1.getPub()==
ekpub_1.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0_IN.getPub()==
ekpub_0_IN.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0_IN_0.getPub()==
ekpub_0_IN_0.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0_IN_1.getPub()==
ekpub_0_IN_1.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0_IN_2.getPub()==
ekpub_0_IN_2.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0_EX_0.getPub()==
ekpub_0_EX_0.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0_EX_1.getPub()==
ekpub_0_EX_1.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_0_EX_2.getPub()==
ekpub_0_EX_2.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_1_IN.getPub()==
ekprv_1_IN.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_1_IN_4095.getPub()==
ekprv_1_IN_4095.getPub() ? "___PASSED___" : "***FAILED***") << endl;
cout << " " << (ekprv_1_IN_4bil.getPub()==
ekprv_1_IN_4bil.getPub() ? "___PASSED___" : "***FAILED***") << endl;
//////////////////////////////////////////////////////////////////////////
// Start with an extended PRIVATE key
cout << endl << endl;
cout << "PRIVATE Key Tree: " << endl;
ekprv.debugPrint();
ekprv_0.debugPrint();
ekprv_1.debugPrint();
ekprv_0_EX.debugPrint();
ekprv_0_IN.debugPrint();
ekprv_0_EX_0.debugPrint();
ekprv_0_EX_1.debugPrint();
ekprv_0_EX_2.debugPrint();
ekprv_0_IN_0.debugPrint();
ekprv_0_IN_1.debugPrint();
ekprv_0_IN_2.debugPrint();
ekprv_1_IN.debugPrint();
ekprv_1_IN_4095.debugPrint();
ekprv_1_IN_4bil.debugPrint();
}
-----------------------------------------------------------------------------------------------
Output of the above code using EncryptionUtils in Armory:
...
Display two numbers in both LE and BE. Confirm byte-order:
LE (5): 05000000
LE (4095): ff0f0000
BE (5): 00000005
BE (4095): 00000fff
Private-Public Tree Equality Tests:
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
___PASSED___
PRIVATE Key Tree:
Indices: M
Fingerprint: Self: d8da0e72 Parent:
Private Key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Public Key: 026a04ab98d9e4774ad806e302dddeb63bea16b5cb5f223ee77478e861bb583eb3
Chain Code: dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
Indices: M/0
Fingerprint: Self: 254e487b Parent: d8da0e72
Private Key: c677f7e86462f30d22eaf35798206c5df65080e9b80378232896a06f24350e7e
Public Key: 035acb1286d1f1a236418166739a20ba8e64a5ff3d7a5d5bb926c079b1b57c47fb
Chain Code: 38f8418a58c4519cbc652d41cbaf29a069b52a0e0825474a3b1b70628854c1fb
Indices: M/1
Fingerprint: Self: 2cd5b896 Parent: d8da0e72
Private Key: 9affe2ba65a020a102ff1685da2b8bbf8d25905c8e256613fe517d8a61df1234
Public Key: 027ad1d2d23ad6d33ec066ff5f3d9dafcdfae568bd63ebf1c39a930c40f148343b
Chain Code: c6fd4ddd712f3501965c212d7b70ff0e49f1a1c4a5b28e7ae43b40d7e8c31f87
Indices: M/0/0
Fingerprint: Self: 7b17cd9d Parent: 254e487b
Private Key: d15f204595f54e2debded3a57e16df2acdd295f31b0ac7d242aaea4ea76a51a9
Public Key: 020432ee4f244c5766bf65bfcfa880887aec8059f9227a2d37f18aabb375dc810f
Chain Code: c3487013281c251092fddedb6045f3437424803d91584976cf0aac2e60d3f34e
Indices: M/0/1
Fingerprint: Self: 343b00e2 Parent: 254e487b
Private Key: 67e7a036d42ba55f1f3371ed2d6684f661189a430f4087a5e48f85c53a4042c7
Public Key: 033fdf5b94b9d749307db9410f3e611a26e87a8500ab844e6580b0f08288dd06df
Chain Code: b146a80fd1e9c6b65feebe5d06445a160c493158bce1ba591a73524e51a8b7fa
Indices: M/0/0/0
Fingerprint: Self: fb5f196e Parent: 7b17cd9d
Private Key: 505eb7e856d61b8e1c36f25155209f91ab9f8ff928280ca7e886be792799e94b
Public Key: 02c1030675e83209462ad2f31f216a43fce947c11917f813979593273437123431
Chain Code: fd86b4212e10c2142b3f8b0e77c796742b9d809fc8fdacf7e7b1ac9f27e9c385
Indices: M/0/0/1
Fingerprint: Self: 6bd9187b Parent: 7b17cd9d
Private Key: afb43c36f45131cfa200a5cdf30aac2a9d645ed67bddb76af3093d943ccb88fd
Public Key: 03443f05bf2be69afe7bafa34e36b7c07d764e7e84f8d2880d29f3b96694c0ee71
Chain Code: 760ace2164a0dd6b554c2052a6bb2e374c5f620f4c4729838234b3eee88d684b
Indices: M/0/0/2
Fingerprint: Self: 88ba9192 Parent: 7b17cd9d
Private Key: 514fd336ef931272d7287dce62741197199ce7f87378eb93d765962c192c8cc4
Public Key: 03fb76e19128cdd8732375638bfb8f8c44d93081c1a04679241e3eaf398b44a612
Chain Code: 18a9577e270124833006d577dc5471e4f4f9a2694cdc16cb3227406085c2faa8
Indices: M/0/1/0
Fingerprint: Self: d874bba7 Parent: 343b00e2
Private Key: ff3d8971a5d8b8eca842b0baea167f97e10ef7dddabc0475d701459fc090dfc3
Public Key: 0210d71ab1015089b8f9e975b57bfd5ee58dbbabf464ab36e42162da46dc038028
Chain Code: 39f476bf30270cf9b620056aa8e234672606bca4779b0b23bb76ce5799e73cfd
Indices: M/0/1/1
Fingerprint: Self: e92707d5 Parent: 343b00e2
Private Key: 7ec5b59a4b82d1a66b54a3437906a5026b8fee1116b4ff65f2eb9109df093a82
Public Key: 0367b0c155b0ff3f639127eef736d0b5ccd8c38ea6c83150f44477f22db1f64562
Chain Code: 740895154a15e07cc6161ca291fba3e7bb2fa029b388dd6c2bc5416e8e63b09a
Indices: M/0/1/2
Fingerprint: Self: 39803d9f Parent: 343b00e2
Private Key: 5e3add13a3c969af0535a2533cc89f89b163876988109dade440130bd00b1b21
Public Key: 035bcff1a8346db855b0a7077fb91d66e8917b9cc245ecc7785d4c110258dce077
Chain Code: fd5d67a45e725a97af53814a90933c2eb9d47ef1e77d3ff2e97e9b1e7e9d6f56
Indices: M/1/1
Fingerprint: Self: a86867f4 Parent: 2cd5b896
Private Key: b8cb851ff2ff129504c87d5c605b2cad59753ce71bf0cd02aacde8c5aa05bf50
Public Key: 031671a5707edb7b15b46f98d81d858b9ba506f26b6d656b876b1c08291b9db9a8
Chain Code: 4ed07788fbd1df7c09b33b0f661320e163aba116b3ac2daf6b3c503293f46e59
Indices: M/1/1/4095
Fingerprint: Self: f465eb45 Parent: a86867f4
Private Key: d129376c6a82dfbbcafaef5050699dd0457a90402e8216a344df99b835e97d96
Public Key: 0294c504145432dd6f61205cb34f90bebddba48b8074ce77cbd5b30ef042cb1f89
Chain Code: d2af3fd937b51d1c7f0d418ebc9e37becb475ebe5c25a4a85642ae35ea8836c9
Indices: M/1/1/4294967295
Fingerprint: Self: bf8ab522 Parent: a86867f4
Private Key: 7d499b6101bdc3fe80c705f1e1ac9df187e40fa70c6bdefb9dde5436c518cd27
Public Key: 023bb281583caefcc48a744a56dfa794ab130d3567af99b70fa6f7771a3860126d
Chain Code: 7ffdc1161f63afe0576a7047edf57b2c0e02173724dcf912ebb5ea1aa026604e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment