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