Merge pull request #308 from LNP-BP/extrakeys/keypair-ser
Adding KeyPair::serialize_sec. Closes #298
This commit is contained in:
commit
c72e7cc743
|
@ -7,7 +7,7 @@ license = "CC0-1.0"
|
||||||
homepage = "https://github.com/rust-bitcoin/rust-secp256k1/"
|
homepage = "https://github.com/rust-bitcoin/rust-secp256k1/"
|
||||||
repository = "https://github.com/rust-bitcoin/rust-secp256k1/"
|
repository = "https://github.com/rust-bitcoin/rust-secp256k1/"
|
||||||
documentation = "https://docs.rs/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" ]
|
keywords = [ "crypto", "ECDSA", "secp256k1", "libsecp256k1", "bitcoin" ]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330
|
autoexamples = false # Remove when edition 2018 https://github.com/rust-lang/cargo/issues/5330
|
||||||
|
|
34
src/key.rs
34
src/key.rs
|
@ -27,7 +27,7 @@ use constants;
|
||||||
use ffi::{self, CPtr};
|
use ffi::{self, CPtr};
|
||||||
|
|
||||||
/// Secret 256-bit key used as `x` in an ECDSA signature
|
/// 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_array_newtype!(SecretKey, u8, constants::SECRET_KEY_SIZE);
|
||||||
impl_pretty_debug!(SecretKey);
|
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
|
/// A Secp256k1 public key, used for verification of signatures
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PublicKey(pub(crate) ffi::PublicKey);
|
pub struct PublicKey(ffi::PublicKey);
|
||||||
|
|
||||||
impl fmt::LowerHex for PublicKey {
|
impl fmt::LowerHex for PublicKey {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
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]
|
#[inline]
|
||||||
/// Negates one secret key.
|
/// Negates one secret key.
|
||||||
pub fn negate_assign(
|
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]
|
#[inline]
|
||||||
/// Serialize the key as a byte-encoded pair of values. In compressed form
|
/// 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
|
/// the y-coordinate is represented by only a single bit, as x determines
|
||||||
|
|
|
@ -211,6 +211,12 @@ impl KeyPair {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serialize the key pair as a secret key byte value
|
||||||
|
#[inline]
|
||||||
|
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
|
/// Tweak a keypair by adding the given tweak to the secret key and updating the
|
||||||
/// public key accordingly.
|
/// public key accordingly.
|
||||||
/// Will return an error if the resulting key would be invalid or if
|
/// Will return an error if the resulting key would be invalid or if
|
||||||
|
@ -450,35 +456,31 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SecretKey {
|
impl From<KeyPair> for SecretKey {
|
||||||
/// Creates a new secret key using data from BIP-340 [`KeyPair`]
|
#[inline]
|
||||||
pub fn from_keypair<V: Verification>(secp: &Secp256k1<V>, keypair: &KeyPair) -> Self {
|
fn from(pair: KeyPair) -> Self {
|
||||||
let mut sk = [0; constants::SECRET_KEY_SIZE];
|
SecretKey::from_keypair(&pair)
|
||||||
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 ::key::PublicKey {
|
impl<'a> From<&'a KeyPair> for SecretKey {
|
||||||
/// Creates a new compressed public key key using data from BIP-340 [`KeyPair`]
|
#[inline]
|
||||||
pub fn from_keypair<C: Signing>(secp: &Secp256k1<C>, keypair: &KeyPair) -> Self {
|
fn from(pair: &'a KeyPair) -> Self {
|
||||||
unsafe {
|
SecretKey::from_keypair(pair)
|
||||||
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 From<KeyPair> 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,9 +730,9 @@ mod tests {
|
||||||
let secp = Secp256k1::new();
|
let secp = Secp256k1::new();
|
||||||
let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF";
|
let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF";
|
||||||
let keypair = KeyPair::from_seckey_str(&secp, sk_str).unwrap();
|
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);
|
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);
|
assert_eq!(::key::PublicKey::from_secret_key(&secp, &sk), pk);
|
||||||
let xpk = PublicKey::from_keypair(&secp, &keypair);
|
let xpk = PublicKey::from_keypair(&secp, &keypair);
|
||||||
assert_eq!(PublicKey::from(pk), xpk);
|
assert_eq!(PublicKey::from(pk), xpk);
|
||||||
|
|
Loading…
Reference in New Issue