Enum sapio_miniscript::interpreter::KeySigPair
source · pub enum KeySigPair {
Ecdsa(PublicKey, EcdsaSig),
Schnorr(XOnlyPublicKey, SchnorrSig),
}
Expand description
A type for representing signatures supported as of bitcoin core 22.0
Variants§
Ecdsa(PublicKey, EcdsaSig)
A Full public key and corresponding Ecdsa signature
Schnorr(XOnlyPublicKey, SchnorrSig)
A x-only key and corresponding Schnorr signature
Implementations§
source§impl KeySigPair
impl KeySigPair
sourcepub fn as_ecdsa(&self) -> Option<(PublicKey, EcdsaSig)>
pub fn as_ecdsa(&self) -> Option<(PublicKey, EcdsaSig)>
Obtain a pair of (bitcoin::PublicKey
, bitcoin::EcdsaSig
) from KeySigPair
Examples found in repository?
examples/verify_tx.rs (line 119)
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
fn main() {
// tx `f27eba163c38ad3f34971198687a3f1882b7ec818599ffe469a8440d82261c98`
#[cfg_attr(feature="cargo-fmt", rustfmt_skip)]
let tx_bytes = vec![
0x01, 0x00, 0x00, 0x00, 0x02, 0xc5, 0x11, 0x1d, 0xb7, 0x93, 0x50, 0xc1,
0x70, 0x28, 0x41, 0x39, 0xe8, 0xe3, 0x4e, 0xb0, 0xed, 0xba, 0x64, 0x7b,
0x6c, 0x88, 0x7e, 0x9f, 0x92, 0x8f, 0xfd, 0x9b, 0x5c, 0x4a, 0x4b, 0x52,
0xd0, 0x01, 0x00, 0x00, 0x00, 0xda, 0x00, 0x47, 0x30, 0x44, 0x02, 0x20,
0x1c, 0xcc, 0x1b, 0xe9, 0xaf, 0x73, 0x4a, 0x10, 0x9f, 0x66, 0xfb, 0xed,
0xeb, 0x77, 0xb7, 0xa1, 0xf4, 0xb3, 0xc5, 0xff, 0x3d, 0x7f, 0x46, 0xf6,
0xde, 0x50, 0x69, 0xbb, 0x52, 0x7f, 0x26, 0x9d, 0x02, 0x20, 0x75, 0x37,
0x2f, 0x6b, 0xd7, 0x0c, 0xf6, 0x45, 0x7a, 0xc7, 0x0e, 0x82, 0x6f, 0xc6,
0xa7, 0x5b, 0xf7, 0xcf, 0x10, 0x8c, 0x92, 0xea, 0xcf, 0xfc, 0xb5, 0xd9,
0xfd, 0x77, 0x66, 0xa3, 0x58, 0xa9, 0x01, 0x48, 0x30, 0x45, 0x02, 0x21,
0x00, 0xfe, 0x82, 0x5b, 0xe1, 0xd5, 0xfd, 0x71, 0x67, 0x83, 0xf4, 0x55,
0xef, 0xe6, 0x6d, 0x61, 0x58, 0xff, 0xf8, 0xc3, 0x2b, 0x93, 0x1c, 0x5f,
0x3f, 0xf9, 0x8e, 0x06, 0x65, 0xa9, 0xfd, 0x8e, 0x64, 0x02, 0x20, 0x22,
0x01, 0x0f, 0xdb, 0x53, 0x8d, 0x0f, 0xa6, 0x8b, 0xd7, 0xf5, 0x20, 0x5d,
0xc1, 0xdf, 0xa6, 0xc4, 0x28, 0x1b, 0x7b, 0xb7, 0x6f, 0xc2, 0x53, 0xf7,
0x51, 0x4d, 0x83, 0x48, 0x52, 0x5f, 0x0d, 0x01, 0x47, 0x52, 0x21, 0x03,
0xd0, 0xbf, 0x26, 0x7c, 0x93, 0x78, 0xb3, 0x18, 0xb5, 0x80, 0xc2, 0x10,
0xa6, 0x78, 0xc4, 0xbb, 0x60, 0xd8, 0x44, 0x8b, 0x52, 0x0d, 0x21, 0x25,
0xa1, 0xbd, 0x37, 0x2b, 0x23, 0xae, 0xa6, 0x49, 0x21, 0x02, 0x11, 0xa8,
0x2a, 0xa6, 0x94, 0x63, 0x99, 0x0a, 0x6c, 0xdd, 0x48, 0x36, 0x76, 0x36,
0x6a, 0x44, 0xac, 0x3c, 0x98, 0xe7, 0x68, 0x54, 0x69, 0x84, 0x0b, 0xf2,
0x7a, 0x72, 0x4e, 0x40, 0x5a, 0x7e, 0x52, 0xae, 0xfd, 0xff, 0xff, 0xff,
0xea, 0x51, 0x1f, 0x33, 0x7a, 0xf5, 0x72, 0xbb, 0xad, 0xcd, 0x2e, 0x03,
0x07, 0x71, 0x62, 0x3a, 0x60, 0xcc, 0x71, 0x82, 0xad, 0x74, 0x53, 0x3e,
0xa3, 0x2f, 0xc8, 0xaa, 0x47, 0xd2, 0x0e, 0x71, 0x01, 0x00, 0x00, 0x00,
0xda, 0x00, 0x48, 0x30, 0x45, 0x02, 0x21, 0x00, 0xfa, 0x2b, 0xfb, 0x4d,
0x49, 0xb7, 0x6d, 0x9f, 0xb4, 0xc6, 0x9c, 0xc7, 0x8c, 0x36, 0xd2, 0x66,
0x92, 0x40, 0xe4, 0x57, 0x14, 0xc7, 0x19, 0x06, 0x85, 0xf7, 0xe5, 0x13,
0x94, 0xac, 0x4e, 0x37, 0x02, 0x20, 0x04, 0x95, 0x2c, 0xf7, 0x75, 0x1c,
0x45, 0x9d, 0x8a, 0x8b, 0x64, 0x76, 0x76, 0xce, 0x86, 0xf3, 0xbd, 0x69,
0xff, 0x39, 0x17, 0xcb, 0x99, 0x85, 0x14, 0xbd, 0x73, 0xb7, 0xfc, 0x04,
0xf6, 0x4c, 0x01, 0x47, 0x30, 0x44, 0x02, 0x20, 0x31, 0xae, 0x81, 0x1e,
0x35, 0x7e, 0x80, 0x00, 0x01, 0xc7, 0x57, 0x27, 0x7a, 0x22, 0x44, 0xa7,
0x2b, 0xd5, 0x9d, 0x0a, 0x00, 0xbe, 0xde, 0x49, 0x0a, 0x96, 0x12, 0x3e,
0x54, 0xce, 0x03, 0x4c, 0x02, 0x20, 0x05, 0xa2, 0x9f, 0x14, 0x30, 0x1e,
0x5e, 0x2f, 0xdc, 0x7c, 0xee, 0x49, 0x43, 0xec, 0x78, 0x78, 0xdf, 0x73,
0xde, 0x96, 0x27, 0x00, 0xa4, 0xd9, 0x43, 0x6b, 0xce, 0x24, 0xd6, 0xc3,
0xa3, 0x57, 0x01, 0x47, 0x52, 0x21, 0x03, 0x4e, 0x74, 0xde, 0x0b, 0x84,
0x3f, 0xaa, 0x60, 0x44, 0x3d, 0xf4, 0x76, 0xf1, 0xf6, 0x14, 0x4a, 0x5b,
0x0e, 0x76, 0x49, 0x9e, 0x8a, 0x26, 0x71, 0x07, 0x36, 0x5b, 0x32, 0xfa,
0xd5, 0xd0, 0xfd, 0x21, 0x03, 0xb4, 0xa6, 0x82, 0xc8, 0x6a, 0xd9, 0x06,
0x38, 0x8f, 0x99, 0x52, 0x76, 0xf0, 0x84, 0x92, 0x72, 0x3a, 0x8c, 0x5f,
0x32, 0x3c, 0x6a, 0xf6, 0x92, 0x97, 0x17, 0x40, 0x5d, 0x2e, 0x1b, 0x2f,
0x70, 0x52, 0xae, 0xfd, 0xff, 0xff, 0xff, 0x02, 0xa7, 0x32, 0x75, 0x01,
0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xfb, 0xf7, 0x76, 0xff,
0xeb, 0x3b, 0xb8, 0x89, 0xb2, 0x01, 0xa5, 0x3f, 0x5f, 0xb0, 0x55, 0x4f,
0x6e, 0x6f, 0xa2, 0x56, 0x88, 0xac, 0x19, 0x88, 0x56, 0x01, 0x00, 0x00,
0x00, 0x00, 0x17, 0xa9, 0x14, 0xd3, 0xb6, 0x1d, 0x34, 0xf6, 0x33, 0x7c,
0xd7, 0xc0, 0x28, 0xb7, 0x90, 0xb0, 0xcf, 0x43, 0xe0, 0x27, 0xd9, 0x1d,
0xe7, 0x87, 0x09, 0x5d, 0x07, 0x00,
];
let transaction =
bitcoin::Transaction::consensus_decode(&mut &tx_bytes[..]).expect("decode transaction");
let spk_input_1 = bitcoin::Script::from(vec![
0xa9, 0x14, 0x92, 0x09, 0xa8, 0xf9, 0x0c, 0x58, 0x4b, 0xb5, 0x97, 0x4d, 0x58, 0x68, 0x72,
0x49, 0xe5, 0x32, 0xde, 0x59, 0xf4, 0xbc, 0x87,
]);
let interpreter = miniscript::Interpreter::from_txdata(
&spk_input_1,
&transaction.input[0].script_sig,
&transaction.input[0].witness,
0,
0,
// TODO: Replace with actual hash
bitcoin::hashes::sha256::Hash::from_inner([0u8; 32]),
)
.unwrap();
let desc_string = interpreter.inferred_descriptor_string();
println!("Descriptor: {}", desc_string);
miniscript::Descriptor::<bitcoin::PublicKey>::from_str(&desc_string)
.expect("this descriptor can be reparsed with sanity checks passing");
interpreter
.inferred_descriptor()
.expect("we can use this method to do the above from_str for us");
// 1. Example one: learn which keys were used, not bothering
// to verify the signatures (trusting that if they're on
// the blockchain, standardness would've required they be
// either valid or 0-length.
println!("\nExample one");
for elem in interpreter.iter_assume_sigs() {
// Don't bother checking signatures
match elem.expect("no evaluation error") {
miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } => {
// Check that the signature is ecdsa sig
let (key, sig) = key_sig
.as_ecdsa()
.expect("Expected Ecdsa sig, found schnorr sig");
println!("Signed with {}: {}", key, sig);
}
_ => {}
}
}
// 2. Example two: verify the signatures to ensure that invalid
// signatures are not treated as having participated in the script
let secp = secp256k1::Secp256k1::new();
// Sometimes it is necessary to have additional information to get the bitcoin::PublicKey
// from the MiniscriptKey which can supplied by `to_pk_ctx` parameter. For example,
// when calculating the script pubkey of a descriptor with xpubs, the secp context and
// child information maybe required.
let interpreter = miniscript::Interpreter::from_txdata(
&spk_input_1,
&transaction.input[0].script_sig,
&transaction.input[0].witness,
0,
0,
bitcoin::hashes::sha256::Hash::from_inner([0u8; 32]),
)
.unwrap();
// We can set prevouts to be empty list because this is a legacy transaction
// and this information is not required for sighash computation.
let prevouts = sighash::Prevouts::All::<TxOut>(&[]);
println!("\nExample two");
for elem in interpreter.iter(&secp, &transaction, 0, &prevouts) {
match elem.expect("no evaluation error") {
miniscript::interpreter::SatisfiedConstraint::PublicKey { key_sig } => {
let (key, sig) = key_sig.as_ecdsa().unwrap();
println!("Signed with {}: {}", key, sig);
}
_ => {}
}
}
// 3. Example three: same, but with the wrong signature hash, to demonstrate
// what happens given an apparently invalid script
let secp = secp256k1::Secp256k1::new();
let message = secp256k1::Message::from_slice(&[0x01; 32][..]).expect("32-byte hash");
let interpreter = miniscript::Interpreter::from_txdata(
&spk_input_1,
&transaction.input[0].script_sig,
&transaction.input[0].witness,
0,
0,
bitcoin::hashes::sha256::Hash::from_inner([0u8; 32]),
)
.unwrap();
let iter = interpreter.iter_custom(Box::new(|key_sig: &KeySigPair| {
let (pk, ecdsa_sig) = key_sig.as_ecdsa().expect("Ecdsa Sig");
ecdsa_sig.hash_ty == bitcoin::EcdsaSighashType::All
&& secp
.verify_ecdsa(&message, &ecdsa_sig.sig, &pk.inner)
.is_ok()
}));
println!("\nExample three");
for elem in iter {
let error = elem.expect_err("evaluation error");
println!("Evaluation error: {}", error);
}
}
sourcepub fn as_schnorr(&self) -> Option<(XOnlyPublicKey, SchnorrSig)>
pub fn as_schnorr(&self) -> Option<(XOnlyPublicKey, SchnorrSig)>
Obtain a pair of ([bitcoin::XOnlyPublicKey
], bitcoin::SchnorrSig
) from KeySigPair
Trait Implementations§
source§impl Clone for KeySigPair
impl Clone for KeySigPair
source§fn clone(&self) -> KeySigPair
fn clone(&self) -> KeySigPair
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moresource§impl Debug for KeySigPair
impl Debug for KeySigPair
source§impl PartialEq for KeySigPair
impl PartialEq for KeySigPair
source§fn eq(&self, other: &KeySigPair) -> bool
fn eq(&self, other: &KeySigPair) -> bool
This method tests for
self
and other
values to be equal, and is used
by ==
.impl Copy for KeySigPair
impl Eq for KeySigPair
impl StructuralEq for KeySigPair
impl StructuralPartialEq for KeySigPair
Auto Trait Implementations§
impl RefUnwindSafe for KeySigPair
impl Send for KeySigPair
impl Sync for KeySigPair
impl Unpin for KeySigPair
impl UnwindSafe for KeySigPair
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more