Skip to content

Commit

Permalink
Merge rust-bitcoin#730: Allow infallible construction of Signature
Browse files Browse the repository at this point in the history
23b87a6 Allow infallible construction of `Signature` (Yuki Kishimoto)

Pull request description:

  Hi! This PR add 1 constructor and 2 methods to `Signature` struct:

  * Add `Signature::from_byte_array` constructor
  * Add `Signature::to_byte_array` and `Signature::as_byte_array` methods
  * Deprecate `Signature::serialize` method

ACKs for top commit:
  Kixunil:
    ACK 23b87a6
  apoelstra:
    ACK 23b87a6 successfully ran local tests

Tree-SHA512: 5500e7a29eddc08b692eb564de5b126ca54bf16b00d12a803b36ed35da925d39d2756c923f6e7dfad58de5b0de4f0558f2b43f0cc067f0c303a8feff16c49b3e
  • Loading branch information
apoelstra committed Sep 2, 2024
2 parents 41a6d43 + 23b87a6 commit e9c959d
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/schnorr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,17 @@ impl str::FromStr for Signature {
fn from_str(s: &str) -> Result<Signature, Error> {
let mut res = [0u8; constants::SCHNORR_SIGNATURE_SIZE];
match from_hex(s, &mut res) {
Ok(constants::SCHNORR_SIGNATURE_SIZE) =>
Signature::from_slice(&res[0..constants::SCHNORR_SIGNATURE_SIZE]),
Ok(constants::SCHNORR_SIGNATURE_SIZE) => Ok(Signature::from_byte_array(res)),
_ => Err(Error::InvalidSignature),
}
}
}

impl Signature {
/// Construct a `Signature` from a 64 bytes array.
#[inline]
pub fn from_byte_array(sig: [u8; constants::SCHNORR_SIGNATURE_SIZE]) -> Self { Self(sig) }

/// Creates a `Signature` directly from a slice.
#[inline]
pub fn from_slice(data: &[u8]) -> Result<Signature, Error> {
Expand All @@ -88,9 +91,17 @@ impl Signature {
}

/// Returns a signature as a byte array.
#[inline]
#[deprecated(since = "0.30.0", note = "Use `to_byte_array` instead.")]
pub fn serialize(&self) -> [u8; constants::SCHNORR_SIGNATURE_SIZE] { self.0 }

/// Returns a signature as a byte array.
#[inline]
pub fn to_byte_array(self) -> [u8; constants::SCHNORR_SIGNATURE_SIZE] { self.0 }

/// Returns a signature as a byte array.
#[inline]
pub fn as_byte_array(&self) -> &[u8; constants::SCHNORR_SIGNATURE_SIZE] { &self.0 }

/// Verifies a schnorr signature for `msg` using `pk` and the global [`SECP256K1`] context.
#[inline]
#[cfg(feature = "global-context")]
Expand Down Expand Up @@ -294,7 +305,7 @@ mod tests {
#[test]
fn test_serialize() {
let sig = Signature::from_str("6470FD1303DDA4FDA717B9837153C24A6EAB377183FC438F939E0ED2B620E9EE5077C4A8B8DCA28963D772A94F5F0DDF598E1C47C137F91933274C7C3EDADCE8").unwrap();
let sig_bytes = sig.serialize();
let sig_bytes = sig.to_byte_array();
let bytes = [
100, 112, 253, 19, 3, 221, 164, 253, 167, 23, 185, 131, 113, 83, 194, 74, 110, 171, 55,
113, 131, 252, 67, 143, 147, 158, 14, 210, 182, 32, 233, 238, 80, 119, 196, 168, 184,
Expand Down Expand Up @@ -697,9 +708,9 @@ mod tests {
let keypair = Keypair::from_seckey_slice(&secp, &secret_key).unwrap();
assert_eq!(keypair.x_only_public_key().0.serialize(), public_key);
let sig = secp.sign_schnorr_with_aux_rand(&message, &keypair, &aux_rand);
assert_eq!(sig.serialize(), signature);
assert_eq!(sig.to_byte_array(), signature);
}
let sig = Signature::from_slice(&signature).unwrap();
let sig = Signature::from_byte_array(signature);
let is_verified = if let Ok(pubkey) = XOnlyPublicKey::from_slice(&public_key) {
secp.verify_schnorr(&sig, &message, &pubkey).is_ok()
} else {
Expand Down

0 comments on commit e9c959d

Please sign in to comment.