2022-06-29 04:05:31 +00:00
|
|
|
// SPDX-License-Identifier: CC0-1.0
|
2021-04-12 11:24:25 +00:00
|
|
|
|
2023-02-07 03:35:03 +00:00
|
|
|
//! Bitcoin taproot keys.
|
2021-04-12 11:24:25 +00:00
|
|
|
//!
|
2023-02-07 03:35:03 +00:00
|
|
|
//! This module provides taproot keys used in Bitcoin (including reexporting secp256k1 keys).
|
2021-04-12 11:24:25 +00:00
|
|
|
//!
|
|
|
|
|
2021-11-16 00:00:12 +00:00
|
|
|
use core::fmt;
|
2022-06-24 02:01:53 +00:00
|
|
|
|
2023-03-28 01:16:47 +00:00
|
|
|
use internals::write_err;
|
2024-01-23 08:10:58 +00:00
|
|
|
use io::Write;
|
2022-09-15 02:14:52 +00:00
|
|
|
|
2024-03-31 01:03:18 +00:00
|
|
|
use crate::prelude::*;
|
2023-05-18 05:45:50 +00:00
|
|
|
use crate::sighash::{InvalidSighashTypeError, TapSighashType};
|
2023-10-31 12:41:07 +00:00
|
|
|
use crate::taproot::serialized_signature::{self, SerializedSignature};
|
|
|
|
|
2023-02-07 03:35:03 +00:00
|
|
|
/// A BIP340-341 serialized taproot signature with the corresponding hash type.
|
2022-05-06 03:37:24 +00:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
2021-10-28 07:43:02 +00:00
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
2022-05-25 06:41:59 +00:00
|
|
|
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
|
2022-11-08 00:36:52 +00:00
|
|
|
pub struct Signature {
|
2024-01-14 22:47:35 +00:00
|
|
|
/// The underlying schnorr signature.
|
|
|
|
pub signature: secp256k1::schnorr::Signature,
|
|
|
|
/// The corresponding hash type.
|
|
|
|
pub sighash_type: TapSighashType,
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|
|
|
|
|
2022-11-08 00:36:52 +00:00
|
|
|
impl Signature {
|
2021-11-16 00:00:12 +00:00
|
|
|
/// Deserialize from slice
|
2023-06-02 05:01:10 +00:00
|
|
|
pub fn from_slice(sl: &[u8]) -> Result<Self, SigFromSliceError> {
|
2021-11-16 00:00:12 +00:00
|
|
|
match sl.len() {
|
|
|
|
64 => {
|
|
|
|
// default type
|
2024-01-14 22:47:35 +00:00
|
|
|
let signature = secp256k1::schnorr::Signature::from_slice(sl)?;
|
|
|
|
Ok(Signature { signature, sighash_type: TapSighashType::Default })
|
2022-12-05 23:39:56 +00:00
|
|
|
}
|
2021-11-16 00:00:12 +00:00
|
|
|
65 => {
|
2024-01-14 22:47:35 +00:00
|
|
|
let (sighash_type, signature) = sl.split_last().expect("Slice len checked == 65");
|
|
|
|
let sighash_type = TapSighashType::from_consensus_u8(*sighash_type)?;
|
|
|
|
let signature = secp256k1::schnorr::Signature::from_slice(signature)?;
|
|
|
|
Ok(Signature { signature, sighash_type })
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|
2023-06-02 05:01:10 +00:00
|
|
|
len => Err(SigFromSliceError::InvalidSignatureSize(len)),
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-08 00:36:52 +00:00
|
|
|
/// Serialize Signature
|
2023-10-31 12:41:07 +00:00
|
|
|
///
|
|
|
|
/// Note: this allocates on the heap, prefer [`serialize`](Self::serialize) if vec is not needed.
|
2022-08-01 22:33:22 +00:00
|
|
|
pub fn to_vec(self) -> Vec<u8> {
|
2024-01-14 22:47:35 +00:00
|
|
|
let mut ser_sig = self.signature.as_ref().to_vec();
|
|
|
|
if self.sighash_type == TapSighashType::Default {
|
2021-11-16 00:00:12 +00:00
|
|
|
// default sighash type, don't add extra sighash byte
|
|
|
|
} else {
|
2024-01-14 22:47:35 +00:00
|
|
|
ser_sig.push(self.sighash_type as u8);
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|
|
|
|
ser_sig
|
|
|
|
}
|
2023-10-31 12:41:07 +00:00
|
|
|
|
2024-01-23 08:10:58 +00:00
|
|
|
/// Serializes the signature to `writer`.
|
|
|
|
#[inline]
|
|
|
|
pub fn serialize_to_writer<W: Write + ?Sized>(&self, writer: &mut W) -> Result<(), io::Error> {
|
|
|
|
let sig = self.serialize();
|
|
|
|
sig.write_to(writer)
|
|
|
|
}
|
|
|
|
|
2023-10-31 12:41:07 +00:00
|
|
|
/// Serializes the signature (without heap allocation)
|
|
|
|
///
|
|
|
|
/// This returns a type with an API very similar to that of `Box<[u8]>`.
|
|
|
|
/// You can get a slice from it using deref coercions or turn it into an iterator.
|
|
|
|
pub fn serialize(self) -> SerializedSignature {
|
|
|
|
let mut buf = [0; serialized_signature::MAX_LEN];
|
2024-01-14 22:47:35 +00:00
|
|
|
let ser_sig = self.signature.serialize();
|
2023-10-31 12:41:07 +00:00
|
|
|
buf[..64].copy_from_slice(&ser_sig);
|
2024-01-14 22:47:35 +00:00
|
|
|
let len = if self.sighash_type == TapSighashType::Default {
|
2023-10-31 12:41:07 +00:00
|
|
|
// default sighash type, don't add extra sighash byte
|
|
|
|
64
|
|
|
|
} else {
|
2024-01-14 22:47:35 +00:00
|
|
|
buf[64] = self.sighash_type as u8;
|
2023-10-31 12:41:07 +00:00
|
|
|
65
|
|
|
|
};
|
|
|
|
SerializedSignature::from_raw_parts(buf, len)
|
|
|
|
}
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|
|
|
|
|
2023-06-02 05:01:10 +00:00
|
|
|
/// An error constructing a [`taproot::Signature`] from a byte slice.
|
|
|
|
///
|
|
|
|
/// [`taproot::Signature`]: crate::crypto::taproot::Signature
|
2023-07-27 01:10:22 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
2022-05-31 04:29:50 +00:00
|
|
|
#[non_exhaustive]
|
2023-06-02 05:01:10 +00:00
|
|
|
pub enum SigFromSliceError {
|
2023-06-02 04:23:37 +00:00
|
|
|
/// Invalid signature hash type.
|
2023-05-18 05:45:50 +00:00
|
|
|
SighashType(InvalidSighashTypeError),
|
2023-05-18 06:19:37 +00:00
|
|
|
/// A secp256k1 error.
|
2021-11-16 00:00:12 +00:00
|
|
|
Secp256k1(secp256k1::Error),
|
2023-02-07 03:35:03 +00:00
|
|
|
/// Invalid taproot signature size
|
2022-11-08 00:36:52 +00:00
|
|
|
InvalidSignatureSize(usize),
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|
|
|
|
|
2024-02-28 23:21:50 +00:00
|
|
|
internals::impl_from_infallible!(SigFromSliceError);
|
|
|
|
|
2023-06-02 05:01:10 +00:00
|
|
|
impl fmt::Display for SigFromSliceError {
|
2021-11-16 00:00:12 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2023-06-02 05:01:10 +00:00
|
|
|
use SigFromSliceError::*;
|
2023-06-02 04:48:22 +00:00
|
|
|
|
2021-11-16 00:00:12 +00:00
|
|
|
match *self {
|
2023-05-18 06:19:37 +00:00
|
|
|
SighashType(ref e) => write_err!(f, "sighash"; e),
|
|
|
|
Secp256k1(ref e) => write_err!(f, "secp256k1"; e),
|
2023-06-02 04:48:22 +00:00
|
|
|
InvalidSignatureSize(sz) => write!(f, "invalid taproot signature size: {}", sz),
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "std")]
|
2023-06-02 05:01:10 +00:00
|
|
|
impl std::error::Error for SigFromSliceError {
|
2022-05-04 05:56:24 +00:00
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
2023-06-02 05:01:10 +00:00
|
|
|
use SigFromSliceError::*;
|
2022-05-04 05:56:24 +00:00
|
|
|
|
Make error types uniform
On our way to v1.0.0 we are defining a standard for our error types,
this includes:
- Uses the following derives (unless not possible, usually because of `io::Error`)
`#[derive(Debug, Clone, PartialEq, Eq)]`
- Has `non_exhaustive` unless we really know we can commit to not adding
anything.
Furthermore, we are trying to make the codebase easy to read. Error code
is write-once-read-many (well it should be) so if we make all the error
code super uniform the users can flick to an error and quickly see what
it includes. In an effort to achieve this I have made up a style and
over recent times have change much of the error code to that new style,
this PR audits _all_ error types in the code base and enforces the
style, specifically:
- Is layed out: definition, [impl block], Display impl, error::Error impl, From impls
- `error::Error` impl matches on enum even if it returns `None` for all variants
- Display/Error impls import enum variants locally
- match uses *self and `ref e`
- error::Error variants that return `Some` come first, `None` after
Re: non_exhaustive
To make dev and review easier I have added `non_exhaustive` to _every_
error type. We can then remove it error by error as we see fit. This is
because it takes a bit of thinking to do and review where as this patch
should not take much brain power to review.
2023-10-04 02:55:45 +00:00
|
|
|
match *self {
|
|
|
|
Secp256k1(ref e) => Some(e),
|
|
|
|
SighashType(ref e) => Some(e),
|
2023-05-18 05:45:50 +00:00
|
|
|
InvalidSignatureSize(_) => None,
|
2022-05-04 05:56:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-16 00:00:12 +00:00
|
|
|
|
2023-06-02 05:01:10 +00:00
|
|
|
impl From<secp256k1::Error> for SigFromSliceError {
|
2023-05-18 05:45:50 +00:00
|
|
|
fn from(e: secp256k1::Error) -> Self { Self::Secp256k1(e) }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<InvalidSighashTypeError> for SigFromSliceError {
|
|
|
|
fn from(err: InvalidSighashTypeError) -> Self { Self::SighashType(err) }
|
2021-11-16 00:00:12 +00:00
|
|
|
}
|