Move `KeyPair` to `key` module
The `KeyPair` type is semantically unrelated to the schnorr signature algorithm.
This commit is contained in:
parent
c47ead9967
commit
2e0e731664
177
src/key.rs
177
src/key.rs
|
@ -134,9 +134,9 @@ impl SecretKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new secret key using data from BIP-340 [`::schnorrsig::KeyPair`]
|
/// Creates a new secret key using data from BIP-340 [`KeyPair`]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_keypair(keypair: &::schnorrsig::KeyPair) -> Self {
|
pub fn from_keypair(keypair: &KeyPair) -> Self {
|
||||||
let mut sk = [0u8; constants::SECRET_KEY_SIZE];
|
let mut sk = [0u8; constants::SECRET_KEY_SIZE];
|
||||||
unsafe {
|
unsafe {
|
||||||
let ret = ffi::secp256k1_keypair_sec(
|
let ret = ffi::secp256k1_keypair_sec(
|
||||||
|
@ -297,9 +297,9 @@ impl PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new compressed public key key using data from BIP-340 [`::schnorrsig::KeyPair`]
|
/// Creates a new compressed public key key using data from BIP-340 [`KeyPair`]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_keypair(keypair: &::schnorrsig::KeyPair) -> Self {
|
pub fn from_keypair(keypair: &KeyPair) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut pk = ffi::PublicKey::new();
|
let mut pk = ffi::PublicKey::new();
|
||||||
let ret = ffi::secp256k1_keypair_pub(
|
let ret = ffi::secp256k1_keypair_pub(
|
||||||
|
@ -505,6 +505,175 @@ impl Ord for PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Opaque data structure that holds a keypair consisting of a secret and a public key.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct KeyPair(ffi::KeyPair);
|
||||||
|
impl_display_secret!(KeyPair);
|
||||||
|
|
||||||
|
impl KeyPair {
|
||||||
|
/// Obtains a raw const pointer suitable for use with FFI functions
|
||||||
|
#[inline]
|
||||||
|
pub fn as_ptr(&self) -> *const ffi::KeyPair {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtains a raw mutable pointer suitable for use with FFI functions
|
||||||
|
#[inline]
|
||||||
|
pub fn as_mut_ptr(&mut self) -> *mut ffi::KeyPair {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a Schnorr KeyPair directly from generic Secp256k1 secret key
|
||||||
|
///
|
||||||
|
/// # Panic
|
||||||
|
///
|
||||||
|
/// Panics if internal representation of the provided [`SecretKey`] does not hold correct secret
|
||||||
|
/// key value obtained from Secp256k1 library previously, specifically when secret key value is
|
||||||
|
/// out-of-range (0 or in excess of the group order).
|
||||||
|
#[inline]
|
||||||
|
pub fn from_secret_key<C: Signing>(
|
||||||
|
secp: &Secp256k1<C>,
|
||||||
|
sk: SecretKey,
|
||||||
|
) -> KeyPair {
|
||||||
|
unsafe {
|
||||||
|
let mut kp = ffi::KeyPair::new();
|
||||||
|
if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, sk.as_c_ptr()) == 1 {
|
||||||
|
KeyPair(kp)
|
||||||
|
} else {
|
||||||
|
panic!("the provided secret key is invalid: it is corrupted or was not produced by Secp256k1 library")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a Schnorr KeyPair directly from a secret key slice.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// [`Error::InvalidSecretKey`] if the provided data has an incorrect length, exceeds Secp256k1
|
||||||
|
/// field `p` value or the corresponding public key is not even.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_seckey_slice<C: Signing>(
|
||||||
|
secp: &Secp256k1<C>,
|
||||||
|
data: &[u8],
|
||||||
|
) -> Result<KeyPair, Error> {
|
||||||
|
if data.is_empty() || data.len() != constants::SECRET_KEY_SIZE {
|
||||||
|
return Err(Error::InvalidSecretKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut kp = ffi::KeyPair::new();
|
||||||
|
if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, data.as_c_ptr()) == 1 {
|
||||||
|
Ok(KeyPair(kp))
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidSecretKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a Schnorr KeyPair directly from a secret key string
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// [`Error::InvalidSecretKey`] if corresponding public key for the provided secret key is not even.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<KeyPair, Error> {
|
||||||
|
let mut res = [0u8; constants::SECRET_KEY_SIZE];
|
||||||
|
match from_hex(s, &mut res) {
|
||||||
|
Ok(constants::SECRET_KEY_SIZE) => {
|
||||||
|
KeyPair::from_seckey_slice(secp, &res[0..constants::SECRET_KEY_SIZE])
|
||||||
|
}
|
||||||
|
_ => Err(Error::InvalidPublicKey),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new random secret key. Requires compilation with the "rand" feature.
|
||||||
|
#[inline]
|
||||||
|
#[cfg(any(test, feature = "rand"))]
|
||||||
|
pub fn new<R: Rng + ?Sized, C: Signing>(secp: &Secp256k1<C>, rng: &mut R) -> KeyPair {
|
||||||
|
let mut random_32_bytes = || {
|
||||||
|
let mut ret = [0u8; 32];
|
||||||
|
rng.fill_bytes(&mut ret);
|
||||||
|
ret
|
||||||
|
};
|
||||||
|
let mut data = random_32_bytes();
|
||||||
|
unsafe {
|
||||||
|
let mut keypair = ffi::KeyPair::new();
|
||||||
|
while ffi::secp256k1_keypair_create(secp.ctx, &mut keypair, data.as_c_ptr()) == 0 {
|
||||||
|
data = random_32_bytes();
|
||||||
|
}
|
||||||
|
KeyPair(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 public key
|
||||||
|
/// accordingly.
|
||||||
|
///
|
||||||
|
/// Will return an error if the resulting key would be invalid or if the tweak was not a 32-byte
|
||||||
|
/// length slice.
|
||||||
|
///
|
||||||
|
/// NB: Will not error if the tweaked public key has an odd value and can't be used for
|
||||||
|
/// BIP 340-342 purposes.
|
||||||
|
// TODO: Add checked implementation
|
||||||
|
#[inline]
|
||||||
|
pub fn tweak_add_assign<C: Verification>(
|
||||||
|
&mut self,
|
||||||
|
secp: &Secp256k1<C>,
|
||||||
|
tweak: &[u8],
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
if tweak.len() != 32 {
|
||||||
|
return Err(Error::InvalidTweak);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let err = ffi::secp256k1_keypair_xonly_tweak_add(
|
||||||
|
secp.ctx,
|
||||||
|
&mut self.0,
|
||||||
|
tweak.as_c_ptr(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if err == 1 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidTweak)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<KeyPair> for SecretKey {
|
||||||
|
#[inline]
|
||||||
|
fn from(pair: KeyPair) -> Self {
|
||||||
|
SecretKey::from_keypair(&pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a KeyPair> for SecretKey {
|
||||||
|
#[inline]
|
||||||
|
fn from(pair: &'a KeyPair) -> Self {
|
||||||
|
SecretKey::from_keypair(pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<KeyPair> for PublicKey {
|
||||||
|
#[inline]
|
||||||
|
fn from(pair: KeyPair) -> Self {
|
||||||
|
PublicKey::from_keypair(&pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a KeyPair> for PublicKey {
|
||||||
|
#[inline]
|
||||||
|
fn from(pair: &'a KeyPair) -> Self {
|
||||||
|
PublicKey::from_keypair(pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use Secp256k1;
|
use Secp256k1;
|
||||||
|
|
|
@ -155,6 +155,7 @@ mod serde_util;
|
||||||
pub use key::SecretKey;
|
pub use key::SecretKey;
|
||||||
pub use key::PublicKey;
|
pub use key::PublicKey;
|
||||||
pub use key::ONE_KEY;
|
pub use key::ONE_KEY;
|
||||||
|
pub use key::KeyPair;
|
||||||
pub use context::*;
|
pub use context::*;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::{mem, fmt, ptr, str};
|
use core::{mem, fmt, ptr, str};
|
||||||
|
|
|
@ -12,7 +12,7 @@ use core::{fmt, ptr, str};
|
||||||
use ffi::{self, CPtr};
|
use ffi::{self, CPtr};
|
||||||
use {constants, Secp256k1};
|
use {constants, Secp256k1};
|
||||||
use {Message, Signing, Verification};
|
use {Message, Signing, Verification};
|
||||||
use SecretKey;
|
use KeyPair;
|
||||||
|
|
||||||
/// Represents a Schnorr signature.
|
/// Represents a Schnorr signature.
|
||||||
pub struct Signature([u8; constants::SCHNORRSIG_SIGNATURE_SIZE]);
|
pub struct Signature([u8; constants::SCHNORRSIG_SIGNATURE_SIZE]);
|
||||||
|
@ -74,11 +74,6 @@ impl str::FromStr for Signature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opaque data structure that holds a keypair consisting of a secret and a public key.
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct KeyPair(ffi::KeyPair);
|
|
||||||
impl_display_secret!(KeyPair);
|
|
||||||
|
|
||||||
/// A Schnorr public key, used for verification of Schnorr signatures
|
/// A Schnorr public key, used for verification of Schnorr signatures
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
||||||
pub struct PublicKey(ffi::XOnlyPublicKey);
|
pub struct PublicKey(ffi::XOnlyPublicKey);
|
||||||
|
@ -127,142 +122,6 @@ impl Signature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyPair {
|
|
||||||
/// Obtains a raw const pointer suitable for use with FFI functions
|
|
||||||
#[inline]
|
|
||||||
pub fn as_ptr(&self) -> *const ffi::KeyPair {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Obtains a raw mutable pointer suitable for use with FFI functions
|
|
||||||
#[inline]
|
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut ffi::KeyPair {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a Schnorr KeyPair directly from generic Secp256k1 secret key
|
|
||||||
///
|
|
||||||
/// # Panic
|
|
||||||
///
|
|
||||||
/// Panics if internal representation of the provided [`SecretKey`] does not hold correct secret
|
|
||||||
/// key value obtained from Secp256k1 library previously, specifically when secret key value is
|
|
||||||
/// out-of-range (0 or in excess of the group order).
|
|
||||||
#[inline]
|
|
||||||
pub fn from_secret_key<C: Signing>(
|
|
||||||
secp: &Secp256k1<C>,
|
|
||||||
sk: ::key::SecretKey,
|
|
||||||
) -> KeyPair {
|
|
||||||
unsafe {
|
|
||||||
let mut kp = ffi::KeyPair::new();
|
|
||||||
if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, sk.as_c_ptr()) == 1 {
|
|
||||||
KeyPair(kp)
|
|
||||||
} else {
|
|
||||||
panic!("the provided secret key is invalid: it is corrupted or was not produced by Secp256k1 library")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a Schnorr KeyPair directly from a secret key slice.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// [`Error::InvalidSecretKey`] if the provided data has an incorrect length, exceeds Secp256k1
|
|
||||||
/// field `p` value or the corresponding public key is not even.
|
|
||||||
#[inline]
|
|
||||||
pub fn from_seckey_slice<C: Signing>(
|
|
||||||
secp: &Secp256k1<C>,
|
|
||||||
data: &[u8],
|
|
||||||
) -> Result<KeyPair, Error> {
|
|
||||||
if data.is_empty() || data.len() != constants::SECRET_KEY_SIZE {
|
|
||||||
return Err(Error::InvalidSecretKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let mut kp = ffi::KeyPair::new();
|
|
||||||
if ffi::secp256k1_keypair_create(secp.ctx, &mut kp, data.as_c_ptr()) == 1 {
|
|
||||||
Ok(KeyPair(kp))
|
|
||||||
} else {
|
|
||||||
Err(Error::InvalidSecretKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a Schnorr KeyPair directly from a secret key string
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// [`Error::InvalidSecretKey`] if corresponding public key for the provided secret key is not even.
|
|
||||||
#[inline]
|
|
||||||
pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<KeyPair, Error> {
|
|
||||||
let mut res = [0u8; constants::SECRET_KEY_SIZE];
|
|
||||||
match from_hex(s, &mut res) {
|
|
||||||
Ok(constants::SECRET_KEY_SIZE) => {
|
|
||||||
KeyPair::from_seckey_slice(secp, &res[0..constants::SECRET_KEY_SIZE])
|
|
||||||
}
|
|
||||||
_ => Err(Error::InvalidPublicKey),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new random secret key. Requires compilation with the "rand" feature.
|
|
||||||
#[inline]
|
|
||||||
#[cfg(any(test, feature = "rand"))]
|
|
||||||
pub fn new<R: Rng + ?Sized, C: Signing>(secp: &Secp256k1<C>, rng: &mut R) -> KeyPair {
|
|
||||||
let mut random_32_bytes = || {
|
|
||||||
let mut ret = [0u8; 32];
|
|
||||||
rng.fill_bytes(&mut ret);
|
|
||||||
ret
|
|
||||||
};
|
|
||||||
let mut data = random_32_bytes();
|
|
||||||
unsafe {
|
|
||||||
let mut keypair = ffi::KeyPair::new();
|
|
||||||
while ffi::secp256k1_keypair_create(secp.ctx, &mut keypair, data.as_c_ptr()) == 0 {
|
|
||||||
data = random_32_bytes();
|
|
||||||
}
|
|
||||||
KeyPair(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 public key
|
|
||||||
/// accordingly.
|
|
||||||
///
|
|
||||||
/// Will return an error if the resulting key would be invalid or if the tweak was not a 32-byte
|
|
||||||
/// length slice.
|
|
||||||
///
|
|
||||||
/// NB: Will not error if the tweaked public key has an odd value and can't be used for
|
|
||||||
/// BIP 340-342 purposes.
|
|
||||||
// TODO: Add checked implementation
|
|
||||||
#[inline]
|
|
||||||
pub fn tweak_add_assign<C: Verification>(
|
|
||||||
&mut self,
|
|
||||||
secp: &Secp256k1<C>,
|
|
||||||
tweak: &[u8],
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
if tweak.len() != 32 {
|
|
||||||
return Err(Error::InvalidTweak);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let err = ffi::secp256k1_keypair_xonly_tweak_add(
|
|
||||||
secp.ctx,
|
|
||||||
&mut self.0,
|
|
||||||
tweak.as_c_ptr(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if err == 1 {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(Error::InvalidTweak)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PublicKey {
|
impl PublicKey {
|
||||||
/// Obtains a raw const pointer suitable for use with FFI functions
|
/// Obtains a raw const pointer suitable for use with FFI functions
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -475,34 +334,6 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<KeyPair> for SecretKey {
|
|
||||||
#[inline]
|
|
||||||
fn from(pair: KeyPair) -> Self {
|
|
||||||
SecretKey::from_keypair(&pair)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a KeyPair> for SecretKey {
|
|
||||||
#[inline]
|
|
||||||
fn from(pair: &'a KeyPair) -> Self {
|
|
||||||
SecretKey::from_keypair(pair)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: Signing> Secp256k1<C> {
|
impl<C: Signing> Secp256k1<C> {
|
||||||
fn schnorrsig_sign_helper(
|
fn schnorrsig_sign_helper(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
//! Helpers for displaying secret values
|
//! Helpers for displaying secret values
|
||||||
|
|
||||||
use ::core::fmt;
|
use ::core::fmt;
|
||||||
use ::{SecretKey, schnorrsig::KeyPair, to_hex};
|
use ::{SecretKey, KeyPair, to_hex};
|
||||||
use constants::SECRET_KEY_SIZE;
|
use constants::SECRET_KEY_SIZE;
|
||||||
|
|
||||||
macro_rules! impl_display_secret {
|
macro_rules! impl_display_secret {
|
||||||
|
@ -124,7 +124,7 @@ impl KeyPair {
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use secp256k1::ONE_KEY;
|
/// use secp256k1::ONE_KEY;
|
||||||
/// use secp256k1::schnorrsig::KeyPair;
|
/// use secp256k1::KeyPair;
|
||||||
/// use secp256k1::Secp256k1;
|
/// use secp256k1::Secp256k1;
|
||||||
///
|
///
|
||||||
/// let secp = Secp256k1::new();
|
/// let secp = Secp256k1::new();
|
||||||
|
|
Loading…
Reference in New Issue