@@ -750,8 +750,13 @@ mod tests {
750
750
use consensus:: deserialize;
751
751
use hashes:: hex:: FromHex ;
752
752
use hashes:: { Hash , HashEngine } ;
753
- use util:: sighash:: { Annex , Error , Prevouts , ScriptPath , SigHashCache , TapLeafHash } ;
754
- use util:: taproot:: TapSighashHash ;
753
+ use util:: sighash:: { Annex , Error , Prevouts , ScriptPath , SigHashCache } ;
754
+ use std:: str:: FromStr ;
755
+ use hashes:: hex:: ToHex ;
756
+ use util:: taproot:: { TapTweakHash , TapSighashHash , TapBranchHash , TapLeafHash } ;
757
+ use secp256k1:: { self , SecretKey } ;
758
+ extern crate serde_json;
759
+
755
760
use { Script , Transaction , TxIn , TxOut } ;
756
761
757
762
#[ test]
@@ -996,4 +1001,102 @@ mod tests {
996
1001
let expected = Vec :: from_hex ( expected_hash) . unwrap ( ) ;
997
1002
assert_eq ! ( expected, hash. into_inner( ) ) ;
998
1003
}
1004
+
1005
+ #[ test]
1006
+ fn bip_341_sighash_tests ( ) {
1007
+
1008
+ let data = bip_341_read_json ( ) ;
1009
+ assert ! ( data[ "version" ] . as_u64( ) . unwrap( ) == 1u64 ) ;
1010
+ let secp = & secp256k1:: Secp256k1 :: new ( ) ;
1011
+ let key_path = & data[ "keyPathSpending" ] . as_array ( ) . unwrap ( ) [ 0 ] ;
1012
+
1013
+ let raw_unsigned_tx = hex_decode ! ( Transaction , key_path[ "given" ] [ "rawUnsignedTx" ] . as_str( ) . unwrap( ) ) ;
1014
+ let mut utxos = vec ! [ ] ;
1015
+ for utxo in key_path[ "given" ] [ "utxosSpent" ] . as_array ( ) . unwrap ( ) {
1016
+ let spk = hex_script ! ( utxo[ "scriptPubKey" ] . as_str( ) . unwrap( ) ) ;
1017
+ let amt = utxo[ "amountSats" ] . as_u64 ( ) . unwrap ( ) ;
1018
+ utxos. push ( TxOut { value : amt, script_pubkey : spk } ) ;
1019
+ }
1020
+
1021
+ // Test intermediary
1022
+ let mut cache = SigHashCache :: new ( & raw_unsigned_tx) ;
1023
+ let expected_amt_hash = key_path[ "intermediary" ] [ "hashAmounts" ] . as_str ( ) . unwrap ( ) ;
1024
+ let expected_outputs_hash = key_path[ "intermediary" ] [ "hashOutputs" ] . as_str ( ) . unwrap ( ) ;
1025
+ let expected_prevouts_hash = key_path[ "intermediary" ] [ "hashPrevouts" ] . as_str ( ) . unwrap ( ) ;
1026
+ let expected_spks_hash = key_path[ "intermediary" ] [ "hashScriptPubkeys" ] . as_str ( ) . unwrap ( ) ;
1027
+ let expected_sequences_hash = key_path[ "intermediary" ] [ "hashSequences" ] . as_str ( ) . unwrap ( ) ;
1028
+
1029
+ // Compute all caches
1030
+ assert_eq ! ( expected_amt_hash, cache. taproot_cache( & utxos) . amounts. to_hex( ) ) ;
1031
+ assert_eq ! ( expected_outputs_hash, cache. common_cache( ) . outputs. to_hex( ) ) ;
1032
+ assert_eq ! ( expected_prevouts_hash, cache. common_cache( ) . prevouts. to_hex( ) ) ;
1033
+ assert_eq ! ( expected_spks_hash, cache. taproot_cache( & utxos) . script_pubkeys. to_hex( ) ) ;
1034
+ assert_eq ! ( expected_sequences_hash, cache. common_cache( ) . sequences. to_hex( ) ) ;
1035
+
1036
+ for inp in key_path[ "inputSpending" ] . as_array ( ) . unwrap ( ) {
1037
+ let tx_ind = inp[ "given" ] [ "txinIndex" ] . as_u64 ( ) . unwrap ( ) as usize ;
1038
+ let internal_priv_key = hex_hash ! ( SecretKey , inp[ "given" ] [ "internalPrivkey" ] . as_str( ) . unwrap( ) ) ;
1039
+ let merkle_root = if inp[ "given" ] [ "merkleRoot" ] . is_null ( ) {
1040
+ None
1041
+ } else {
1042
+ Some ( hex_hash ! ( TapBranchHash , inp[ "given" ] [ "merkleRoot" ] . as_str( ) . unwrap( ) ) )
1043
+ } ;
1044
+ let hash_ty = SchnorrSigHashType :: from_u8 ( inp[ "given" ] [ "hashType" ] . as_u64 ( ) . unwrap ( ) as u8 ) . unwrap ( ) ;
1045
+
1046
+ use schnorr:: PublicKey as XOnlyPubKey ;
1047
+ let expected_internal_pk = hex_hash ! ( XOnlyPubKey , inp[ "intermediary" ] [ "internalPubkey" ] . as_str( ) . unwrap( ) ) ;
1048
+ let expected_tweak = hex_hash ! ( TapTweakHash , inp[ "intermediary" ] [ "tweak" ] . as_str( ) . unwrap( ) ) ;
1049
+ let _expected_tweaked_priv_key = hex_hash ! ( SecretKey , inp[ "intermediary" ] [ "tweakedPrivkey" ] . as_str( ) . unwrap( ) ) ;
1050
+ let expected_sig_msg = Vec :: < u8 > :: from_hex ( inp[ "intermediary" ] [ "sigMsg" ] . as_str ( ) . unwrap ( ) ) . unwrap ( ) ;
1051
+ let expected_sig_hash = hex_hash ! ( TapSighashHash , inp[ "intermediary" ] [ "sigHash" ] . as_str( ) . unwrap( ) ) ;
1052
+ let sig_str = inp[ "expected" ] [ "witness" ] [ 0 ] . as_str ( ) . unwrap ( ) ;
1053
+ let ( expected_key_spend_sig, expected_hash_ty) = if sig_str. len ( ) == 128 {
1054
+ ( secp256k1:: schnorrsig:: Signature :: from_str ( sig_str) . unwrap ( ) , SchnorrSigHashType :: Default )
1055
+ } else {
1056
+ let hash_ty = SchnorrSigHashType :: from_u8 ( Vec :: < u8 > :: from_hex ( & sig_str[ 128 ..] ) . unwrap ( ) [ 0 ] ) . unwrap ( ) ;
1057
+ ( secp256k1:: schnorrsig:: Signature :: from_str ( & sig_str[ ..128 ] ) . unwrap ( ) , hash_ty)
1058
+ } ;
1059
+
1060
+ // tests
1061
+ let keypair = secp256k1:: schnorrsig:: KeyPair :: from_secret_key ( & secp, internal_priv_key) ;
1062
+ let internal_key = XOnlyPubKey :: from_keypair ( secp, & keypair) ;
1063
+ let tweak = TapTweakHash :: from_key_and_tweak ( internal_key, merkle_root) ;
1064
+ let mut tweaked_keypair = keypair;
1065
+ tweaked_keypair. tweak_add_assign ( & secp, & tweak) . unwrap ( ) ;
1066
+ let mut sig_msg = Vec :: new ( ) ;
1067
+ cache. taproot_encode_signing_data_to (
1068
+ & mut sig_msg,
1069
+ tx_ind,
1070
+ & Prevouts :: All ( & utxos) ,
1071
+ None ,
1072
+ None ,
1073
+ hash_ty
1074
+ ) . unwrap ( ) ;
1075
+ let sig_hash = cache. taproot_signature_hash (
1076
+ tx_ind,
1077
+ & Prevouts :: All ( & utxos) ,
1078
+ None ,
1079
+ None ,
1080
+ hash_ty
1081
+ ) . unwrap ( ) ;
1082
+
1083
+ let msg = secp256k1:: Message :: from_slice ( & sig_hash) . unwrap ( ) ;
1084
+ let key_spend_sig = secp. schnorrsig_sign_with_aux_rand ( & msg, & tweaked_keypair, & [ 0u8 ; 32 ] ) ;
1085
+
1086
+ assert_eq ! ( expected_internal_pk, internal_key) ;
1087
+ assert_eq ! ( expected_tweak, tweak) ;
1088
+ assert_eq ! ( expected_sig_msg, sig_msg) ;
1089
+ assert_eq ! ( expected_sig_hash, sig_hash) ;
1090
+ assert_eq ! ( expected_hash_ty, hash_ty) ;
1091
+ assert_eq ! ( expected_key_spend_sig, key_spend_sig) ;
1092
+ // TODO: Uncomment these after a rust-secp release
1093
+ // let tweaked_priv_key = SecretKey::from_keypair(&tweaked_keypair);
1094
+ // assert_eq!(expected_tweaked_priv_key, tweaked_priv_key);
1095
+ }
1096
+ }
1097
+
1098
+ fn bip_341_read_json ( ) -> serde_json:: Value {
1099
+ let json_str = include_str ! ( "../../test_data/bip341_tests.json" ) ;
1100
+ serde_json:: from_str ( json_str) . expect ( "JSON was not well-formatted" )
1101
+ }
999
1102
}
0 commit comments