Skip to content

Commit 7bddfd5

Browse files
OttoAllmendingerllm-git
andcommitted
feat(wasm-utxo): pass SighashCache to Taproot signature verification
Optimize Taproot script path signature verification by reusing the SighashCache, allowing it to be created once and passed into the verification function. This improves performance for bulk signature verification by avoiding redundant cache creation. Issue: BTC-2866 Co-authored-by: llm-git <llm-git@ttll.de>
1 parent 5c34219 commit 7bddfd5

2 files changed

Lines changed: 13 additions & 6 deletions

File tree

packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2578,11 +2578,14 @@ impl BitGoPsbt {
25782578

25792579
// Check for Taproot script path signatures first
25802580
if !input.tap_script_sigs.is_empty() {
2581+
use miniscript::bitcoin::sighash::SighashCache;
2582+
let mut cache = SighashCache::new(&psbt.unsigned_tx);
25812583
return psbt_wallet_input::verify_taproot_script_signature(
25822584
secp,
25832585
psbt,
25842586
input_index,
25852587
public_key,
2588+
&mut cache,
25862589
);
25872590
}
25882591

@@ -2603,11 +2606,14 @@ impl BitGoPsbt {
26032606

26042607
// Check for Taproot script path signatures first
26052608
if !input.tap_script_sigs.is_empty() {
2609+
use miniscript::bitcoin::sighash::SighashCache;
2610+
let mut cache = SighashCache::new(&psbt.unsigned_tx);
26062611
return psbt_wallet_input::verify_taproot_script_signature(
26072612
secp,
26082613
psbt,
26092614
input_index,
26102615
public_key,
2616+
&mut cache,
26112617
);
26122618
}
26132619

packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/psbt_wallet_input.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,23 @@ pub fn derive_pubkey_from_input<C: secp256k1::Verification>(
131131
/// - `psbt`: The PSBT containing the transaction and inputs
132132
/// - `input_index`: The index of the input to verify
133133
/// - `public_key`: The compressed public key to verify the signature for
134+
/// - `cache`: Mutable reference to a SighashCache for computing sighash (can be reused for bulk verification)
134135
///
135136
/// # Returns
136137
/// - `Ok(true)` if a valid Schnorr signature exists for the public key
137138
/// - `Ok(false)` if no signature exists or verification fails
138139
/// - `Err(String)` if required data is missing or computation fails
139-
pub fn verify_taproot_script_signature<C: secp256k1::Verification>(
140+
pub fn verify_taproot_script_signature<
141+
C: secp256k1::Verification,
142+
T: std::borrow::Borrow<miniscript::bitcoin::Transaction>,
143+
>(
140144
secp: &secp256k1::Secp256k1<C>,
141145
psbt: &miniscript::bitcoin::psbt::Psbt,
142146
input_index: usize,
143147
public_key: miniscript::bitcoin::CompressedPublicKey,
148+
cache: &mut miniscript::bitcoin::sighash::SighashCache<T>,
144149
) -> Result<bool, String> {
145-
use miniscript::bitcoin::{
146-
hashes::Hash, sighash::Prevouts, sighash::SighashCache, TapLeafHash, XOnlyPublicKey,
147-
};
150+
use miniscript::bitcoin::{hashes::Hash, sighash::Prevouts, TapLeafHash, XOnlyPublicKey};
148151

149152
let input = &psbt.inputs[input_index];
150153

@@ -160,8 +163,6 @@ pub fn verify_taproot_script_signature<C: secp256k1::Verification>(
160163
for ((sig_pubkey, leaf_hash), signature) in &input.tap_script_sigs {
161164
if sig_pubkey == &x_only_key {
162165
// Found a signature for this public key, now verify it
163-
let mut cache = SighashCache::new(&psbt.unsigned_tx);
164-
165166
// Compute taproot script spend sighash
166167
let prevouts = super::p2tr_musig2_input::collect_prevouts(psbt)
167168
.map_err(|e| format!("Failed to collect prevouts: {}", e))?;

0 commit comments

Comments
 (0)