From 7e2f7fef72f90a439e52f1911f22911f609e2301 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 19 Jun 2021 11:06:27 +0200 Subject: [PATCH 1/2] Adding KeyPair::serialize_sec. Closes #298 --- Cargo.toml | 2 +- src/schnorrsig.rs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e545b2e..6f9920f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ license = "CC0-1.0" homepage = "https://github.com/rust-bitcoin/rust-secp256k1/" repository = "https://github.com/rust-bitcoin/rust-secp256k1/" documentation = "https://docs.rs/secp256k1/" -description = "Rust bindings for Pieter Wuille's `libsecp256k1` library. Implements ECDSA for the SECG elliptic curve group secp256k1 and related utilities." +description = "Rust wrapper library for Pieter Wuille's `libsecp256k1`. Implements ECDSA and BIP 340 signatures for the SECG elliptic curve group secp256k1 and related utilities." keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ] readme = "README.md" autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330 diff --git a/src/schnorrsig.rs b/src/schnorrsig.rs index d8c48a0..88a3276 100644 --- a/src/schnorrsig.rs +++ b/src/schnorrsig.rs @@ -211,6 +211,12 @@ impl KeyPair { } } + /// Serialize the key pair as a secret key byte value + #[inline] + pub fn serialize_sec(&self, secp: &Secp256k1) -> [u8; constants::SECRET_KEY_SIZE] { + *SecretKey::from_keypair(secp, self).as_ref() + } + /// Tweak a keypair by adding the given tweak to the secret key and updating the /// public key accordingly. /// Will return an error if the resulting key would be invalid or if From 8ee4e05e630bec8017f71669edd9e5cdc9d09cf1 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sun, 20 Jun 2021 17:07:44 +0200 Subject: [PATCH 2/2] Removing uneeded Secp context arguments --- src/key.rs | 34 ++++++++++++++++++++++++++-- src/schnorrsig.rs | 56 ++++++++++++++++++++++------------------------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/src/key.rs b/src/key.rs index 834137c..f3dd061 100644 --- a/src/key.rs +++ b/src/key.rs @@ -27,7 +27,7 @@ use constants; use ffi::{self, CPtr}; /// Secret 256-bit key used as `x` in an ECDSA signature -pub struct SecretKey(pub(crate) [u8; constants::SECRET_KEY_SIZE]); +pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]); impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE); impl_pretty_debug!(SecretKey); @@ -66,7 +66,7 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0, /// A Secp256k1 public key, used for verification of signatures #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] #[repr(transparent)] -pub struct PublicKey(pub(crate) ffi::PublicKey); +pub struct PublicKey(ffi::PublicKey); impl fmt::LowerHex for PublicKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -149,6 +149,21 @@ impl SecretKey { } } + /// Creates a new secret key using data from BIP-340 [`::schnorrsig::KeyPair`] + #[inline] + pub fn from_keypair(keypair: &::schnorrsig::KeyPair) -> Self { + let mut sk = [0; constants::SECRET_KEY_SIZE]; + unsafe { + let ret = ffi::secp256k1_keypair_sec( + ffi::secp256k1_context_no_precomp, + sk.as_mut_c_ptr(), + keypair.as_ptr() + ); + debug_assert_eq!(ret, 1); + } + SecretKey(sk) + } + #[inline] /// Negates one secret key. pub fn negate_assign( @@ -290,6 +305,21 @@ impl PublicKey { } } + /// Creates a new compressed public key key using data from BIP-340 [`::schnorrsig::KeyPair`] + #[inline] + pub fn from_keypair(keypair: &::schnorrsig::KeyPair) -> Self { + unsafe { + let mut pk = ffi::PublicKey::new(); + let ret = ffi::secp256k1_keypair_pub( + ffi::secp256k1_context_no_precomp, + &mut pk, + keypair.as_ptr() + ); + debug_assert_eq!(ret, 1); + PublicKey(pk) + } + } + #[inline] /// Serialize the key as a byte-encoded pair of values. In compressed form /// the y-coordinate is represented by only a single bit, as x determines diff --git a/src/schnorrsig.rs b/src/schnorrsig.rs index 88a3276..a1548b0 100644 --- a/src/schnorrsig.rs +++ b/src/schnorrsig.rs @@ -213,8 +213,8 @@ impl KeyPair { /// Serialize the key pair as a secret key byte value #[inline] - pub fn serialize_sec(&self, secp: &Secp256k1) -> [u8; constants::SECRET_KEY_SIZE] { - *SecretKey::from_keypair(secp, self).as_ref() + pub fn serialize_secret(&self) -> [u8; constants::SECRET_KEY_SIZE] { + *SecretKey::from_keypair(self).as_ref() } /// Tweak a keypair by adding the given tweak to the secret key and updating the @@ -456,35 +456,31 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey { } } -impl SecretKey { - /// Creates a new secret key using data from BIP-340 [`KeyPair`] - pub fn from_keypair(secp: &Secp256k1, keypair: &KeyPair) -> Self { - let mut sk = [0; constants::SECRET_KEY_SIZE]; - unsafe { - let ret = ffi::secp256k1_keypair_sec( - secp.ctx, - sk.as_mut_c_ptr(), - keypair.as_ptr() - ); - debug_assert_eq!(ret, 1); - } - SecretKey(sk) +impl From for SecretKey { + #[inline] + fn from(pair: KeyPair) -> Self { + SecretKey::from_keypair(&pair) } } -impl ::key::PublicKey { - /// Creates a new compressed public key key using data from BIP-340 [`KeyPair`] - pub fn from_keypair(secp: &Secp256k1, keypair: &KeyPair) -> Self { - unsafe { - let mut pk = ffi::PublicKey::new(); - let ret = ffi::secp256k1_keypair_pub( - secp.ctx, - &mut pk, - keypair.as_ptr() - ); - debug_assert_eq!(ret, 1); - ::key::PublicKey(pk) - } +impl<'a> From<&'a KeyPair> for SecretKey { + #[inline] + fn from(pair: &'a KeyPair) -> Self { + SecretKey::from_keypair(pair) + } +} + +impl From for ::key::PublicKey { + #[inline] + fn from(pair: KeyPair) -> Self { + ::key::PublicKey::from_keypair(&pair) + } +} + +impl<'a> From<&'a KeyPair> for ::key::PublicKey { + #[inline] + fn from(pair: &'a KeyPair) -> Self { + ::key::PublicKey::from_keypair(pair) } } @@ -734,9 +730,9 @@ mod tests { let secp = Secp256k1::new(); let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF"; let keypair = KeyPair::from_seckey_str(&secp, sk_str).unwrap(); - let sk = SecretKey::from_keypair(&secp, &keypair); + let sk = SecretKey::from_keypair(&keypair); assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk); - let pk = ::key::PublicKey::from_keypair(&secp, &keypair); + let pk = ::key::PublicKey::from_keypair(&keypair); assert_eq!(::key::PublicKey::from_secret_key(&secp, &sk), pk); let xpk = PublicKey::from_keypair(&secp, &keypair); assert_eq!(PublicKey::from(pk), xpk);