bitcoin/crypto/
taproot.rs1use core::fmt;
9
10use internals::write_err;
11use io::Write;
12
13use crate::prelude::*;
14use crate::sighash::{InvalidSighashTypeError, TapSighashType};
15use crate::taproot::serialized_signature::{self, SerializedSignature};
16
17#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
21pub struct Signature {
22 pub signature: secp256k1::schnorr::Signature,
24 pub sighash_type: TapSighashType,
26}
27
28impl Signature {
29 pub fn from_slice(sl: &[u8]) -> Result<Self, SigFromSliceError> {
31 match sl.len() {
32 64 => {
33 let signature = secp256k1::schnorr::Signature::from_slice(sl)?;
35 Ok(Signature { signature, sighash_type: TapSighashType::Default })
36 }
37 65 => {
38 let (sighash_type, signature) = sl.split_last().expect("Slice len checked == 65");
39 let sighash_type = TapSighashType::from_consensus_u8(*sighash_type)?;
40 let signature = secp256k1::schnorr::Signature::from_slice(signature)?;
41 Ok(Signature { signature, sighash_type })
42 }
43 len => Err(SigFromSliceError::InvalidSignatureSize(len)),
44 }
45 }
46
47 pub fn to_vec(self) -> Vec<u8> {
51 let mut ser_sig = self.signature.as_ref().to_vec();
52 if self.sighash_type == TapSighashType::Default {
53 } else {
55 ser_sig.push(self.sighash_type as u8);
56 }
57 ser_sig
58 }
59
60 #[inline]
62 pub fn serialize_to_writer<W: Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
63 let sig = self.serialize();
64 sig.write_to(writer)
65 }
66
67 pub fn serialize(self) -> SerializedSignature {
72 let mut buf = [0; serialized_signature::MAX_LEN];
73 let ser_sig = self.signature.serialize();
74 buf[..64].copy_from_slice(&ser_sig);
75 let len = if self.sighash_type == TapSighashType::Default {
76 64
78 } else {
79 buf[64] = self.sighash_type as u8;
80 65
81 };
82 SerializedSignature::from_raw_parts(buf, len)
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Eq)]
90#[non_exhaustive]
91pub enum SigFromSliceError {
92 SighashType(InvalidSighashTypeError),
94 Secp256k1(secp256k1::Error),
96 InvalidSignatureSize(usize),
98}
99
100internals::impl_from_infallible!(SigFromSliceError);
101
102impl fmt::Display for SigFromSliceError {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 use SigFromSliceError::*;
105
106 match *self {
107 SighashType(ref e) => write_err!(f, "sighash"; e),
108 Secp256k1(ref e) => write_err!(f, "secp256k1"; e),
109 InvalidSignatureSize(sz) => write!(f, "invalid taproot signature size: {}", sz),
110 }
111 }
112}
113
114#[cfg(feature = "std")]
115impl std::error::Error for SigFromSliceError {
116 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
117 use SigFromSliceError::*;
118
119 match *self {
120 Secp256k1(ref e) => Some(e),
121 SighashType(ref e) => Some(e),
122 InvalidSignatureSize(_) => None,
123 }
124 }
125}
126
127impl From<secp256k1::Error> for SigFromSliceError {
128 fn from(e: secp256k1::Error) -> Self { Self::Secp256k1(e) }
129}
130
131impl From<InvalidSighashTypeError> for SigFromSliceError {
132 fn from(err: InvalidSighashTypeError) -> Self { Self::SighashType(err) }
133}