From 865ca5f0a9534ca64f41a1d508983029b55c9b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Vejpustek?= Date: Tue, 6 Aug 2024 15:20:17 +0200 Subject: [PATCH] fix(crypto): fix fingerprints for curve25519 and ed25519 --- core/.changelog.d/4093.fixed | 1 + crypto/bip32.c | 5 +++ crypto/tests/test_check.c | 42 ++++++++++++++++++++----- legacy/firmware/.changelog.d/4093.fixed | 1 + 4 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 core/.changelog.d/4093.fixed create mode 100644 legacy/firmware/.changelog.d/4093.fixed diff --git a/core/.changelog.d/4093.fixed b/core/.changelog.d/4093.fixed new file mode 100644 index 0000000000..0fa95d8866 --- /dev/null +++ b/core/.changelog.d/4093.fixed @@ -0,0 +1 @@ +Fixed SLIP-10 fingerprints for ed25519 and curve25519. diff --git a/crypto/bip32.c b/crypto/bip32.c index 741049c433..15a7d7add1 100644 --- a/crypto/bip32.c +++ b/crypto/bip32.c @@ -186,6 +186,11 @@ uint32_t hdnode_fingerprint(HDNode *node) { uint32_t fingerprint = 0; hdnode_fill_public_key(node); + if (node->public_key[0] == 0x01) { + // The prefix 0x01 indicates curve25519 or ed25519 + // In this case, SLIP-10 uses the prefix 0x00 to calculate the fingerprint + node->public_key[0] = 0x00; + } hasher_Raw(node->curve->hasher_pubkey, node->public_key, 33, digest); fingerprint = ((uint32_t)digest[0] << 24) + (digest[1] << 16) + (digest[2] << 8) + digest[3]; diff --git a/crypto/tests/test_check.c b/crypto/tests/test_check.c index 1a7ba16441..c08b34389e 100644 --- a/crypto/tests/test_check.c +++ b/crypto/tests/test_check.c @@ -2633,9 +2633,11 @@ START_TEST(test_bip32_nist_repeat) { } END_TEST -// test vector 1 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors +// https://github.com/satoshilabs/slips/blob/master/slip-0010.md#test-vector-1-for-ed25519 START_TEST(test_bip32_ed25519_vector_1) { HDNode node; + uint32_t fingerprint; + int r; // init m hdnode_from_seed(fromhex("000102030405060708090a0b0c0d0e0f"), 16, @@ -2660,7 +2662,10 @@ START_TEST(test_bip32_ed25519_vector_1) { 33); // [Chain m/0'] - hdnode_private_ckd_prime(&node, 0); + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0xddebc675); + r = hdnode_private_ckd_prime(&node, 0); + ck_assert_int_eq(r, 1); ck_assert_mem_eq( node.chain_code, fromhex( @@ -2679,7 +2684,10 @@ START_TEST(test_bip32_ed25519_vector_1) { 33); // [Chain m/0'/1'] - hdnode_private_ckd_prime(&node, 1); + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0x13dab143); + r = hdnode_private_ckd_prime(&node, 1); + ck_assert_int_eq(r, 1); ck_assert_mem_eq( node.chain_code, fromhex( @@ -2698,7 +2706,10 @@ START_TEST(test_bip32_ed25519_vector_1) { 33); // [Chain m/0'/1'/2'] - hdnode_private_ckd_prime(&node, 2); + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0xebe4cb29); + r = hdnode_private_ckd_prime(&node, 2); + ck_assert_int_eq(r, 1); ck_assert_mem_eq( node.chain_code, fromhex( @@ -2717,7 +2728,10 @@ START_TEST(test_bip32_ed25519_vector_1) { 33); // [Chain m/0'/1'/2'/2'] - hdnode_private_ckd_prime(&node, 2); + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0x316ec1c6); + r = hdnode_private_ckd_prime(&node, 2); + ck_assert_int_eq(r, 1); ck_assert_mem_eq( node.chain_code, fromhex( @@ -2736,7 +2750,10 @@ START_TEST(test_bip32_ed25519_vector_1) { 33); // [Chain m/0'/1'/2'/2'/1000000000'] - hdnode_private_ckd_prime(&node, 1000000000); + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0xd6322ccd); + r = hdnode_private_ckd_prime(&node, 1000000000); + ck_assert_int_eq(r, 1); ck_assert_mem_eq( node.chain_code, fromhex( @@ -2756,9 +2773,10 @@ START_TEST(test_bip32_ed25519_vector_1) { } END_TEST -// test vector 2 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors +// https://github.com/satoshilabs/slips/blob/master/slip-0010.md#test-vector-2-for-ed25519 START_TEST(test_bip32_ed25519_vector_2) { HDNode node; + uint32_t fingerprint; int r; // init m @@ -2787,6 +2805,8 @@ START_TEST(test_bip32_ed25519_vector_2) { 33); // [Chain m/0'] + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0x31981b50); r = hdnode_private_ckd_prime(&node, 0); ck_assert_int_eq(r, 1); ck_assert_mem_eq( @@ -2807,6 +2827,8 @@ START_TEST(test_bip32_ed25519_vector_2) { 33); // [Chain m/0'/2147483647'] + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0x1e9411b1); r = hdnode_private_ckd_prime(&node, 2147483647); ck_assert_int_eq(r, 1); ck_assert_mem_eq( @@ -2827,6 +2849,8 @@ START_TEST(test_bip32_ed25519_vector_2) { 33); // [Chain m/0'/2147483647'/1'] + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0xfcadf38c); r = hdnode_private_ckd_prime(&node, 1); ck_assert_int_eq(r, 1); ck_assert_mem_eq( @@ -2847,6 +2871,8 @@ START_TEST(test_bip32_ed25519_vector_2) { 33); // [Chain m/0'/2147483647'/1'/2147483646'] + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0xaca70953); r = hdnode_private_ckd_prime(&node, 2147483646); ck_assert_int_eq(r, 1); ck_assert_mem_eq( @@ -2867,6 +2893,8 @@ START_TEST(test_bip32_ed25519_vector_2) { 33); // [Chain m/0'/2147483647'/1'/2147483646'/2'] + fingerprint = hdnode_fingerprint(&node); + ck_assert_uint_eq(fingerprint, 0x422c654b); r = hdnode_private_ckd_prime(&node, 2); ck_assert_int_eq(r, 1); ck_assert_mem_eq( diff --git a/legacy/firmware/.changelog.d/4093.fixed b/legacy/firmware/.changelog.d/4093.fixed new file mode 100644 index 0000000000..0fa95d8866 --- /dev/null +++ b/legacy/firmware/.changelog.d/4093.fixed @@ -0,0 +1 @@ +Fixed SLIP-10 fingerprints for ed25519 and curve25519.