Skip to content

Commit 3114ec4

Browse files
committed
Add some multi_a interpreter tests
1 parent f711901 commit 3114ec4

File tree

1 file changed

+116
-11
lines changed

1 file changed

+116
-11
lines changed

src/interpreter/mod.rs

Lines changed: 116 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ mod tests {
10331033
use super::*;
10341034
use bitcoin;
10351035
use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
1036-
use bitcoin::secp256k1::{self, Secp256k1, VerifyOnly};
1036+
use bitcoin::secp256k1::{self, Secp256k1};
10371037
use miniscript::context::NoChecks;
10381038
use Miniscript;
10391039
use MiniscriptKey;
@@ -1046,15 +1046,21 @@ mod tests {
10461046
Vec<Vec<u8>>,
10471047
Vec<bitcoin::EcdsaSig>,
10481048
secp256k1::Message,
1049-
Secp256k1<VerifyOnly>,
1049+
Secp256k1<secp256k1::All>,
1050+
Vec<bitcoin::XOnlyPublicKey>,
1051+
Vec<bitcoin::SchnorrSig>,
1052+
Vec<Vec<u8>>,
10501053
) {
1051-
let secp_sign = secp256k1::Secp256k1::signing_only();
1052-
let secp_verify = secp256k1::Secp256k1::verification_only();
1054+
let secp = secp256k1::Secp256k1::new();
10531055
let msg = secp256k1::Message::from_slice(&b"Yoda: btc, I trust. HODL I must!"[..])
10541056
.expect("32 bytes");
10551057
let mut pks = vec![];
10561058
let mut ecdsa_sigs = vec![];
10571059
let mut der_sigs = vec![];
1060+
let mut x_only_pks = vec![];
1061+
let mut schnorr_sigs = vec![];
1062+
let mut ser_schnorr_sigs = vec![];
1063+
10581064
let mut sk = [0; 32];
10591065
for i in 1..n + 1 {
10601066
sk[0] = i as u8;
@@ -1063,10 +1069,10 @@ mod tests {
10631069

10641070
let sk = secp256k1::SecretKey::from_slice(&sk[..]).expect("secret key");
10651071
let pk = bitcoin::PublicKey {
1066-
inner: secp256k1::PublicKey::from_secret_key(&secp_sign, &sk),
1072+
inner: secp256k1::PublicKey::from_secret_key(&secp, &sk),
10671073
compressed: true,
10681074
};
1069-
let sig = secp_sign.sign_ecdsa(&msg, &sk);
1075+
let sig = secp.sign_ecdsa(&msg, &sk);
10701076
ecdsa_sigs.push(bitcoin::EcdsaSig {
10711077
sig,
10721078
hash_ty: bitcoin::EcdsaSigHashType::All,
@@ -1075,21 +1081,41 @@ mod tests {
10751081
sigser.push(0x01); // sighash_all
10761082
pks.push(pk);
10771083
der_sigs.push(sigser);
1084+
1085+
let keypair = bitcoin::KeyPair::from_secret_key(&secp, sk);
1086+
x_only_pks.push(bitcoin::XOnlyPublicKey::from_keypair(&keypair));
1087+
let schnorr_sig = secp.sign_schnorr_with_aux_rand(&msg, &keypair, &[0u8; 32]);
1088+
let schnorr_sig = bitcoin::SchnorrSig {
1089+
sig: schnorr_sig,
1090+
hash_ty: bitcoin::SchnorrSigHashType::Default,
1091+
};
1092+
ser_schnorr_sigs.push(schnorr_sig.to_vec());
1093+
schnorr_sigs.push(schnorr_sig);
10781094
}
1079-
(pks, der_sigs, ecdsa_sigs, msg, secp_verify)
1095+
(
1096+
pks,
1097+
der_sigs,
1098+
ecdsa_sigs,
1099+
msg,
1100+
secp,
1101+
x_only_pks,
1102+
schnorr_sigs,
1103+
ser_schnorr_sigs,
1104+
)
10801105
}
10811106

10821107
#[test]
10831108
fn sat_constraints() {
1084-
let (pks, der_sigs, ecdsa_sigs, sighash, secp) = setup_keys_sigs(10);
1109+
let (pks, der_sigs, ecdsa_sigs, sighash, secp, xpks, schnorr_sigs, ser_schnorr_sigs) =
1110+
setup_keys_sigs(10);
10851111
let secp_ref = &secp;
10861112
let vfyfn_ = |pksig: &KeySigPair| match pksig {
10871113
KeySigPair::Ecdsa(pk, ecdsa_sig) => secp_ref
10881114
.verify_ecdsa(&sighash, &ecdsa_sig.sig, &pk.inner)
10891115
.is_ok(),
1090-
KeySigPair::Schnorr(_xpk, _schnorr_sig) => {
1091-
unreachable!("Schnorr sig not tested in this test")
1092-
}
1116+
KeySigPair::Schnorr(xpk, schnorr_sig) => secp_ref
1117+
.verify_schnorr(&schnorr_sig.sig, &sighash, xpk)
1118+
.is_ok(),
10931119
};
10941120

10951121
fn from_stack<'txin, 'elem>(
@@ -1495,6 +1521,79 @@ mod tests {
14951521

14961522
let multi_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
14971523
assert!(multi_error.is_err());
1524+
1525+
// multi_a tests
1526+
let stack = Stack::from(vec![
1527+
stack::Element::Dissatisfied,
1528+
stack::Element::Dissatisfied,
1529+
stack::Element::Push(&ser_schnorr_sigs[2]),
1530+
stack::Element::Push(&ser_schnorr_sigs[1]),
1531+
stack::Element::Push(&ser_schnorr_sigs[0]),
1532+
]);
1533+
1534+
let elem = x_only_no_checks_ms(&format!(
1535+
"multi_a(3,{},{},{},{},{})",
1536+
xpks[0], xpks[1], xpks[2], xpks[3], xpks[4],
1537+
));
1538+
let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1539+
let constraints = from_stack(Box::new(vfyfn), stack, &elem);
1540+
1541+
let multi_a_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1542+
assert_eq!(
1543+
multi_a_satisfied.unwrap(),
1544+
vec![
1545+
SatisfiedConstraint::PublicKey {
1546+
key_sig: KeySigPair::Schnorr(xpks[0], schnorr_sigs[0])
1547+
},
1548+
SatisfiedConstraint::PublicKey {
1549+
key_sig: KeySigPair::Schnorr(xpks[1], schnorr_sigs[1])
1550+
},
1551+
SatisfiedConstraint::PublicKey {
1552+
key_sig: KeySigPair::Schnorr(xpks[2], schnorr_sigs[2])
1553+
},
1554+
]
1555+
);
1556+
1557+
// multi_a tests: wrong order of sigs
1558+
let stack = Stack::from(vec![
1559+
stack::Element::Dissatisfied,
1560+
stack::Element::Push(&ser_schnorr_sigs[2]),
1561+
stack::Element::Push(&ser_schnorr_sigs[1]),
1562+
stack::Element::Push(&ser_schnorr_sigs[0]),
1563+
stack::Element::Dissatisfied,
1564+
]);
1565+
1566+
let elem = x_only_no_checks_ms(&format!(
1567+
"multi_a(3,{},{},{},{},{})",
1568+
xpks[0], xpks[1], xpks[2], xpks[3], xpks[4],
1569+
));
1570+
let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1571+
let constraints = from_stack(Box::new(vfyfn), stack.clone(), &elem);
1572+
1573+
let multi_a_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1574+
assert!(multi_a_error.is_err());
1575+
1576+
// multi_a wrong thresh: k = 2, but three sigs
1577+
let elem = x_only_no_checks_ms(&format!(
1578+
"multi_a(2,{},{},{},{},{})",
1579+
xpks[0], xpks[1], xpks[2], xpks[3], xpks[4],
1580+
));
1581+
let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1582+
let constraints = from_stack(Box::new(vfyfn), stack.clone(), &elem);
1583+
1584+
let multi_a_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1585+
assert!(multi_a_error.is_err());
1586+
1587+
// multi_a correct thresh, but small stack
1588+
let elem = x_only_no_checks_ms(&format!(
1589+
"multi_a(3,{},{},{},{},{}, {})",
1590+
xpks[0], xpks[1], xpks[2], xpks[3], xpks[4], xpks[5]
1591+
));
1592+
let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1593+
let constraints = from_stack(Box::new(vfyfn), stack, &elem);
1594+
1595+
let multi_a_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1596+
assert!(multi_a_error.is_err());
14981597
}
14991598

15001599
// By design there is no support for parse a miniscript with BitcoinKey
@@ -1504,4 +1603,10 @@ mod tests {
15041603
Miniscript::from_str_insane(ms).unwrap();
15051604
elem.to_no_checks_ms()
15061605
}
1606+
1607+
fn x_only_no_checks_ms(ms: &str) -> Miniscript<BitcoinKey, NoChecks> {
1608+
let elem: Miniscript<bitcoin::XOnlyPublicKey, NoChecks> =
1609+
Miniscript::from_str_insane(ms).unwrap();
1610+
elem.to_no_checks_ms()
1611+
}
15071612
}

0 commit comments

Comments
 (0)