diff --git a/test_check.c b/test_check.c index f86b69f0d1..b99b1a251d 100644 --- a/test_check.c +++ b/test_check.c @@ -58,6 +58,7 @@ #include "rfc6979.h" #include "address.h" #include "rc4.h" +#include "nem.h" /* * This is a clever trick to make Valgrind's Memcheck verify code @@ -90,6 +91,13 @@ const uint8_t *fromhex(const char *str) return buf; } +void nem_private_key(const char *reversed_hex, ed25519_secret_key private_key) { + const uint8_t *reversed_key = fromhex(reversed_hex); + for (size_t j = 0; j < sizeof(ed25519_secret_key); j++) { + private_key[j] = reversed_key[sizeof(ed25519_secret_key) - j - 1]; + } +} + START_TEST(test_bignum_read_be) { bignum256 a; @@ -2948,11 +2956,7 @@ START_TEST(test_ed25519_keccak) ed25519_signature signature; for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { - // For some reason, NEM stores private keys in big endian - const uint8_t *reversed_key = fromhex(tests[i].private_key); - for (size_t j = 0; j < 32; j++) { - private_key[j] = reversed_key[32 - j - 1]; - } + nem_private_key(tests[i].private_key, private_key); MARK_SECRET_DATA(private_key, sizeof(private_key)); ed25519_publickey_keccak(private_key, public_key); @@ -3224,6 +3228,54 @@ START_TEST(test_ethereum_address) } END_TEST +// test vectors from https://raw.githubusercontent.com/NemProject/nem-test-vectors/master/1.test-keys.dat +START_TEST(test_nem_address) +{ + static const struct { + const char *private_key; + const char *public_key; + const char *address; + } tests[] = { + { "575dbb3062267eff57c970a336ebbc8fbcfe12c5bd3ed7bc11eb0481d7704ced", "c5f54ba980fcbb657dbaaa42700539b207873e134d2375efeab5f1ab52f87844", "NDD2CT6LQLIYQ56KIXI3ENTM6EK3D44P5JFXJ4R4", }, + { "5b0e3fa5d3b49a79022d7c1e121ba1cbbf4db5821f47ab8c708ef88defc29bfe", "96eb2a145211b1b7ab5f0d4b14f8abc8d695c7aee31a3cfc2d4881313c68eea3", "NABHFGE5ORQD3LE4O6B7JUFN47ECOFBFASC3SCAC", }, + { "738ba9bb9110aea8f15caa353aca5653b4bdfca1db9f34d0efed2ce1325aeeda", "2d8425e4ca2d8926346c7a7ca39826acd881a8639e81bd68820409c6e30d142a", "NAVOZX4HDVOAR4W6K4WJHWPD3MOFU27DFHC7KZOZ", }, + { "e8bf9bc0f35c12d8c8bf94dd3a8b5b4034f1063948e3cc5304e55e31aa4b95a6", "4feed486777ed38e44c489c7c4e93a830e4c4a907fa19a174e630ef0f6ed0409", "NBZ6JK5YOCU6UPSSZ5D3G27UHAPHTY5HDQMGE6TT", }, + { "c325ea529674396db5675939e7988883d59a5fc17a28ca977e3ba85370232a83", "83ee32e4e145024d29bca54f71fa335a98b3e68283f1a3099c4d4ae113b53e54", "NCQW2P5DNZ5BBXQVGS367DQ4AHC3RXOEVGRCLY6V", }, + { "a811cb7a80a7227ae61f6da536534ee3c2744e3c7e4b85f3e0df3c6a9c5613df", "6d34c04f3a0e42f0c3c6f50e475ae018cfa2f56df58c481ad4300424a6270cbb", "NA5IG3XFXZHIPJ5QLKX2FBJPEZYPMBPPK2ZRC3EH", }, + { "9c66de1ec77f4dfaaebdf9c8bc599ca7e8e6f0bc71390ffee2c9dd3f3619242a", "a8fefd72a3b833dc7c7ed7d57ed86906dac22f88f1f4331873eb2da3152a3e77", "NAABHVFJDBM74XMJJ52R7QN2MTTG2ZUXPQS62QZ7", }, + { "c56bc16ecf727878c15e24f4ae68569600ac7b251218a44ef50ce54175776edc", "c92f761e6d83d20068fd46fe4bd5b97f4c6ba05d23180679b718d1f3e4fb066e", "NCLK3OLMHR3F2E3KSBUIZ4K5PNWUDN37MLSJBJZP", }, + { "9dd73599283882fa1561ddfc9be5830b5dd453c90465d3fe5eeb646a3606374e", "eaf16a4833e59370a04ccd5c63395058de34877b48c17174c71db5ed37b537ed", "ND3AHW4VTI5R5QE5V44KIGPRU5FBJ5AFUCJXOY5H", }, + { "d9639dc6f49dad02a42fd8c217f1b1b4f8ce31ccd770388b645e639c72ff24fa", "0f74a2f537cd9c986df018994dde75bdeee05e35eb9fe27adf506ca8475064f7", "NCTZ4YAP43ONK3UYTASQVNDMBO24ZHJE65F3QPYE", }, + { "efc1992cd50b70ca55ac12c07aa5d026a8b78ffe28a7dbffc9228b26e02c38c1", "2ebff201255f6cf948c78f528658b99a7c13ac791942fa22d59af610558111f5", "NDQ2TMCMXBSFPZQPE2YKH6XLC24HD6LUMN6Z4GIC", }, + { "143a815e92e43f3ed1a921ee48cd143931b88b7c3d8e1e981f743c2a5be3c5ba", "419ed11d48730e4ae2c93f0ea4df853b8d578713a36dab227517cf965861af4e", "NA32IDDW2C53BDSBJNFL3Z6UU3J5CJZJMCZDXCF4", }, + { "bc1a082f5ac6fdd3a83ade211e5986ac0551bad6c7da96727ec744e5df963e2a", "a160e6f9112233a7ce94202ed7a4443e1dac444b5095f9fecbb965fba3f92cac", "NADUCEQLC3FTGB25GTA5HOUTB53CBVQNVOIP7NTJ", }, + { "4e47b4c6f4c7886e49ec109c61f4af5cfbb1637283218941d55a7f9fe1053f72", "fbb91b16df828e21a9802980a44fc757c588bc1382a4cea429d6fa2ae0333f56", "NBAF3BFLLPWH33MYE6VUPP5T6DQBZBKIDEQKZQOE", }, + { "efc4389da48ce49f85365cfa578c746530e9eac42db1b64ec346119b1becd347", "2232f24dda0f2ded3ecd831210d4e8521a096b50cadd5a34f3f7083374e1ec12", "NBOGTK2I2ATOGGD7ZFJHROG5MWL7XCKAUKSWIVSA", }, + { "bdba57c78ca7da16a3360efd13f06276284db8c40351de7fcd38ba0c35ac754d", "c334c6c0dad5aaa2a0d0fb4c6032cb6a0edd96bf61125b5ea9062d5a00ee0eee", "NCLERTEFYXKLK7RA4MVACEFMXMK3P7QMWTM7FBW2", }, + { "20694c1ec3c4a311bcdb29ed2edc428f6d4f9a4c429ad6a5bf3222084e35695f", "518c4de412efa93de06a55947d11f697639443916ec8fcf04ebc3e6d17d0bd93", "NB5V4BPIJHXVONO7UGMJDPFARMFA73BOBNOOYCOV", }, + { "e0d4f3760ac107b33c22c2cac24ab2f520b282684f5f66a4212ff95d926323ce", "b3d16f4ead9de67c290144da535a0ed2504b03c05e5f1ceb8c7863762f786857", "NC4PBAO5TPCAVQKBVOC4F6DMZP3CFSQBU46PSKBD", }, + { "efa9afc617412093c9c7a7c211a5332dd556f941e1a88c494ec860608610eea2", "7e7716e4cebceb731d6f1fd28676f34888e9a0000fcfa1471db1c616c2ddf559", "NCFW2LPXIWLBWAQN2QVIWEOD7IVDO3HQBD2OU56K", }, + { "d98499b3db61944684ce06a91735af4e14105338473fcf6ebe2b0bcada3dfd21", "114171230ad6f8522a000cdc73fbc5c733b30bb71f2b146ccbdf34499f79a810", "NCUKWDY3J3THKQHAKOK5ALF6ANJQABZHCH7VN6DP", }, + }; + + HDNode node; + ed25519_secret_key private_key; + uint8_t chain_code[32]; + char address[41]; + + for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) { + nem_private_key(tests[i].private_key, private_key); + + ck_assert(hdnode_from_xprv(0, 0, chain_code, private_key, ED25519_KECCAK_NAME, &node)); + + ck_assert(hdnode_get_nem_address(&node, NEM_NETWORK_MAINNET, address)); + ck_assert_str_eq(address, tests[i].address); + + ck_assert_mem_eq(&node.public_key[1], fromhex(tests[i].public_key), 32); + } +} +END_TEST + START_TEST(test_multibyte_address) { uint8_t priv_key[32]; @@ -3680,6 +3732,10 @@ Suite *test_suite(void) tcase_add_test(tc, test_ethereum_pubkeyhash); suite_add_tcase(s, tc); + tc = tcase_create("nem_address"); + tcase_add_test(tc, test_nem_address); + suite_add_tcase(s, tc); + tc = tcase_create("multibyte_address"); tcase_add_test(tc, test_multibyte_address); suite_add_tcase(s, tc);