Skip to content

Commit 92ee5a7

Browse files
committed
Test BIP341 sighash code
1 parent 670e808 commit 92ee5a7

File tree

2 files changed

+108
-2
lines changed

2 files changed

+108
-2
lines changed

src/internal_macros.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ macro_rules! hex_script (($s:expr) => (<$crate::Script as ::core::str::FromStr>:
165165
#[cfg(test)]
166166
macro_rules! hex_hash (($h:ident, $s:expr) => ($h::from_slice(&<$crate::prelude::Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()).unwrap()));
167167

168+
#[cfg(test)]
169+
macro_rules! hex_decode (($h:ident, $s:expr) => (deserialize::<$h>(&<$crate::prelude::Vec<u8> as $crate::hashes::hex::FromHex>::from_hex($s).unwrap()).unwrap()));
170+
168171
macro_rules! serde_string_impl {
169172
($name:ident, $expecting:expr) => {
170173
#[cfg(feature = "serde")]

src/util/sighash.rs

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,8 +750,13 @@ mod tests {
750750
use consensus::deserialize;
751751
use hashes::hex::FromHex;
752752
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+
755760
use {Script, Transaction, TxIn, TxOut};
756761

757762
#[test]
@@ -996,4 +1001,102 @@ mod tests {
9961001
let expected = Vec::from_hex(expected_hash).unwrap();
9971002
assert_eq!(expected, hash.into_inner());
9981003
}
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+
}
9991102
}

0 commit comments

Comments
 (0)