Skip to content

Commit c72e7cc

Browse files
authored
Merge pull request #308 from LNP-BP/extrakeys/keypair-ser
Adding KeyPair::serialize_sec. Closes #298
2 parents acba77c + 8ee4e05 commit c72e7cc

File tree

3 files changed

+63
-31
lines changed

3 files changed

+63
-31
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ license = "CC0-1.0"
77
homepage = "https://github.com/rust-bitcoin/rust-secp256k1/"
88
repository = "https://github.com/rust-bitcoin/rust-secp256k1/"
99
documentation = "https://docs.rs/secp256k1/"
10-
description = "Rust bindings for Pieter Wuille's `libsecp256k1` library. Implements ECDSA for the SECG elliptic curve group secp256k1 and related utilities."
10+
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."
1111
keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ]
1212
readme = "README.md"
1313
autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330

src/key.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use constants;
2727
use ffi::{self, CPtr};
2828

2929
/// Secret 256-bit key used as `x` in an ECDSA signature
30-
pub struct SecretKey(pub(crate) [u8; constants::SECRET_KEY_SIZE]);
30+
pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]);
3131
impl_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE);
3232
impl_pretty_debug!(SecretKey);
3333

@@ -66,7 +66,7 @@ pub const ONE_KEY: SecretKey = SecretKey([0, 0, 0, 0, 0, 0, 0, 0,
6666
/// A Secp256k1 public key, used for verification of signatures
6767
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
6868
#[repr(transparent)]
69-
pub struct PublicKey(pub(crate) ffi::PublicKey);
69+
pub struct PublicKey(ffi::PublicKey);
7070

7171
impl fmt::LowerHex for PublicKey {
7272
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -149,6 +149,21 @@ impl SecretKey {
149149
}
150150
}
151151

152+
/// Creates a new secret key using data from BIP-340 [`::schnorrsig::KeyPair`]
153+
#[inline]
154+
pub fn from_keypair(keypair: &::schnorrsig::KeyPair) -> Self {
155+
let mut sk = [0; constants::SECRET_KEY_SIZE];
156+
unsafe {
157+
let ret = ffi::secp256k1_keypair_sec(
158+
ffi::secp256k1_context_no_precomp,
159+
sk.as_mut_c_ptr(),
160+
keypair.as_ptr()
161+
);
162+
debug_assert_eq!(ret, 1);
163+
}
164+
SecretKey(sk)
165+
}
166+
152167
#[inline]
153168
/// Negates one secret key.
154169
pub fn negate_assign(
@@ -290,6 +305,21 @@ impl PublicKey {
290305
}
291306
}
292307

308+
/// Creates a new compressed public key key using data from BIP-340 [`::schnorrsig::KeyPair`]
309+
#[inline]
310+
pub fn from_keypair(keypair: &::schnorrsig::KeyPair) -> Self {
311+
unsafe {
312+
let mut pk = ffi::PublicKey::new();
313+
let ret = ffi::secp256k1_keypair_pub(
314+
ffi::secp256k1_context_no_precomp,
315+
&mut pk,
316+
keypair.as_ptr()
317+
);
318+
debug_assert_eq!(ret, 1);
319+
PublicKey(pk)
320+
}
321+
}
322+
293323
#[inline]
294324
/// Serialize the key as a byte-encoded pair of values. In compressed form
295325
/// the y-coordinate is represented by only a single bit, as x determines

src/schnorrsig.rs

+30-28
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ impl KeyPair {
211211
}
212212
}
213213

214+
/// Serialize the key pair as a secret key byte value
215+
#[inline]
216+
pub fn serialize_secret(&self) -> [u8; constants::SECRET_KEY_SIZE] {
217+
*SecretKey::from_keypair(self).as_ref()
218+
}
219+
214220
/// Tweak a keypair by adding the given tweak to the secret key and updating the
215221
/// public key accordingly.
216222
/// Will return an error if the resulting key would be invalid or if
@@ -450,35 +456,31 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey {
450456
}
451457
}
452458

453-
impl SecretKey {
454-
/// Creates a new secret key using data from BIP-340 [`KeyPair`]
455-
pub fn from_keypair<V: Verification>(secp: &Secp256k1<V>, keypair: &KeyPair) -> Self {
456-
let mut sk = [0; constants::SECRET_KEY_SIZE];
457-
unsafe {
458-
let ret = ffi::secp256k1_keypair_sec(
459-
secp.ctx,
460-
sk.as_mut_c_ptr(),
461-
keypair.as_ptr()
462-
);
463-
debug_assert_eq!(ret, 1);
464-
}
465-
SecretKey(sk)
459+
impl From<KeyPair> for SecretKey {
460+
#[inline]
461+
fn from(pair: KeyPair) -> Self {
462+
SecretKey::from_keypair(&pair)
466463
}
467464
}
468465

469-
impl ::key::PublicKey {
470-
/// Creates a new compressed public key key using data from BIP-340 [`KeyPair`]
471-
pub fn from_keypair<C: Signing>(secp: &Secp256k1<C>, keypair: &KeyPair) -> Self {
472-
unsafe {
473-
let mut pk = ffi::PublicKey::new();
474-
let ret = ffi::secp256k1_keypair_pub(
475-
secp.ctx,
476-
&mut pk,
477-
keypair.as_ptr()
478-
);
479-
debug_assert_eq!(ret, 1);
480-
::key::PublicKey(pk)
481-
}
466+
impl<'a> From<&'a KeyPair> for SecretKey {
467+
#[inline]
468+
fn from(pair: &'a KeyPair) -> Self {
469+
SecretKey::from_keypair(pair)
470+
}
471+
}
472+
473+
impl From<KeyPair> for ::key::PublicKey {
474+
#[inline]
475+
fn from(pair: KeyPair) -> Self {
476+
::key::PublicKey::from_keypair(&pair)
477+
}
478+
}
479+
480+
impl<'a> From<&'a KeyPair> for ::key::PublicKey {
481+
#[inline]
482+
fn from(pair: &'a KeyPair) -> Self {
483+
::key::PublicKey::from_keypair(pair)
482484
}
483485
}
484486

@@ -728,9 +730,9 @@ mod tests {
728730
let secp = Secp256k1::new();
729731
let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF";
730732
let keypair = KeyPair::from_seckey_str(&secp, sk_str).unwrap();
731-
let sk = SecretKey::from_keypair(&secp, &keypair);
733+
let sk = SecretKey::from_keypair(&keypair);
732734
assert_eq!(SecretKey::from_str(sk_str).unwrap(), sk);
733-
let pk = ::key::PublicKey::from_keypair(&secp, &keypair);
735+
let pk = ::key::PublicKey::from_keypair(&keypair);
734736
assert_eq!(::key::PublicKey::from_secret_key(&secp, &sk), pk);
735737
let xpk = PublicKey::from_keypair(&secp, &keypair);
736738
assert_eq!(PublicKey::from(pk), xpk);

0 commit comments

Comments
 (0)