Skip to content

Commit 515b42d

Browse files
committed
sign_tx: produce schnorr signatues from the BIP-0341 tweaked private key for p2tr inputs
Removes another repeated sighash type check, re-intoducing it only in the taproot branch where we avoid appending the sighash type byte for SIGHASH_DEFAULT signatures.
1 parent 9f3dd01 commit 515b42d

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

main/wallet.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ bool wallet_get_signer_commitment(const uint8_t* signature_hash, const size_t si
10371037
bool wallet_sign_tx_input_hash(
10381038
signing_data_t* sig_data, const uint8_t* ae_host_entropy, const size_t ae_host_entropy_len)
10391039
{
1040-
if (!sig_data || sig_data->path_len == 0 || sig_data->sighash == 0) {
1040+
if (!sig_data || sig_data->path_len == 0) {
10411041
return false;
10421042
}
10431043
if ((!ae_host_entropy && ae_host_entropy_len > 0)
@@ -1053,16 +1053,34 @@ bool wallet_sign_tx_input_hash(
10531053
wallet_get_privkey(sig_data->path, sig_data->path_len, privkey, sizeof(privkey));
10541054

10551055
// Generate signature as appropriate
1056-
int wret;
1057-
if (ae_host_entropy) {
1056+
int wret = WALLY_OK;
1057+
if (ae_host_entropy && sig_data->segwit_ver != SEGWIT_V1) {
10581058
// Anti-Exfil signature
10591059
wret = wally_ae_sig_from_bytes(privkey, sizeof(privkey), sig_data->signature_hash,
10601060
sizeof(sig_data->signature_hash), ae_host_entropy, ae_host_entropy_len, EC_FLAG_ECDSA, signature,
10611061
sizeof(signature));
10621062
} else {
1063-
// Standard EC signature
1064-
wret = wally_ec_sig_from_bytes(privkey, sizeof(privkey), sig_data->signature_hash,
1065-
sizeof(sig_data->signature_hash), EC_FLAG_ECDSA | EC_FLAG_GRIND_R, signature, sizeof(signature));
1063+
// Standard EC or taproot signature
1064+
uint8_t tweaked[EC_PRIVATE_KEY_LEN];
1065+
uint8_t* signing_key;
1066+
uint32_t flags;
1067+
SENSITIVE_PUSH(tweaked, sizeof(tweaked));
1068+
1069+
if (sig_data->segwit_ver != SEGWIT_V1) {
1070+
// ECDSA. Sign directly with the private key
1071+
signing_key = privkey;
1072+
flags = EC_FLAG_ECDSA | EC_FLAG_GRIND_R;
1073+
} else {
1074+
// Taproot. Tweak the private key before Schnorr signing
1075+
signing_key = tweaked;
1076+
flags = EC_FLAG_SCHNORR;
1077+
wret = wally_ec_private_key_bip341_tweak(privkey, sizeof(privkey), NULL, 0, 0, tweaked, sizeof(tweaked));
1078+
}
1079+
if (wret == WALLY_OK) {
1080+
wret = wally_ec_sig_from_bytes(signing_key, EC_PRIVATE_KEY_LEN, sig_data->signature_hash,
1081+
sizeof(sig_data->signature_hash), flags, signature, sizeof(signature));
1082+
}
1083+
SENSITIVE_POP(tweaked);
10661084
}
10671085
SENSITIVE_POP(privkey);
10681086

@@ -1071,12 +1089,22 @@ bool wallet_sign_tx_input_hash(
10711089
return false;
10721090
}
10731091

1074-
// Make the signature in DER format
1075-
JADE_WALLY_VERIFY(wally_ec_sig_to_der(
1076-
signature, sizeof(signature), sig_data->sig, sizeof(sig_data->sig) - 1, &sig_data->sig_len));
1077-
JADE_ASSERT(sig_data->sig_len <= sizeof(sig_data->sig) - 1);
1092+
if (sig_data->segwit_ver != SEGWIT_V1) {
1093+
// ECDSA: DER-encode the signature
1094+
JADE_WALLY_VERIFY(wally_ec_sig_to_der(
1095+
signature, sizeof(signature), sig_data->sig, sizeof(sig_data->sig) - 1, &sig_data->sig_len));
1096+
} else {
1097+
// Taproot: Copy the Schnorr signature as-is.
1098+
sig_data->sig_len = sizeof(signature);
1099+
memcpy(sig_data->sig, signature, sizeof(signature));
1100+
if (sig_data->sighash == WALLY_SIGHASH_DEFAULT) {
1101+
// We don't add the sighash byte for default signatures, so we are done
1102+
return true;
1103+
}
1104+
}
10781105

10791106
// Append the sighash used
1107+
JADE_ASSERT(sig_data->sig_len <= sizeof(sig_data->sig) - 1);
10801108
sig_data->sig[sig_data->sig_len] = sig_data->sighash;
10811109
sig_data->sig_len += 1;
10821110

0 commit comments

Comments
 (0)