Enum 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

Source

pub fn as_ecdsa(&self) -> Option<(PublicKey, EcdsaSig)>

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}
Source

pub fn as_schnorr(&self) -> Option<(XOnlyPublicKey, SchnorrSig)>

Trait Implementations§

Source§

impl Clone for KeySigPair

Source§

fn clone(&self) -> KeySigPair

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for KeySigPair

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for KeySigPair

Source§

fn eq(&self, other: &KeySigPair) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for KeySigPair

Source§

impl Eq for KeySigPair

Source§

impl StructuralPartialEq for KeySigPair

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.