From d577410fc4a87262c107fb25657158f8f8ba720e Mon Sep 17 00:00:00 2001 From: Jochen Hoenicke Date: Wed, 20 Apr 2016 15:13:40 +0200 Subject: [PATCH] Unit tests for the NIST256P1 curve --- tests.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 153 insertions(+), 1 deletion(-) diff --git a/tests.c b/tests.c index 8b89b9493..1e69e824e 100644 --- a/tests.c +++ b/tests.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "aes.h" @@ -502,7 +503,152 @@ START_TEST(test_bip32_cache_2) } END_TEST -#define test_deterministic(KEY, MSG, K) do { \ +START_TEST(test_bip32_nist_vector_1) +{ + HDNode node; + + // init m + hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, NIST256P1_NAME, &node); + + // [Chain m] + ck_assert_int_eq(node.fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("beeb672fe4621673f722f38529c07392fecaa61015c80c34f29ce8b41b3cb6ea"), 32); + ck_assert_mem_eq(node.private_key, fromhex("612091aaa12e22dd2abef664f8a01a82cae99ad7441b7ef8110424915c268bc2"), 32); + ck_assert_mem_eq(node.public_key, fromhex("0266874dc6ade47b3ecd096745ca09bcd29638dd52c2c12117b11ed3e458cfa9e8"), 33); + + // [Chain m/0'] + hdnode_private_ckd_prime(&node, 0); + ck_assert_int_eq(node.fingerprint, 0xbe6105b5); + ck_assert_mem_eq(node.chain_code, fromhex("3460cea53e6a6bb5fb391eeef3237ffd8724bf0a40e94943c98b83825342ee11"), 32); + ck_assert_mem_eq(node.private_key, fromhex("6939694369114c67917a182c59ddb8cafc3004e63ca5d3b84403ba8613debc0c"), 32); + ck_assert_mem_eq(node.public_key, fromhex("0384610f5ecffe8fda089363a41f56a5c7ffc1d81b59a612d0d649b2d22355590c"), 33); + + // [Chain m/0'/1] + hdnode_private_ckd(&node, 1); + ck_assert_int_eq(node.fingerprint, 0x9b02312f); + ck_assert_mem_eq(node.chain_code, fromhex("4187afff1aafa8445010097fb99d23aee9f599450c7bd140b6826ac22ba21d0c"), 32); + ck_assert_mem_eq(node.private_key, fromhex("284e9d38d07d21e4e281b645089a94f4cf5a5a81369acf151a1c3a57f18b2129"), 32); + ck_assert_mem_eq(node.public_key, fromhex("03526c63f8d0b4bbbf9c80df553fe66742df4676b241dabefdef67733e070f6844"), 33); + + // [Chain m/0'/1/2'] + hdnode_private_ckd_prime(&node, 2); + ck_assert_int_eq(node.fingerprint, 0xb98005c1); + ck_assert_mem_eq(node.chain_code, fromhex("98c7514f562e64e74170cc3cf304ee1ce54d6b6da4f880f313e8204c2a185318"), 32); + ck_assert_mem_eq(node.private_key, fromhex("694596e8a54f252c960eb771a3c41e7e32496d03b954aeb90f61635b8e092aa7"), 32); + ck_assert_mem_eq(node.public_key, fromhex("0359cf160040778a4b14c5f4d7b76e327ccc8c4a6086dd9451b7482b5a4972dda0"), 33); + + // [Chain m/0'/1/2'/2] + hdnode_private_ckd(&node, 2); + ck_assert_int_eq(node.fingerprint, 0x0e9f3274); + ck_assert_mem_eq(node.chain_code, fromhex("ba96f776a5c3907d7fd48bde5620ee374d4acfd540378476019eab70790c63a0"), 32); + ck_assert_mem_eq(node.private_key, fromhex("5996c37fd3dd2679039b23ed6f70b506c6b56b3cb5e424681fb0fa64caf82aaa"), 32); + ck_assert_mem_eq(node.public_key, fromhex("029f871f4cb9e1c97f9f4de9ccd0d4a2f2a171110c61178f84430062230833ff20"), 33); + + // [Chain m/0'/1/2'/2/1000000000] + hdnode_private_ckd(&node, 1000000000); + ck_assert_int_eq(node.fingerprint, 0x8b2b5c4b); + ck_assert_mem_eq(node.chain_code, fromhex("b9b7b82d326bb9cb5b5b121066feea4eb93d5241103c9e7a18aad40f1dde8059"), 32); + ck_assert_mem_eq(node.private_key, fromhex("21c4f269ef0a5fd1badf47eeacebeeaa3de22eb8e5b0adcd0f27dd99d34d0119"), 32); + ck_assert_mem_eq(node.public_key, fromhex("02216cd26d31147f72427a453c443ed2cde8a1e53c9cc44e5ddf739725413fe3f4"), 33); +} +END_TEST + +START_TEST(test_bip32_nist_vector_2) +{ + HDNode node; + int r; + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, NIST256P1_NAME, &node); + + // [Chain m] + ck_assert_int_eq(node.fingerprint, 0x00000000); + ck_assert_mem_eq(node.chain_code, fromhex("96cd4465a9644e31528eda3592aa35eb39a9527769ce1855beafc1b81055e75d"), 32); + ck_assert_mem_eq(node.private_key, fromhex("eaa31c2e46ca2962227cf21d73a7ef0ce8b31c756897521eb6c7b39796633357"), 32); + ck_assert_mem_eq(node.public_key, fromhex("02c9e16154474b3ed5b38218bb0463e008f89ee03e62d22fdcc8014beab25b48fa"), 33); + + // [Chain m/0] + r = hdnode_private_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(node.fingerprint, 0x607f628f); + ck_assert_mem_eq(node.chain_code, fromhex("84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), 32); + ck_assert_mem_eq(node.private_key, fromhex("d7d065f63a62624888500cdb4f88b6d59c2927fee9e6d0cdff9cad555884df6e"), 32); + ck_assert_mem_eq(node.public_key, fromhex("039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), 33); + + // [Chain m/0/2147483647'] + r = hdnode_private_ckd_prime(&node, 2147483647); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(node.fingerprint, 0x946d2a54); + ck_assert_mem_eq(node.chain_code, fromhex("f235b2bc5c04606ca9c30027a84f353acf4e4683edbd11f635d0dcc1cd106ea6"), 32); + ck_assert_mem_eq(node.private_key, fromhex("96d2ec9316746a75e7793684ed01e3d51194d81a42a3276858a5b7376d4b94b9"), 32); + ck_assert_mem_eq(node.public_key, fromhex("02f89c5deb1cae4fedc9905f98ae6cbf6cbab120d8cb85d5bd9a91a72f4c068c76"), 33); + + // [Chain m/0/2147483647'/1] + r = hdnode_private_ckd(&node, 1); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(node.fingerprint, 0x218182d8); + ck_assert_mem_eq(node.chain_code, fromhex("7c0b833106235e452eba79d2bdd58d4086e663bc8cc55e9773d2b5eeda313f3b"), 32); + ck_assert_mem_eq(node.private_key, fromhex("974f9096ea6873a915910e82b29d7c338542ccde39d2064d1cc228f371542bbc"), 32); + ck_assert_mem_eq(node.public_key, fromhex("03abe0ad54c97c1d654c1852dfdc32d6d3e487e75fa16f0fd6304b9ceae4220c64"), 33); + + // [Chain m/0/2147483647'/1/2147483646'] + r = hdnode_private_ckd_prime(&node, 2147483646); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(node.fingerprint, 0x931223e4); + ck_assert_mem_eq(node.chain_code, fromhex("5794e616eadaf33413aa309318a26ee0fd5163b70466de7a4512fd4b1a5c9e6a"), 32); + ck_assert_mem_eq(node.private_key, fromhex("da29649bbfaff095cd43819eda9a7be74236539a29094cd8336b07ed8d4eff63"), 32); + ck_assert_mem_eq(node.public_key, fromhex("03cb8cb067d248691808cd6b5a5a06b48e34ebac4d965cba33e6dc46fe13d9b933"), 33); + + // [Chain m/0/2147483647'/1/2147483646'/2] + r = hdnode_private_ckd(&node, 2); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(node.fingerprint, 0x956c4629); + ck_assert_mem_eq(node.chain_code, fromhex("3bfb29ee8ac4484f09db09c2079b520ea5616df7820f071a20320366fbe226a7"), 32); + ck_assert_mem_eq(node.private_key, fromhex("bb0a77ba01cc31d77205d51d08bd313b979a71ef4de9b062f8958297e746bd67"), 32); + ck_assert_mem_eq(node.public_key, fromhex("020ee02e18967237cf62672983b253ee62fa4dd431f8243bfeccdf39dbe181387f"), 33); + + // init m + hdnode_from_seed(fromhex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"), 64, NIST256P1_NAME, &node); + + // test public derivation + // [Chain m/0] + r = hdnode_public_ckd(&node, 0); + ck_assert_int_eq(r, 1); + ck_assert_int_eq(node.fingerprint, 0x607f628f); + ck_assert_mem_eq(node.chain_code, fromhex("84e9c258bb8557a40e0d041115b376dd55eda99c0042ce29e81ebe4efed9b86a"), 32); + ck_assert_mem_eq(node.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + ck_assert_mem_eq(node.public_key, fromhex("039b6df4bece7b6c81e2adfeea4bcf5c8c8a6e40ea7ffa3cf6e8494c61a1fc82cc"), 33); +} +END_TEST + +START_TEST(test_bip32_nist_compare) +{ + HDNode node1, node2, node3; + int i, r; + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, NIST256P1_NAME, &node1); + hdnode_from_seed(fromhex("301133282ad079cbeb59bc446ad39d333928f74c46997d3609cd3e2801ca69d62788f9f174429946ff4e9be89f67c22fae28cb296a9b37734f75e73d1477af19"), 64, NIST256P1_NAME, &node2); + for (i = 0; i < 100; i++) { + memcpy(&node3, &node1, sizeof(HDNode)); + r = hdnode_private_ckd(&node1, i); ck_assert_int_eq(r, 1); + r = hdnode_public_ckd(&node2, i); ck_assert_int_eq(r, 1); + r = hdnode_public_ckd(&node3, i); ck_assert_int_eq(r, 1); + ck_assert_int_eq(node1.depth, node2.depth); + ck_assert_int_eq(node1.depth, node3.depth); + ck_assert_int_eq(node1.fingerprint, node2.fingerprint); + ck_assert_int_eq(node1.fingerprint, node3.fingerprint); + ck_assert_int_eq(node1.child_num, node2.child_num); + ck_assert_int_eq(node1.child_num, node3.child_num); + ck_assert_mem_eq(node1.chain_code, node2.chain_code, 32); + ck_assert_mem_eq(node1.chain_code, node3.chain_code, 32); + ck_assert_mem_eq(node2.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + ck_assert_mem_eq(node3.private_key, fromhex("0000000000000000000000000000000000000000000000000000000000000000"), 32); + ck_assert_mem_eq(node1.public_key, node2.public_key, 33); + ck_assert_mem_eq(node1.public_key, node3.public_key, 33); + } +} +END_TEST + +#define test_deterministic(KEY, MSG, K) do { \ sha256_Raw((uint8_t *)MSG, strlen(MSG), buf); \ res = generate_k_rfc6979(curve, &k, fromhex(KEY), buf); \ ck_assert_int_eq(res, 0); \ @@ -1419,6 +1565,12 @@ Suite *test_suite(void) tcase_add_test(tc, test_bip32_cache_2); suite_add_tcase(s, tc); + tc = tcase_create("bip32-nist"); + tcase_add_test(tc, test_bip32_nist_vector_1); + tcase_add_test(tc, test_bip32_nist_vector_2); + tcase_add_test(tc, test_bip32_nist_compare); + suite_add_tcase(s, tc); + tc = tcase_create("rfc6979"); tcase_add_test(tc, test_rfc6979); suite_add_tcase(s, tc);