Skip to content

Commit 503da17

Browse files
committed
feat: Add nested-segwit support
feat: add nested segwit support test nested segwit digest for 1 inputs and 2 output transactions add tests to verify nested segwit transactions test nested segwit digest for 2 inputs and 2 output transactions
1 parent 7ad67f2 commit 503da17

File tree

5 files changed

+369
-9
lines changed

5 files changed

+369
-9
lines changed

apps/btc_family/btc_pub_key.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,17 @@ static size_t btc_get_address(const uint8_t *seed,
204204
case NON_SEGWIT:
205205
hdnode_get_address(&node, g_btc_app->p2pkh_addr_ver, addr, 35);
206206
break;
207-
// TODO: add support for taproot and segwit
207+
case PURPOSE_SEGWIT:
208+
ecdsa_get_address_segwit_p2sh(
209+
node.public_key,
210+
g_btc_app->p2sh_addr_ver,
211+
node.curve->hasher_pubkey,
212+
node.curve->hasher_base58,
213+
addr,
214+
36
215+
);
216+
break;
217+
// TODO: add support for taproot
208218
default:
209219
break;
210220
}

apps/btc_family/btc_txn.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,11 +648,26 @@ static bool sign_input(scrip_sig_t *signatures) {
648648
status = true;
649649
for (int idx = 0; idx < btc_txn_context->metadata.input_count; idx++) {
650650
// generate the input digest and respective private key
651-
status = btc_digest_input(btc_txn_context, idx, buffer);
652651
memcpy(&t_node, &node, sizeof(HDNode));
653652
hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].change_index);
654653
hdnode_private_ckd(&t_node, btc_txn_context->inputs[idx].address_index);
655654
hdnode_fill_public_key(&t_node);
655+
656+
// detect input type
657+
btc_sign_txn_input_script_pub_key_t *script =
658+
&btc_txn_context->inputs[idx].script_pub_key;
659+
btc_script_type_e type = btc_get_script_type(script->bytes, script->size);
660+
if (SCRIPT_TYPE_P2SH == type) {
661+
// replace BIP16 scriptpubkey with redeemscript(P2WPKH)
662+
uint8_t buf[22] = {0};
663+
buf[0] = 0; // version byte
664+
buf[1] = 20; // push 20 bytes
665+
ecdsa_get_pubkeyhash(t_node.public_key, t_node.curve->hasher_pubkey, buf + 2);
666+
memcpy(btc_txn_context->inputs[idx].script_pub_key.bytes, buf, 22);
667+
btc_txn_context->inputs[idx].script_pub_key.size = 22;
668+
}
669+
670+
status = btc_digest_input(btc_txn_context, idx, buffer);
656671
ecdsa_sign_digest(
657672
curve, t_node.private_key, buffer, signatures[idx].bytes, NULL, NULL);
658673
signatures[idx].size = btc_sig_to_script_sig(

apps/btc_family/btc_txn_helpers.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,6 @@ bool btc_digest_input(const btc_txn_context_t *context,
670670
btc_sign_txn_input_script_pub_key_t *script =
671671
&context->inputs[index].script_pub_key;
672672
btc_script_type_e type = btc_get_script_type(script->bytes, script->size);
673-
674673
if (SCRIPT_TYPE_P2WPKH == type) {
675674
// segwit digest calculation; could fail if segwit_cache not filled
676675
status = calculate_p2wpkh_digest(context, index, digest);

0 commit comments

Comments
 (0)