@@ -91,7 +91,7 @@ use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpriv};
9191use bitcoin:: hashes:: hash160;
9292use bitcoin:: secp256k1:: Message ;
9393use bitcoin:: sighash:: { EcdsaSighashType , TapSighash , TapSighashType } ;
94- use bitcoin:: { ecdsa, psbt, sighash, taproot, transaction } ;
94+ use bitcoin:: { ecdsa, psbt, sighash, taproot} ;
9595use bitcoin:: { key:: TapTweak , key:: XOnlyPublicKey , secp256k1} ;
9696use bitcoin:: { PrivateKey , Psbt , PublicKey } ;
9797
@@ -159,12 +159,10 @@ pub enum SignerError {
159159 NonStandardSighash ,
160160 /// Invalid SIGHASH for the signing context in use
161161 InvalidSighash ,
162- /// Error while computing the hash to sign a P2WPKH input.
163- SighashP2wpkh ( sighash:: P2wpkhError ) ,
164162 /// Error while computing the hash to sign a Taproot input.
165163 SighashTaproot ( sighash:: TaprootError ) ,
166- /// Error while computing the hash, out of bounds access on the transaction inputs .
167- TxInputsIndexError ( transaction :: InputsIndexError ) ,
164+ /// PSBT sign error .
165+ Psbt ( psbt :: SignError ) ,
168166 /// Miniscript PSBT error
169167 MiniscriptPsbt ( MiniscriptPsbtError ) ,
170168 /// To be used only by external libraries implementing [`InputSigner`] or
@@ -173,24 +171,6 @@ pub enum SignerError {
173171 External ( String ) ,
174172}
175173
176- impl From < transaction:: InputsIndexError > for SignerError {
177- fn from ( v : transaction:: InputsIndexError ) -> Self {
178- Self :: TxInputsIndexError ( v)
179- }
180- }
181-
182- impl From < sighash:: P2wpkhError > for SignerError {
183- fn from ( e : sighash:: P2wpkhError ) -> Self {
184- Self :: SighashP2wpkh ( e)
185- }
186- }
187-
188- impl From < sighash:: TaprootError > for SignerError {
189- fn from ( e : sighash:: TaprootError ) -> Self {
190- Self :: SighashTaproot ( e)
191- }
192- }
193-
194174impl fmt:: Display for SignerError {
195175 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
196176 match self {
@@ -205,9 +185,8 @@ impl fmt::Display for SignerError {
205185 Self :: MissingHdKeypath => write ! ( f, "Missing fingerprint and derivation path" ) ,
206186 Self :: NonStandardSighash => write ! ( f, "The psbt contains a non standard sighash" ) ,
207187 Self :: InvalidSighash => write ! ( f, "Invalid SIGHASH for the signing context in use" ) ,
208- Self :: SighashP2wpkh ( err) => write ! ( f, "Error while computing the hash to sign a P2WPKH input: {}" , err) ,
209188 Self :: SighashTaproot ( err) => write ! ( f, "Error while computing the hash to sign a Taproot input: {}" , err) ,
210- Self :: TxInputsIndexError ( err) => write ! ( f, "Error while computing the hash, out of bounds access on the transaction inputs : {}" , err) ,
189+ Self :: Psbt ( err) => write ! ( f, "Error computing the sighash : {}" , err) ,
211190 Self :: MiniscriptPsbt ( err) => write ! ( f, "Miniscript PSBT error: {}" , err) ,
212191 Self :: External ( err) => write ! ( f, "{}" , err) ,
213192 }
@@ -472,92 +451,87 @@ impl InputSigner for SignerWrapper<PrivateKey> {
472451 }
473452
474453 let pubkey = PublicKey :: from_private_key ( secp, self ) ;
475- let x_only_pubkey = XOnlyPublicKey :: from ( pubkey. inner ) ;
476-
477- if let SignerContext :: Tap { is_internal_key } = self . ctx {
478- if let Some ( psbt_internal_key) = psbt. inputs [ input_index] . tap_internal_key {
479- if is_internal_key
480- && psbt. inputs [ input_index] . tap_key_sig . is_none ( )
481- && sign_options. sign_with_tap_internal_key
482- && x_only_pubkey == psbt_internal_key
483- {
484- let ( hash, hash_ty) = compute_tap_sighash ( psbt, input_index, None ) ?;
485- sign_psbt_schnorr (
486- & self . inner ,
487- x_only_pubkey,
488- None ,
489- & mut psbt. inputs [ input_index] ,
490- hash,
491- hash_ty,
492- secp,
493- ) ;
454+
455+ match self . ctx {
456+ SignerContext :: Tap { is_internal_key } => {
457+ let x_only_pubkey = XOnlyPublicKey :: from ( pubkey. inner ) ;
458+
459+ if let Some ( psbt_internal_key) = psbt. inputs [ input_index] . tap_internal_key {
460+ if is_internal_key
461+ && psbt. inputs [ input_index] . tap_key_sig . is_none ( )
462+ && sign_options. sign_with_tap_internal_key
463+ && x_only_pubkey == psbt_internal_key
464+ {
465+ let ( sighash, sighash_type) = compute_tap_sighash ( psbt, input_index, None ) ?;
466+ sign_psbt_schnorr (
467+ & self . inner ,
468+ x_only_pubkey,
469+ None ,
470+ & mut psbt. inputs [ input_index] ,
471+ sighash,
472+ sighash_type,
473+ secp,
474+ ) ;
475+ }
494476 }
495- }
496477
497- if let Some ( ( leaf_hashes, _) ) =
498- psbt. inputs [ input_index] . tap_key_origins . get ( & x_only_pubkey)
499- {
500- let leaf_hashes = leaf_hashes
501- . iter ( )
502- . filter ( |lh| {
503- // Removing the leaves we shouldn't sign for
504- let should_sign = match & sign_options. tap_leaves_options {
505- TapLeavesOptions :: All => true ,
506- TapLeavesOptions :: Include ( v) => v. contains ( lh) ,
507- TapLeavesOptions :: Exclude ( v) => !v. contains ( lh) ,
508- TapLeavesOptions :: None => false ,
509- } ;
510- // Filtering out the leaves without our key
511- should_sign
512- && !psbt. inputs [ input_index]
513- . tap_script_sigs
514- . contains_key ( & ( x_only_pubkey, * * lh) )
515- } )
516- . cloned ( )
517- . collect :: < Vec < _ > > ( ) ;
518- for lh in leaf_hashes {
519- let ( hash, hash_ty) = compute_tap_sighash ( psbt, input_index, Some ( lh) ) ?;
520- sign_psbt_schnorr (
521- & self . inner ,
522- x_only_pubkey,
523- Some ( lh) ,
524- & mut psbt. inputs [ input_index] ,
525- hash,
526- hash_ty,
527- secp,
528- ) ;
478+ if let Some ( ( leaf_hashes, _) ) =
479+ psbt. inputs [ input_index] . tap_key_origins . get ( & x_only_pubkey)
480+ {
481+ let leaf_hashes = leaf_hashes
482+ . iter ( )
483+ . filter ( |lh| {
484+ // Removing the leaves we shouldn't sign for
485+ let should_sign = match & sign_options. tap_leaves_options {
486+ TapLeavesOptions :: All => true ,
487+ TapLeavesOptions :: Include ( v) => v. contains ( lh) ,
488+ TapLeavesOptions :: Exclude ( v) => !v. contains ( lh) ,
489+ TapLeavesOptions :: None => false ,
490+ } ;
491+ // Filtering out the leaves without our key
492+ should_sign
493+ && !psbt. inputs [ input_index]
494+ . tap_script_sigs
495+ . contains_key ( & ( x_only_pubkey, * * lh) )
496+ } )
497+ . cloned ( )
498+ . collect :: < Vec < _ > > ( ) ;
499+ for lh in leaf_hashes {
500+ let ( sighash, sighash_type) =
501+ compute_tap_sighash ( psbt, input_index, Some ( lh) ) ?;
502+ sign_psbt_schnorr (
503+ & self . inner ,
504+ x_only_pubkey,
505+ Some ( lh) ,
506+ & mut psbt. inputs [ input_index] ,
507+ sighash,
508+ sighash_type,
509+ secp,
510+ ) ;
511+ }
529512 }
530513 }
514+ SignerContext :: Segwitv0 | SignerContext :: Legacy => {
515+ if psbt. inputs [ input_index] . partial_sigs . contains_key ( & pubkey) {
516+ return Ok ( ( ) ) ;
517+ }
531518
532- return Ok ( ( ) ) ;
533- }
534-
535- if psbt. inputs [ input_index] . partial_sigs . contains_key ( & pubkey) {
536- return Ok ( ( ) ) ;
537- }
519+ let mut sighasher = sighash:: SighashCache :: new ( psbt. unsigned_tx . clone ( ) ) ;
520+ let ( msg, sighash_type) = psbt
521+ . sighash_ecdsa ( input_index, & mut sighasher)
522+ . map_err ( SignerError :: Psbt ) ?;
538523
539- let ( hash, hash_ty) = match self . ctx {
540- SignerContext :: Segwitv0 => {
541- let ( h, t) = compute_segwitv0_sighash ( psbt, input_index) ?;
542- let h = h. to_raw_hash ( ) ;
543- ( h, t)
544- }
545- SignerContext :: Legacy => {
546- let ( h, t) = compute_legacy_sighash ( psbt, input_index) ?;
547- let h = h. to_raw_hash ( ) ;
548- ( h, t)
524+ sign_psbt_ecdsa (
525+ & self . inner ,
526+ pubkey,
527+ & mut psbt. inputs [ input_index] ,
528+ & msg,
529+ sighash_type,
530+ secp,
531+ sign_options. allow_grinding ,
532+ ) ;
549533 }
550- _ => return Ok ( ( ) ) , // handled above
551- } ;
552- sign_psbt_ecdsa (
553- & self . inner ,
554- pubkey,
555- & mut psbt. inputs [ input_index] ,
556- hash,
557- hash_ty,
558- secp,
559- sign_options. allow_grinding ,
560- ) ;
534+ }
561535
562536 Ok ( ( ) )
563537 }
@@ -567,12 +541,11 @@ fn sign_psbt_ecdsa(
567541 secret_key : & secp256k1:: SecretKey ,
568542 pubkey : PublicKey ,
569543 psbt_input : & mut psbt:: Input ,
570- hash : impl bitcoin :: hashes :: Hash < Bytes = [ u8 ; 32 ] > ,
544+ msg : & Message ,
571545 sighash_type : EcdsaSighashType ,
572546 secp : & SecpCtx ,
573547 allow_grinding : bool ,
574548) {
575- let msg = & Message :: from_digest ( hash. to_byte_array ( ) ) ;
576549 let signature = if allow_grinding {
577550 secp. sign_ecdsa_low_r ( msg, secret_key)
578551 } else {
@@ -594,7 +567,7 @@ fn sign_psbt_schnorr(
594567 pubkey : XOnlyPublicKey ,
595568 leaf_hash : Option < taproot:: TapLeafHash > ,
596569 psbt_input : & mut psbt:: Input ,
597- hash : TapSighash ,
570+ sighash : TapSighash ,
598571 sighash_type : TapSighashType ,
599572 secp : & SecpCtx ,
600573) {
@@ -606,7 +579,7 @@ fn sign_psbt_schnorr(
606579 Some ( _) => keypair, // no tweak for script spend
607580 } ;
608581
609- let msg = & Message :: from ( hash ) ;
582+ let msg = & Message :: from ( sighash ) ;
610583 let signature = secp. sign_schnorr_no_aux_rand ( msg, & keypair) ;
611584 secp. verify_schnorr ( & signature, msg, & XOnlyPublicKey :: from_keypair ( & keypair) . 0 )
612585 . expect ( "invalid or corrupted schnorr signature" ) ;
@@ -853,120 +826,6 @@ impl Default for SignOptions {
853826 }
854827}
855828
856- /// Computes the legacy sighash.
857- fn compute_legacy_sighash (
858- psbt : & Psbt ,
859- input_index : usize ,
860- ) -> Result < ( sighash:: LegacySighash , EcdsaSighashType ) , SignerError > {
861- if input_index >= psbt. inputs . len ( ) || input_index >= psbt. unsigned_tx . input . len ( ) {
862- return Err ( SignerError :: InputIndexOutOfRange ) ;
863- }
864-
865- let psbt_input = & psbt. inputs [ input_index] ;
866- let tx_input = & psbt. unsigned_tx . input [ input_index] ;
867-
868- let sighash_type = psbt_input
869- . sighash_type
870- . unwrap_or_else ( || EcdsaSighashType :: All . into ( ) )
871- . ecdsa_hash_ty ( )
872- . map_err ( |_| SignerError :: InvalidSighash ) ?;
873-
874- let script = match psbt_input. redeem_script {
875- Some ( ref redeem_script) => redeem_script. clone ( ) ,
876- None => {
877- let non_witness_utxo = psbt_input
878- . non_witness_utxo
879- . as_ref ( )
880- . ok_or ( SignerError :: MissingNonWitnessUtxo ) ?;
881- let prev_out = non_witness_utxo
882- . output
883- . get ( tx_input. previous_output . vout as usize )
884- . ok_or ( SignerError :: InvalidNonWitnessUtxo ) ?;
885-
886- prev_out. script_pubkey . clone ( )
887- }
888- } ;
889-
890- Ok ( (
891- sighash:: SighashCache :: new ( & psbt. unsigned_tx ) . legacy_signature_hash (
892- input_index,
893- & script,
894- sighash_type. to_u32 ( ) ,
895- ) ?,
896- sighash_type,
897- ) )
898- }
899-
900- /// Computes the segwitv0 sighash.
901- fn compute_segwitv0_sighash (
902- psbt : & Psbt ,
903- input_index : usize ,
904- ) -> Result < ( sighash:: SegwitV0Sighash , EcdsaSighashType ) , SignerError > {
905- if input_index >= psbt. inputs . len ( ) || input_index >= psbt. unsigned_tx . input . len ( ) {
906- return Err ( SignerError :: InputIndexOutOfRange ) ;
907- }
908-
909- let psbt_input = & psbt. inputs [ input_index] ;
910- let tx_input = & psbt. unsigned_tx . input [ input_index] ;
911-
912- let sighash_type = psbt_input
913- . sighash_type
914- . unwrap_or_else ( || EcdsaSighashType :: All . into ( ) )
915- . ecdsa_hash_ty ( )
916- . map_err ( |_| SignerError :: InvalidSighash ) ?;
917-
918- // Always try first with the non-witness utxo
919- let utxo = if let Some ( prev_tx) = & psbt_input. non_witness_utxo {
920- // Check the provided prev-tx
921- if prev_tx. compute_txid ( ) != tx_input. previous_output . txid {
922- return Err ( SignerError :: InvalidNonWitnessUtxo ) ;
923- }
924-
925- // The output should be present, if it's missing the `non_witness_utxo` is invalid
926- prev_tx
927- . output
928- . get ( tx_input. previous_output . vout as usize )
929- . ok_or ( SignerError :: InvalidNonWitnessUtxo ) ?
930- } else if let Some ( witness_utxo) = & psbt_input. witness_utxo {
931- // Fallback to the witness_utxo. If we aren't allowed to use it, signing should fail
932- // before we get to this point
933- witness_utxo
934- } else {
935- // Nothing has been provided
936- return Err ( SignerError :: MissingNonWitnessUtxo ) ;
937- } ;
938- let value = utxo. value ;
939-
940- let mut sighasher = sighash:: SighashCache :: new ( & psbt. unsigned_tx ) ;
941-
942- let sighash = match psbt_input. witness_script {
943- Some ( ref witness_script) => {
944- sighasher. p2wsh_signature_hash ( input_index, witness_script, value, sighash_type) ?
945- }
946- None => {
947- if utxo. script_pubkey . is_p2wpkh ( ) {
948- sighasher. p2wpkh_signature_hash (
949- input_index,
950- & utxo. script_pubkey ,
951- value,
952- sighash_type,
953- ) ?
954- } else if psbt_input
955- . redeem_script
956- . as_ref ( )
957- . map ( |s| s. is_p2wpkh ( ) )
958- . unwrap_or ( false )
959- {
960- let script_pubkey = psbt_input. redeem_script . as_ref ( ) . unwrap ( ) ;
961- sighasher. p2wpkh_signature_hash ( input_index, script_pubkey, value, sighash_type) ?
962- } else {
963- return Err ( SignerError :: MissingWitnessScript ) ;
964- }
965- }
966- } ;
967- Ok ( ( sighash, sighash_type) )
968- }
969-
970829/// Computes the taproot sighash.
971830fn compute_tap_sighash (
972831 psbt : & Psbt ,
@@ -1009,7 +868,9 @@ fn compute_tap_sighash(
1009868 let extra = extra. map ( |leaf_hash| ( leaf_hash, 0xFFFFFFFF ) ) ;
1010869
1011870 Ok ( (
1012- cache. taproot_signature_hash ( input_index, & prevouts, None , extra, sighash_type) ?,
871+ cache
872+ . taproot_signature_hash ( input_index, & prevouts, None , extra, sighash_type)
873+ . map_err ( SignerError :: SighashTaproot ) ?,
1013874 sighash_type,
1014875 ) )
1015876}
0 commit comments