From 77620b4fa5e63548507f6dd74ef237d84bafb438 Mon Sep 17 00:00:00 2001 From: rxbryan Date: Tue, 9 Jul 2024 22:07:30 +0100 Subject: [PATCH] feat (app): Add nested-segwit support test nested-segwit digest for 1 inputs and 2 output transactions test nested-segwit digest for 2 inputs and 2 output transactions --- apps/btc_family/btc_pub_key.c | 11 +- apps/btc_family/btc_script.c | 16 +- apps/btc_family/btc_txn.c | 21 +- apps/btc_family/btc_txn_helpers.c | 1 - tests/apps/btc_app/btc_txn_helpers_tests.c | 373 ++++++++++++++++++++- tests/unit_test_lists.c | 8 + 6 files changed, 418 insertions(+), 12 deletions(-) diff --git a/apps/btc_family/btc_pub_key.c b/apps/btc_family/btc_pub_key.c index 6c56aac18..1f2f72c84 100644 --- a/apps/btc_family/btc_pub_key.c +++ b/apps/btc_family/btc_pub_key.c @@ -204,7 +204,16 @@ static size_t btc_get_address(const uint8_t *seed, case NON_SEGWIT: hdnode_get_address(&node, g_btc_app->p2pkh_addr_ver, addr, 35); break; - // TODO: add support for taproot and segwit + case PURPOSE_SEGWIT: + ecdsa_get_address_segwit_p2sh(node.public_key, + g_btc_app->p2sh_addr_ver, + node.curve->hasher_pubkey, + node.curve->hasher_base58, + addr, + 36); + break; + + // TODO: add support for taproot default: break; } diff --git a/apps/btc_family/btc_script.c b/apps/btc_family/btc_script.c index 2418584eb..34b06bbad 100644 --- a/apps/btc_family/btc_script.c +++ b/apps/btc_family/btc_script.c @@ -239,13 +239,25 @@ bool btc_check_script_address(const uint8_t *script, uint8_t digest[HASHER_DIGEST_LENGTH] = {0}; btc_script_type_e type = btc_get_script_type(script, script_len); - if (SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type) { - // allow only p2pkh and p2wpkh for change output + if (SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type && + SCRIPT_TYPE_P2SH != type) { + // allow only p2pkh and p2wpkh and p2sh-p2wpkh for change output return false; } uint8_t offset = (SCRIPT_TYPE_P2PKH == type) ? 3 : 2; hasher_Raw(HASHER_SHA2_RIPEMD, public_key, BTC_SHORT_PUB_KEY_SIZE, digest); + + if (SCRIPT_TYPE_P2SH == type) { + // Compute redeemscript(P2WPKH). scriptpub of nested-segwit is hash160 of + // redeemscript + uint8_t buf[22] = {0}; + buf[0] = 0; // version byte + buf[1] = 20; // push 20 bytes + memcpy(buf + 2, digest, 20); + hasher_Raw(HASHER_SHA2_RIPEMD, buf, 22, digest); + } + return (memcmp(digest, &script[offset], RIPEMD160_DIGEST_LENGTH) == 0); } diff --git a/apps/btc_family/btc_txn.c b/apps/btc_family/btc_txn.c index 38033939f..4b3a84e80 100644 --- a/apps/btc_family/btc_txn.c +++ b/apps/btc_family/btc_txn.c @@ -478,7 +478,8 @@ static bool fetch_valid_input(btc_query_t *query) { return false; } - if ((SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type) || + if ((SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type && + SCRIPT_TYPE_P2SH != type) || 0 != status) { // input validation failed, terminate immediately btc_send_error(ERROR_COMMON_ERROR_CORRUPT_DATA_TAG, @@ -648,11 +649,27 @@ static bool sign_input(scrip_sig_t *signatures) { status = true; for (int idx = 0; idx < btc_txn_context->metadata.input_count; idx++) { // generate the input digest and respective private key - status = btc_digest_input(btc_txn_context, idx, buffer); memcpy(&t_node, &node, sizeof(HDNode)); hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].change_index); hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].address_index); hdnode_fill_public_key(&t_node); + + // detect input type + btc_sign_txn_input_script_pub_key_t *script = + &btc_txn_context->inputs[idx].script_pub_key; + btc_script_type_e type = btc_get_script_type(script->bytes, script->size); + if (SCRIPT_TYPE_P2SH == type) { + // replace BIP16 scriptpubkey with redeemscript(P2WPKH) + uint8_t buf[22] = {0}; + buf[0] = 0; // version byte + buf[1] = 20; // push 20 bytes + ecdsa_get_pubkeyhash( + t_node.public_key, t_node.curve->hasher_pubkey, buf + 2); + memcpy(btc_txn_context->inputs[idx].script_pub_key.bytes, buf, 22); + btc_txn_context->inputs[idx].script_pub_key.size = 22; + } + + status = btc_digest_input(btc_txn_context, idx, buffer); ecdsa_sign_digest( curve, t_node.private_key, buffer, signatures[idx].bytes, NULL, NULL); signatures[idx].size = btc_sig_to_script_sig( diff --git a/apps/btc_family/btc_txn_helpers.c b/apps/btc_family/btc_txn_helpers.c index 7e40adef3..1fa337eba 100644 --- a/apps/btc_family/btc_txn_helpers.c +++ b/apps/btc_family/btc_txn_helpers.c @@ -670,7 +670,6 @@ bool btc_digest_input(const btc_txn_context_t *context, btc_sign_txn_input_script_pub_key_t *script = &context->inputs[index].script_pub_key; btc_script_type_e type = btc_get_script_type(script->bytes, script->size); - if (SCRIPT_TYPE_P2WPKH == type) { // segwit digest calculation; could fail if segwit_cache not filled status = calculate_p2wpkh_digest(context, index, digest); diff --git a/tests/apps/btc_app/btc_txn_helpers_tests.c b/tests/apps/btc_app/btc_txn_helpers_tests.c index 18d6a6bb9..62868b5bc 100644 --- a/tests/apps/btc_app/btc_txn_helpers_tests.c +++ b/tests/apps/btc_app/btc_txn_helpers_tests.c @@ -149,7 +149,7 @@ TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2pk) { "0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9", 64, input.prev_txn_hash); - // revere order of txn-id: + // Reverse order of txn-id: cy_reverse_byte_array(input.prev_txn_hash, sizeof(input.prev_txn_hash)); hex_string_to_byte_array( @@ -189,7 +189,7 @@ TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2pk_fail) { "0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9", 64, input.prev_txn_hash); - // revere order of txn-id: + // Reverse order of txn-id: // 0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9 cy_reverse_byte_array(input.prev_txn_hash, sizeof(input.prev_txn_hash)); hex_string_to_byte_array( @@ -231,7 +231,7 @@ TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2pkh) { "eb0e2029310edade8e2a034aea4f0c4a1e243fe2dce67d05f95fddb7ac11bfbe", 64, input.prev_txn_hash); - // revere order of txn-id: + // Reverse order of txn-id: // eb0e2029310edade8e2a034aea4f0c4a1e243fe2dce67d05f95fddb7ac11bfbe cy_reverse_byte_array(input.prev_txn_hash, sizeof(input.prev_txn_hash)); hex_string_to_byte_array("76a91412ab8dc588ca9d5787dde7eb29569da63c3a238c88ac", @@ -271,7 +271,7 @@ TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2pkh_fail) { "eb0e2029310edade8e2a034aea4f0c4a1e243fe2dce67d05f95fddb7ac11bfbe", 64, input.prev_txn_hash); - // revere order of txn-id: + // Reverse order of txn-id: // eb0e2029310edade8e2a034aea4f0c4a1e243fe2dce67d05f95fddb7ac11bfbe cy_reverse_byte_array(input.prev_txn_hash, sizeof(input.prev_txn_hash)); hex_string_to_byte_array("76a91412ab8dc588ca9d5787dde7eb29569da63c3a238c88ac", @@ -329,7 +329,7 @@ TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2wpkh) { "21706dfac590a74e7d083ad60e790c3a1775a4818afd7aa3ddf1a3d76dc16b03", 64, input.prev_txn_hash); - // revere order of txn-id: + // Reverse order of txn-id: // 21706dfac590a74e7d083ad60e790c3a1775a4818afd7aa3ddf1a3d76dc16b03 cy_reverse_byte_array(input.prev_txn_hash, sizeof(input.prev_txn_hash)); hex_string_to_byte_array("0014854fe623a8a6a4c76779b57c3895ed2e09626474", @@ -389,7 +389,7 @@ TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2wpkh_fail) { "21706dfac590a74e7d083ad60e790c3a1775a4818afd7aa3ddf1a3d76dc16b04", 64, input.prev_txn_hash); - // revere order of txn-id: + // Reverse order of txn-id: // 21706dfac590a74e7d083ad60e790c3a1775a4818afd7aa3ddf1a3d76dc16b04 cy_reverse_byte_array(input.prev_txn_hash, sizeof(input.prev_txn_hash)); hex_string_to_byte_array("0014854fe623a8a6a4c76779b57c3895ed2e09626474", @@ -400,6 +400,152 @@ TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2wpkh_fail) { TEST_ASSERT_EQUAL_INT(2, status); } +TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2wpkh_in_p2sh) { + /* Test data source: Bip143 + * https://blockstream.info/testnet/tx/b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a2?expand + */ + int status = 2; + uint8_t raw_txn[2000] = {0}; + hex_string_to_byte_array( + "0200000000010258afb1ece76f01c24f4935f453d210518163cb1d0383eaec331b202ebe" + "b5e389" + "0000000017160014a76cad25cb569bb47305513ebedd6011dc419deeffffffff2b3682b3" + "592588" + "5001f0e321df28d4ac675a9cbbccef2a69533bea7c5e5ad2c40000000017160014a76cad" + "25cb56" + "9bb47305513ebedd6011dc419deeffffffff02941100000000000017a914bd7aabdeeef2" + "11b1bd" + "ad7218e14fea6c032101c087f22f00000000000017a914eaf97514c5ac1e41e413502e97" + "ae42eb" + "f27ace3a870247304402206e038f4712541d699697ed55efc41219df4f244fc72caa5edd" + "653837" + "f6555f6f02201cd8ea15b65fda17992abafaed86e066c3271ac16b9c46c54c2192438843" + "dd0401" + "21029f75e1ef6b04e004a308b1f59215a8a3a5b7958bbcf184cc24ba7ab6574448780248" + "304502" + "2100d15ce61648edc28b8b5a3531b80a1e8fc3b3eebe7d3fc4ca962cb04afc770dda0220" + "7c7eaf8" + "82d7fac45d2752f20e48d2f896715cbc5a3b0f5de3e19fea0da99beac0121029f75e1ef6" + "b04e004" + "a308b1f59215a8a3a5b7958bbcf184cc24ba7ab65744487800000000", + 838, + raw_txn); + // only fill necessary values + btc_txn_input_t input[] = {{ + .value = 4500, + .prev_output_index = 0x00000000, + .script_pub_key = {.size = 23}, + }, + { + .value = 12274, + .prev_output_index = 0x00000001, + .script_pub_key = {.size = 23}, + }}; + + hex_string_to_byte_array( + "b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a2", + 64, + input[0].prev_txn_hash); + // Reverse order of txn-id: + // A244A293475AC245DEE8B3343F51EE2296BAB24FCC3FE0A49628DF605E2295B0 + cy_reverse_byte_array(input[0].prev_txn_hash, sizeof(input[0].prev_txn_hash)); + + hex_string_to_byte_array( + "b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a2", + 64, + input[1].prev_txn_hash); + // Reverse order of txn-id: + // A244A293475AC245DEE8B3343F51EE2296BAB24FCC3FE0A49628DF605E2295B0 + cy_reverse_byte_array(input[1].prev_txn_hash, sizeof(input[1].prev_txn_hash)); + + hex_string_to_byte_array("a914bd7aabdeeef211b1bdad7218e14fea6c032101c087", + 46, + input[0].script_pub_key.bytes); + hex_string_to_byte_array("a914eaf97514c5ac1e41e413502e97ae42ebf27ace3a87", + 46, + input[1].script_pub_key.bytes); + + status = btc_verify_input_test(input, raw_txn, 419); + TEST_ASSERT_EQUAL_INT(0, status); + status = btc_verify_input_test(input + 1, raw_txn, 419); + TEST_ASSERT_EQUAL_INT(0, status); +} + +TEST(btc_txn_helper_test, btc_txn_helper_verify_input_p2wpkh_in_p2sh_fail) { + /* Test data source: Bip143 + * https://blockstream.info/testnet/tx/b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a2?expand + */ + int status = 2; + uint8_t raw_txn[2000] = {0}; + hex_string_to_byte_array( + "0200000000010258afb1ece76f01c24f4935f453d210518163cb1d0383eaec331b202ebe" + "b5e389" + "0000000017160014a76cad25cb569bb47305513ebedd6011dc419deeffffffff2b3682b3" + "592588" + "5001f0e321df28d4ac675a9cbbccef2a69533bea7c5e5ad2c40000000017160014a76cad" + "25cb56" + "9bb47305513ebedd6011dc419deeffffffff02941100000000000017a914bd7aabdeeef2" + "11b1bd" + "ad7218e14fea6c032101c087f22f00000000000017a914eaf97514c5ac1e41e413502e97" + "ae42eb" + "f27ace3a870247304402206e038f4712541d699697ed55efc41219df4f244fc72caa5edd" + "653837" + "f6555f6f02201cd8ea15b65fda17992abafaed86e066c3271ac16b9c46c54c2192438843" + "dd0401" + "21029f75e1ef6b04e004a308b1f59215a8a3a5b7958bbcf184cc24ba7ab6574448780248" + "304502" + "2100d15ce61648edc28b8b5a3531b80a1e8fc3b3eebe7d3fc4ca962cb04afc770dda0220" + "7c7eaf8" + "82d7fac45d2752f20e48d2f896715cbc5a3b0f5de3e19fea0da99beac0121029f75e1ef6" + "b04e004" + "a308b1f59215a8a3a5b7958bbcf184cc24ba7ab65744487800000000", + 838, + raw_txn); + // only fill necessary values + btc_txn_input_t input[] = {{ + .value = 4500, + .prev_output_index = 0x00000000, + .script_pub_key = {.size = 23}, + }, + { + .value = 12274, + .prev_output_index = 0x00000001, + .script_pub_key = {.size = 23}, + }}; + + hex_string_to_byte_array( + // invalid txn hash test. valid txn hash/id: + // b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a2 + "b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a3", + 64, + input[0].prev_txn_hash); + // Reverse order of txn-id: + // A344A293475AC245DEE8B3343F51EE2296BAB24FCC3FE0A49628DF605E2295B0 + cy_reverse_byte_array(input[0].prev_txn_hash, sizeof(input[0].prev_txn_hash)); + + hex_string_to_byte_array( + // invalid txn hash test. valid txn hash/id: + // b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a2 + "b095225e60df2896a4e03fcc4fb2ba9622ee513f34b3e8de45c25a4793a244a3", + 64, + input[1].prev_txn_hash); + // Reverse order of txn-id: + // A344A293475AC245DEE8B3343F51EE2296BAB24FCC3FE0A49628DF605E2295B0 + cy_reverse_byte_array(input[1].prev_txn_hash, sizeof(input[1].prev_txn_hash)); + + hex_string_to_byte_array("a914bd7aabdeeef211b1bdad7218e14fea6c032101c087", + 46, + input[0].script_pub_key.bytes); + hex_string_to_byte_array("a914eaf97514c5ac1e41e413502e97ae42ebf27ace3a87", + 46, + input[1].script_pub_key.bytes); + + status = btc_verify_input_test(input, raw_txn, 419); + TEST_ASSERT_EQUAL_INT(2, status); + status = btc_verify_input_test(input + 1, raw_txn, 419); + TEST_ASSERT_EQUAL_INT(2, status); +} + /* FIX: Required to fix the hardcoded value of 106 (2 + 33 + 71) since the * signature part of the script can vary (71 bytes | 72 bytes | 73 bytes). * Check the get_transaction_weight function. */ @@ -661,6 +807,21 @@ TEST(btc_txn_helper_test, btc_script_check_script_address) { btc_check_script_address(script_pub, sizeof(script_pub), public_key)); } +TEST(btc_txn_helper_test, btc_script_check_p2sh_p2pwkh_script_address) { + uint8_t script_pub[23] = {0}; + uint8_t public_key[33] = {0}; + + hex_string_to_byte_array( + "a914336caa13e08b96080a32b5d818d59b4ab3b3674287", 46, script_pub); + hex_string_to_byte_array( + "03a1af804ac108a8a51782198c2d034b28bf90c8803f5a53f76276fa69a4eae77f", + 66, + public_key); + + TEST_ASSERT_TRUE( + btc_check_script_address(script_pub, sizeof(script_pub), public_key)); +} + TEST(btc_txn_helper_test, btc_txn_helper_p2pkh_digest_1_2) { uint8_t calculated_digest[32] = {0}; uint8_t expected_digest[32] = {0}; @@ -812,6 +973,206 @@ TEST(btc_txn_helper_test, btc_txn_helper_p2wpkh_digest_1_2) { TEST(btc_txn_helper_test, btc_txn_helper_p2wpkh_digest_2_2) { } +TEST(btc_txn_helper_test, btc_txn_helper_p2wpkh_in_p2sh_digest_1_2) { + uint8_t calculated_digest[32] = {0}; + uint8_t expected_digest[32] = {0}; + btc_segwit_cache_t expected_cache = {.filled = true}; + btc_txn_input_t input = { + .prev_txn_hash = {0}, + .value = 1000000000, + .prev_output_index = 0x00000001, + .script_pub_key = {.size = 22}, + .change_index = 0, + .address_index = 1, + .sequence = 0xFFFFFFFe, + }; + btc_sign_txn_output_t outputs[] = { + { + .value = 0x000000000bebb4b8, + .script_pub_key = {.size = 25}, + .is_change = false, + .has_changes_index = false, + }, + { + .value = 0x000000002faf0800, + .script_pub_key = {.size = 25}, + .is_change = false, + .has_changes_index = false, + }, + }; + btc_txn_context_t context = { + .init_info = {.derivation_path_count = 3, + .derivation_path = {0x80000000 + 49, + 0x80000000, + 0x80000000}}, + .metadata = {.version = 0x00000001, + .input_count = 0x01, + .output_count = 0x02, + .sighash = 0x00000001, + .locktime = 0x00000492}, + .segwit_cache = {0}, + .change_output_idx = 1, + }; + + context.inputs = &input; + context.outputs = outputs; + + hex_string_to_byte_array( + "db6b1b20aa0fd7b23880be2ecbd4a98130974cf4748fb66092ac4d3ceb1a5477", + 64, + input.prev_txn_hash); + hex_string_to_byte_array("001479091972186c449eb1ded22b78e40d009bdf0089", + 44, + input.script_pub_key.bytes); + hex_string_to_byte_array("76a914a457b684d7f0d539a46a45bbc043f35b59d0d96388ac", + 50, + outputs[0].script_pub_key.bytes); + hex_string_to_byte_array("76a914fd270b1ee6abcaea97fea7ad0402e8bd8ad6d77c88ac", + 50, + outputs[1].script_pub_key.bytes); + hex_string_to_byte_array( + "b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a", + 64, + expected_cache.hash_prevouts); + hex_string_to_byte_array( + "18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198", + 64, + expected_cache.hash_sequence); + hex_string_to_byte_array( + "de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83", + 64, + expected_cache.hash_outputs); + hex_string_to_byte_array( + "64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6", + 64, + expected_digest); + + btc_segwit_init_cache(&context); + TEST_ASSERT_EQUAL_UINT8_ARRAY( + expected_cache.hash_prevouts, context.segwit_cache.hash_prevouts, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY( + expected_cache.hash_sequence, context.segwit_cache.hash_sequence, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY( + expected_cache.hash_outputs, context.segwit_cache.hash_outputs, 32); + + btc_digest_input(&context, 0, calculated_digest); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_digest, calculated_digest, 32); +} + +TEST(btc_txn_helper_test, btc_txn_helper_p2wpkh_in_p2sh_digest_2_2) { + bool status = false; + uint8_t calculated_digest[32] = {0}; + uint8_t expected_digest[2][32] = {0}; + btc_segwit_cache_t expected_cache = {.filled = true}; + btc_txn_input_t input[] = {{ + .prev_txn_hash = {0}, + .value = 8650, + .prev_output_index = 0x00000000, + .script_pub_key = {.size = 22}, + .address_index = 0, + .sequence = 4294967295, + }, + { + .prev_txn_hash = {0}, + .value = 18123, + .prev_output_index = 0x00000000, + .script_pub_key = {.size = 22}, + .address_index = 0, + .sequence = 4294967295, + }}; + btc_sign_txn_output_t outputs[] = { + { + .value = 4500, + .script_pub_key = {.size = 23}, + .is_change = false, + .has_changes_index = false, + }, + { + .value = 12274, + .script_pub_key = {.size = 23}, + .is_change = false, + .has_changes_index = false, + }, + }; + btc_txn_context_t context = { + .init_info = {.derivation_path_count = 3, + .derivation_path = {0x80000000 + 49, + 0x80000001, + 0x80000000}}, + .metadata = {.version = 0x00000002, + .input_count = 0x02, + .output_count = 0x02, + .sighash = 0x01, + .locktime = 0}, + .segwit_cache = {0}, + }; + + context.inputs = &input; + context.outputs = outputs; + + hex_string_to_byte_array( + "58afb1ece76f01c24f4935f453d210518163cb1d0383eaec331b202ebeb5e389", + 64, + input[0].prev_txn_hash); + hex_string_to_byte_array("0014a76cad25cb569bb47305513ebedd6011dc419dee", + 44, + input[0].script_pub_key.bytes); + hex_string_to_byte_array( + "2b3682b35925885001f0e321df28d4ac675a9cbbccef2a69533bea7c5e5ad2c4", + 64, + input[1].prev_txn_hash); + hex_string_to_byte_array("0014a76cad25cb569bb47305513ebedd6011dc419dee", + 44, + input[1].script_pub_key.bytes); + /*outputs*/ + hex_string_to_byte_array("a914bd7aabdeeef211b1bdad7218e14fea6c032101c087", + 46, + outputs[0].script_pub_key.bytes); + hex_string_to_byte_array("a914eaf97514c5ac1e41e413502e97ae42ebf27ace3a87", + 46, + outputs[1].script_pub_key.bytes); + hex_string_to_byte_array( + "ce9186e6b6b4ce2ed0d42bdd2ae8a0003188b2b5070139eb53d1bd49ade831b7", + 64, + expected_cache.hash_prevouts); + hex_string_to_byte_array( + "752adad0a7b9ceca853768aebb6965eca126a62965f698a0c1bc43d83db632ad", + 64, + expected_cache.hash_sequence); + hex_string_to_byte_array( + "c42e53e6e72da4a8068e3115134201ebdcd8567fcaedaffc3169ab673ef4f0f9", + 64, + expected_cache.hash_outputs); + + btc_segwit_init_cache(&context); + TEST_ASSERT_EQUAL_UINT8_ARRAY( + expected_cache.hash_prevouts, context.segwit_cache.hash_prevouts, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY( + expected_cache.hash_sequence, context.segwit_cache.hash_sequence, 32); + TEST_ASSERT_EQUAL_UINT8_ARRAY( + expected_cache.hash_outputs, context.segwit_cache.hash_outputs, 32); + + /* digest input 0*/ + hex_string_to_byte_array( + "84b6c444101a5d7d41c521b1034bf2c82afb19d45fe2a4fc6bdfae4edd720334", + 64, + expected_digest[0]); + + status = btc_digest_input(&context, 0, calculated_digest); + TEST_ASSERT_TRUE(status); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_digest[0], calculated_digest, 32); + + /* digest input 1*/ + hex_string_to_byte_array( + "7503b14676ff1de1d85819f31e43b96a5f400c273e7f143d8b05aa32e261a2b1", + 64, + expected_digest[1]); + + status = btc_digest_input(&context, 1, calculated_digest); + TEST_ASSERT_TRUE(status); + TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_digest[1], calculated_digest, 32); +} + TEST(btc_txn_helper_test, btc_txn_helper_get_fee) { /* Test data source: * https://blockchain.info/rawtx/b77a9ff6738877d4eb2d300b1c0ec7ca4d14353e8d501d55139019609ca2e4e5?format=json diff --git a/tests/unit_test_lists.c b/tests/unit_test_lists.c index 276b38da6..6ca10494b 100644 --- a/tests/unit_test_lists.c +++ b/tests/unit_test_lists.c @@ -140,6 +140,10 @@ TEST_GROUP_RUNNER(btc_txn_helper_test) { RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_verify_input_p2pkh_fail); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_verify_input_p2wpkh); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_verify_input_p2wpkh_fail); + RUN_TEST_CASE(btc_txn_helper_test, + btc_txn_helper_verify_input_p2wpkh_in_p2sh); + RUN_TEST_CASE(btc_txn_helper_test, + btc_txn_helper_verify_input_p2wpkh_in_p2sh_fail); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_transaction_weight_legacy1); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_transaction_weight_legacy2); @@ -153,10 +157,14 @@ TEST_GROUP_RUNNER(btc_txn_helper_test) { RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_format_value_1btc); RUN_TEST_CASE(btc_txn_helper_test, btc_script_check_script_address); + RUN_TEST_CASE(btc_txn_helper_test, + btc_script_check_p2sh_p2pwkh_script_address); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_p2pkh_digest_1_2); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_p2wpkh_digest_1_2); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_p2wpkh_digest_2_2); + RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_p2wpkh_in_p2sh_digest_1_2); + RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_p2wpkh_in_p2sh_digest_2_2); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_get_fee); RUN_TEST_CASE(btc_txn_helper_test, btc_txn_helper_get_fee_overspend);