2014-08-12 02:26:14 +00:00
// Bitcoin secp256k1 bindings
// Written in 2014 by
// Dawid Ciężarkiewicz
// Andrew Poelstra
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//
2022-01-13 06:02:58 +00:00
//! Public and secret keys.
//!
2014-08-10 01:03:17 +00:00
2021-09-14 14:47:26 +00:00
use core ::convert ::TryFrom ;
2022-11-16 00:06:12 +00:00
use core ::ops ::BitXor ;
use core ::{ fmt , ptr , str } ;
2022-10-27 03:14:57 +00:00
2022-03-01 18:20:56 +00:00
#[ cfg(feature = " serde " ) ]
use serde ::ser ::SerializeTuple ;
2022-11-16 00:06:12 +00:00
use crate ::ffi ::types ::c_uint ;
2022-11-16 23:33:38 +00:00
use crate ::ffi ::{ self , CPtr } ;
2022-11-16 00:06:12 +00:00
#[ cfg(all(feature = " global-context " , feature = " rand-std " )) ]
2021-09-14 09:18:22 +00:00
use crate ::schnorr ;
2022-11-16 00:06:12 +00:00
use crate ::Error ::{ self , InvalidPublicKey , InvalidPublicKeySum , InvalidSecretKey } ;
2022-11-16 23:33:38 +00:00
use crate ::{ constants , from_hex , impl_array_newtype , Scalar , Secp256k1 , Signing , Verification } ;
2022-11-16 00:06:12 +00:00
#[ cfg(feature = " global-context " ) ]
use crate ::{ ecdsa , Message , SECP256K1 } ;
#[ cfg(feature = " bitcoin-hashes " ) ]
use crate ::{ hashes , ThirtyTwoByteHash } ;
2022-02-08 06:11:05 +00:00
2022-01-13 07:54:28 +00:00
/// Secret 256-bit key used as `x` in an ECDSA signature.
///
2022-03-08 01:01:55 +00:00
/// # Serde support
///
/// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
/// of 32 `u8`s for non-human-readable formats. This representation is optimal for for some formats
/// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
///
2022-01-13 07:54:28 +00:00
/// # Examples
///
/// Basic usage:
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1, SecretKey};
///
/// let secp = Secp256k1::new();
/// let secret_key = SecretKey::new(&mut rand::thread_rng());
/// # }
/// ```
2022-03-08 01:01:55 +00:00
/// [`bincode`]: https://docs.rs/bincode
/// [`cbor`]: https://docs.rs/cbor
2021-06-20 15:07:44 +00:00
pub struct SecretKey ( [ u8 ; constants ::SECRET_KEY_SIZE ] ) ;
2015-01-17 16:13:45 +00:00
impl_array_newtype! ( SecretKey , u8 , constants ::SECRET_KEY_SIZE ) ;
2021-08-09 15:06:05 +00:00
impl_display_secret! ( SecretKey ) ;
2019-07-23 09:56:23 +00:00
2018-08-26 18:39:41 +00:00
impl str ::FromStr for SecretKey {
type Err = Error ;
fn from_str ( s : & str ) -> Result < SecretKey , Error > {
2021-10-17 01:07:51 +00:00
let mut res = [ 0 u8 ; constants ::SECRET_KEY_SIZE ] ;
2018-08-26 18:39:41 +00:00
match from_hex ( s , & mut res ) {
2021-04-26 05:43:54 +00:00
Ok ( constants ::SECRET_KEY_SIZE ) = > SecretKey ::from_slice ( & res ) ,
2022-11-16 00:06:12 +00:00
_ = > Err ( Error ::InvalidSecretKey ) ,
2018-08-26 18:39:41 +00:00
}
}
}
2022-01-13 07:54:28 +00:00
/// A Secp256k1 public key, used for verification of signatures.
///
2022-03-08 01:01:55 +00:00
/// # Serde support
///
/// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
/// of 33 `u8`s for non-human-readable formats. This representation is optimal for for some formats
/// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
///
2022-01-13 07:54:28 +00:00
/// # Examples
///
/// Basic usage:
///
/// ```
2022-02-01 02:43:42 +00:00
/// # #[cfg(any(feature = "alloc", feature = "std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{SecretKey, Secp256k1, PublicKey};
///
/// let secp = Secp256k1::new();
/// let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
/// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
2022-02-01 02:43:42 +00:00
/// # }
2022-01-13 07:54:28 +00:00
/// ```
2022-03-08 01:01:55 +00:00
/// [`bincode`]: https://docs.rs/bincode
/// [`cbor`]: https://docs.rs/cbor
2022-11-07 01:23:43 +00:00
#[ derive(Copy, Clone, Debug) ]
#[ cfg_attr(fuzzing, derive(PartialOrd, Ord, PartialEq, Eq, Hash)) ]
2021-03-31 01:07:20 +00:00
#[ repr(transparent) ]
2021-06-20 15:07:44 +00:00
pub struct PublicKey ( ffi ::PublicKey ) ;
2014-08-10 01:03:17 +00:00
2019-07-23 09:56:23 +00:00
impl fmt ::LowerHex for PublicKey {
2018-08-15 20:40:15 +00:00
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
let ser = self . serialize ( ) ;
for ch in & ser [ .. ] {
write! ( f , " {:02x} " , * ch ) ? ;
}
Ok ( ( ) )
}
}
2019-07-23 09:56:23 +00:00
impl fmt ::Display for PublicKey {
2022-11-16 00:06:12 +00:00
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result { fmt ::LowerHex ::fmt ( self , f ) }
2019-07-23 09:56:23 +00:00
}
2018-08-26 18:39:41 +00:00
impl str ::FromStr for PublicKey {
type Err = Error ;
fn from_str ( s : & str ) -> Result < PublicKey , Error > {
2021-10-17 01:07:51 +00:00
let mut res = [ 0 u8 ; constants ::UNCOMPRESSED_PUBLIC_KEY_SIZE ] ;
2018-08-26 18:39:41 +00:00
match from_hex ( s , & mut res ) {
2022-11-16 00:06:12 +00:00
Ok ( constants ::PUBLIC_KEY_SIZE ) = >
PublicKey ::from_slice ( & res [ 0 .. constants ::PUBLIC_KEY_SIZE ] ) ,
Ok ( constants ::UNCOMPRESSED_PUBLIC_KEY_SIZE ) = > PublicKey ::from_slice ( & res ) ,
_ = > Err ( Error ::InvalidPublicKey ) ,
2018-08-26 18:39:41 +00:00
}
}
}
2017-12-19 20:49:01 +00:00
#[ cfg(any(test, feature = " rand " )) ]
2021-09-14 09:18:22 +00:00
fn random_32_bytes < R : rand ::Rng + ? Sized > ( rng : & mut R ) -> [ u8 ; 32 ] {
2015-01-17 16:13:45 +00:00
let mut ret = [ 0 u8 ; 32 ] ;
rng . fill_bytes ( & mut ret ) ;
2014-08-16 09:21:35 +00:00
ret
2014-08-10 01:03:17 +00:00
}
2014-09-12 13:28:35 +00:00
impl SecretKey {
2022-01-04 15:55:01 +00:00
/// Generates a new random secret key.
2022-01-13 07:54:28 +00:00
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, SecretKey};
/// let secret_key = SecretKey::new(&mut rand::thread_rng());
/// # }
/// ```
2014-08-10 01:03:17 +00:00
#[ inline ]
2017-12-19 20:49:01 +00:00
#[ cfg(any(test, feature = " rand " )) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " rand " ))) ]
2021-09-14 09:18:22 +00:00
pub fn new < R : rand ::Rng + ? Sized > ( rng : & mut R ) -> SecretKey {
2015-04-12 20:54:22 +00:00
let mut data = random_32_bytes ( rng ) ;
2014-08-28 18:11:25 +00:00
unsafe {
2018-11-06 21:57:52 +00:00
while ffi ::secp256k1_ec_seckey_verify (
ffi ::secp256k1_context_no_precomp ,
2019-08-16 18:49:24 +00:00
data . as_c_ptr ( ) ,
2018-11-06 21:57:52 +00:00
) = = 0
{
2015-04-12 20:54:22 +00:00
data = random_32_bytes ( rng ) ;
2014-08-28 18:11:25 +00:00
}
}
2014-09-12 13:28:35 +00:00
SecretKey ( data )
2014-08-10 01:03:17 +00:00
}
2022-01-13 07:54:28 +00:00
/// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key.
///
/// # Examples
///
/// ```
/// use secp256k1::SecretKey;
/// let sk = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
/// ```
2014-08-10 01:46:38 +00:00
#[ inline ]
2022-11-16 00:06:12 +00:00
pub fn from_slice ( data : & [ u8 ] ) -> Result < SecretKey , Error > {
2021-09-14 14:47:26 +00:00
match < [ u8 ; constants ::SECRET_KEY_SIZE ] > ::try_from ( data ) {
Ok ( data ) = > {
2014-08-10 01:46:38 +00:00
unsafe {
2018-11-06 21:57:52 +00:00
if ffi ::secp256k1_ec_seckey_verify (
ffi ::secp256k1_context_no_precomp ,
2019-08-16 18:49:24 +00:00
data . as_c_ptr ( ) ,
2018-11-06 21:57:52 +00:00
) = = 0
{
2014-08-24 23:13:08 +00:00
return Err ( InvalidSecretKey ) ;
}
2014-08-10 01:46:38 +00:00
}
2021-09-14 14:47:26 +00:00
Ok ( SecretKey ( data ) )
2014-08-10 01:46:38 +00:00
}
2022-11-16 00:06:12 +00:00
Err ( _ ) = > Err ( InvalidSecretKey ) ,
2014-08-10 01:46:38 +00:00
}
}
2014-08-28 16:16:53 +00:00
2022-01-13 07:54:28 +00:00
/// Creates a new secret key using data from BIP-340 [`KeyPair`].
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1, SecretKey, KeyPair};
///
/// let secp = Secp256k1::new();
/// let key_pair = KeyPair::new(&secp, &mut rand::thread_rng());
/// let secret_key = SecretKey::from_keypair(&key_pair);
/// # }
/// ```
2021-06-20 15:07:44 +00:00
#[ inline ]
2021-09-09 09:34:48 +00:00
pub fn from_keypair ( keypair : & KeyPair ) -> Self {
2021-10-17 01:07:51 +00:00
let mut sk = [ 0 u8 ; constants ::SECRET_KEY_SIZE ] ;
2021-06-20 15:07:44 +00:00
unsafe {
let ret = ffi ::secp256k1_keypair_sec (
ffi ::secp256k1_context_no_precomp ,
sk . as_mut_c_ptr ( ) ,
2022-11-16 00:06:12 +00:00
keypair . as_c_ptr ( ) ,
2021-06-20 15:07:44 +00:00
) ;
debug_assert_eq! ( ret , 1 ) ;
}
SecretKey ( sk )
}
2022-10-27 03:14:57 +00:00
/// Constructs a [`SecretKey`] by hashing `data` with hash algorithm `H`.
///
/// Requires the feature `bitcoin_hashes` to be enabled.
///
/// # Examples
///
/// ```
/// # #[cfg(feature="bitcoin_hashes")] {
/// use secp256k1::hashes::{sha256, Hash};
/// use secp256k1::SecretKey;
///
/// let sk1 = SecretKey::from_hashed_data::<sha256::Hash>("Hello world!".as_bytes());
/// // is equivalent to
/// let sk2 = SecretKey::from(sha256::Hash::hash("Hello world!".as_bytes()));
///
/// assert_eq!(sk1, sk2);
/// # }
/// ```
2022-11-09 23:35:49 +00:00
#[ cfg(feature = " bitcoin-hashes " ) ]
#[ cfg_attr(docsrs, doc(cfg(feature = " bitcoin-hashes " ))) ]
2022-10-27 03:14:57 +00:00
#[ inline ]
pub fn from_hashed_data < H : ThirtyTwoByteHash + hashes ::Hash > ( data : & [ u8 ] ) -> Self {
< H as hashes ::Hash > ::hash ( data ) . into ( )
}
2022-02-18 11:48:56 +00:00
/// Returns the secret key as a byte value.
2021-08-09 15:06:05 +00:00
#[ inline ]
2022-11-16 00:06:12 +00:00
pub fn secret_bytes ( & self ) -> [ u8 ; constants ::SECRET_KEY_SIZE ] { self . 0 }
2021-08-09 15:06:05 +00:00
2022-04-06 04:39:15 +00:00
/// Negates the secret key.
#[ inline ]
2022-06-28 03:18:57 +00:00
#[ must_use = " you forgot to use the negated secret key " ]
2022-04-06 04:39:15 +00:00
pub fn negate ( mut self ) -> SecretKey {
2020-02-07 04:31:43 +00:00
unsafe {
2020-05-13 11:52:18 +00:00
let res = ffi ::secp256k1_ec_seckey_negate (
2020-02-07 04:31:43 +00:00
ffi ::secp256k1_context_no_precomp ,
2022-11-16 00:06:12 +00:00
self . as_mut_c_ptr ( ) ,
2020-02-07 04:31:43 +00:00
) ;
2020-06-10 00:59:55 +00:00
debug_assert_eq! ( res , 1 ) ;
2020-02-07 04:31:43 +00:00
}
2022-04-06 04:39:15 +00:00
self
2020-02-07 04:31:43 +00:00
}
2022-04-06 04:05:04 +00:00
/// Tweaks a [`SecretKey`] by adding `tweak` modulo the curve order.
///
/// # Errors
///
2022-06-21 16:37:35 +00:00
/// Returns an error if the resulting key would be invalid.
2022-04-06 04:05:04 +00:00
#[ inline ]
pub fn add_tweak ( mut self , tweak : & Scalar ) -> Result < SecretKey , Error > {
2014-08-28 16:16:53 +00:00
unsafe {
2020-05-13 11:52:18 +00:00
if ffi ::secp256k1_ec_seckey_tweak_add (
2018-11-06 21:57:52 +00:00
ffi ::secp256k1_context_no_precomp ,
2019-08-16 18:49:24 +00:00
self . as_mut_c_ptr ( ) ,
2022-04-06 04:05:04 +00:00
tweak . as_c_ptr ( ) ,
2018-11-06 21:57:52 +00:00
) ! = 1
{
2018-08-15 17:11:32 +00:00
Err ( Error ::InvalidTweak )
2014-08-28 16:16:53 +00:00
} else {
2022-04-06 04:05:04 +00:00
Ok ( self )
2014-08-28 16:16:53 +00:00
}
}
}
2016-08-20 17:00:39 +00:00
2022-04-06 04:05:04 +00:00
/// Tweaks a [`SecretKey`] by multiplying by `tweak` modulo the curve order.
///
/// # Errors
///
2022-06-21 16:37:35 +00:00
/// Returns an error if the resulting key would be invalid.
2022-04-06 04:05:04 +00:00
#[ inline ]
pub fn mul_tweak ( mut self , tweak : & Scalar ) -> Result < SecretKey , Error > {
2016-08-20 17:00:39 +00:00
unsafe {
2020-05-13 11:52:18 +00:00
if ffi ::secp256k1_ec_seckey_tweak_mul (
2018-11-06 21:57:52 +00:00
ffi ::secp256k1_context_no_precomp ,
2019-08-16 18:49:24 +00:00
self . as_mut_c_ptr ( ) ,
2022-04-06 04:05:04 +00:00
tweak . as_c_ptr ( ) ,
2018-11-06 21:57:52 +00:00
) ! = 1
{
2018-08-15 17:11:32 +00:00
Err ( Error ::InvalidTweak )
2016-08-20 17:00:39 +00:00
} else {
2022-04-06 04:05:04 +00:00
Ok ( self )
2016-08-20 17:00:39 +00:00
}
}
}
2022-02-08 06:11:05 +00:00
/// Constructs an ECDSA signature for `msg` using the global [`SECP256K1`] context.
#[ inline ]
#[ cfg(feature = " global-context " ) ]
#[ cfg_attr(docsrs, doc(cfg(feature = " global-context " ))) ]
2022-11-16 00:06:12 +00:00
pub fn sign_ecdsa ( & self , msg : Message ) -> ecdsa ::Signature { SECP256K1 . sign_ecdsa ( & msg , self ) }
2022-03-24 03:53:40 +00:00
/// Returns the [`KeyPair`] for this [`SecretKey`].
///
/// This is equivalent to using [`KeyPair::from_secret_key`].
#[ inline ]
pub fn keypair < C : Signing > ( & self , secp : & Secp256k1 < C > ) -> KeyPair {
KeyPair ::from_secret_key ( secp , self )
}
/// Returns the [`PublicKey`] for this [`SecretKey`].
///
/// This is equivalent to using [`PublicKey::from_secret_key`].
#[ inline ]
pub fn public_key < C : Signing > ( & self , secp : & Secp256k1 < C > ) -> PublicKey {
PublicKey ::from_secret_key ( secp , self )
}
/// Returns the [`XOnlyPublicKey`] (and it's [`Parity`]) for this [`SecretKey`].
///
/// This is equivalent to `XOnlyPublicKey::from_keypair(self.keypair(secp))`.
#[ inline ]
pub fn x_only_public_key < C : Signing > ( & self , secp : & Secp256k1 < C > ) -> ( XOnlyPublicKey , Parity ) {
let kp = self . keypair ( secp ) ;
XOnlyPublicKey ::from_keypair ( & kp )
}
2014-08-10 01:03:17 +00:00
}
2022-11-09 23:35:49 +00:00
#[ cfg(feature = " bitcoin-hashes " ) ]
2022-10-27 03:14:57 +00:00
impl < T : ThirtyTwoByteHash > From < T > for SecretKey {
/// Converts a 32-byte hash directly to a secret key without error paths.
fn from ( t : T ) -> SecretKey {
SecretKey ::from_slice ( & t . into_32 ( ) ) . expect ( " failed to create secret key " )
}
}
2020-05-15 12:37:08 +00:00
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl serde ::Serialize for SecretKey {
fn serialize < S : serde ::Serializer > ( & self , s : S ) -> Result < S ::Ok , S ::Error > {
2020-05-15 12:37:08 +00:00
if s . is_human_readable ( ) {
2022-02-08 08:41:43 +00:00
let mut buf = [ 0 u8 ; constants ::SECRET_KEY_SIZE * 2 ] ;
2021-09-14 09:18:22 +00:00
s . serialize_str ( crate ::to_hex ( & self . 0 , & mut buf ) . expect ( " fixed-size hex serialization " ) )
2020-05-15 12:37:08 +00:00
} else {
2022-03-01 18:20:56 +00:00
let mut tuple = s . serialize_tuple ( constants ::SECRET_KEY_SIZE ) ? ;
for byte in self . 0. iter ( ) {
tuple . serialize_element ( byte ) ? ;
}
tuple . end ( )
2020-05-15 12:37:08 +00:00
}
}
}
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl < ' de > serde ::Deserialize < ' de > for SecretKey {
fn deserialize < D : serde ::Deserializer < ' de > > ( d : D ) -> Result < Self , D ::Error > {
2020-05-15 12:37:08 +00:00
if d . is_human_readable ( ) {
2021-01-12 22:54:33 +00:00
d . deserialize_str ( super ::serde_util ::FromStrVisitor ::new (
2022-11-16 00:06:12 +00:00
" a hex string representing 32 byte SecretKey " ,
2020-05-15 12:37:08 +00:00
) )
} else {
2022-03-01 18:20:56 +00:00
let visitor = super ::serde_util ::Tuple32Visitor ::new (
2020-05-15 12:37:08 +00:00
" raw 32 bytes SecretKey " ,
2022-11-16 00:06:12 +00:00
SecretKey ::from_slice ,
2022-03-01 18:20:56 +00:00
) ;
d . deserialize_tuple ( constants ::SECRET_KEY_SIZE , visitor )
2020-05-15 12:37:08 +00:00
}
}
}
2018-07-25 13:57:36 +00:00
2014-08-10 01:03:17 +00:00
impl PublicKey {
2022-01-13 07:54:28 +00:00
/// Obtains a raw const pointer suitable for use with FFI functions.
2015-07-28 16:03:10 +00:00
#[ inline ]
2022-11-07 01:09:57 +00:00
#[ deprecated(since = " 0.25.0 " , note = " Use Self::as_c_ptr if you need to access the FFI layer " ) ]
2022-11-16 00:06:12 +00:00
pub fn as_ptr ( & self ) -> * const ffi ::PublicKey { self . as_c_ptr ( ) }
2014-08-10 01:03:17 +00:00
2022-01-13 07:54:28 +00:00
/// Obtains a raw mutable pointer suitable for use with FFI functions.
2019-04-16 18:48:24 +00:00
#[ inline ]
2022-11-16 00:06:12 +00:00
#[ deprecated(
since = " 0.25.0 " ,
note = " Use Self::as_mut_c_ptr if you need to access the FFI layer "
) ]
pub fn as_mut_ptr ( & mut self ) -> * mut ffi ::PublicKey { self . as_mut_c_ptr ( ) }
2019-04-16 18:48:24 +00:00
2022-01-13 07:54:28 +00:00
/// Creates a new public key from a [`SecretKey`].
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1, SecretKey, PublicKey};
///
/// let secp = Secp256k1::new();
/// let secret_key = SecretKey::new(&mut rand::thread_rng());
/// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
/// # }
/// ```
2014-08-10 01:03:17 +00:00
#[ inline ]
2022-11-16 00:06:12 +00:00
pub fn from_secret_key < C : Signing > ( secp : & Secp256k1 < C > , sk : & SecretKey ) -> PublicKey {
2014-08-28 17:59:44 +00:00
unsafe {
2020-11-27 17:49:11 +00:00
let mut pk = ffi ::PublicKey ::new ( ) ;
2014-08-28 18:11:25 +00:00
// We can assume the return value because it's not possible to construct
2021-11-17 23:52:28 +00:00
// an invalid `SecretKey` without transmute trickery or something.
2019-08-16 18:49:24 +00:00
let res = ffi ::secp256k1_ec_pubkey_create ( secp . ctx , & mut pk , sk . as_c_ptr ( ) ) ;
2015-04-11 18:07:43 +00:00
debug_assert_eq! ( res , 1 ) ;
2020-11-27 17:49:11 +00:00
PublicKey ( pk )
2014-08-10 03:34:16 +00:00
}
2014-08-10 01:03:17 +00:00
}
2022-02-08 06:11:05 +00:00
/// Creates a new public key from a [`SecretKey`] and the global [`SECP256K1`] context.
#[ inline ]
#[ cfg(feature = " global-context " ) ]
#[ cfg_attr(docsrs, doc(cfg(feature = " global-context " ))) ]
pub fn from_secret_key_global ( sk : & SecretKey ) -> PublicKey {
2022-06-10 02:29:16 +00:00
PublicKey ::from_secret_key ( SECP256K1 , sk )
2022-02-08 06:11:05 +00:00
}
2022-01-13 07:57:11 +00:00
/// Creates a public key directly from a slice.
2014-08-10 01:46:38 +00:00
#[ inline ]
2018-11-06 21:57:52 +00:00
pub fn from_slice ( data : & [ u8 ] ) -> Result < PublicKey , Error > {
2022-11-16 00:06:12 +00:00
if data . is_empty ( ) {
return Err ( Error ::InvalidPublicKey ) ;
}
2019-08-08 20:01:08 +00:00
2015-07-28 16:03:10 +00:00
unsafe {
2020-11-27 17:49:11 +00:00
let mut pk = ffi ::PublicKey ::new ( ) ;
2018-11-06 21:57:52 +00:00
if ffi ::secp256k1_ec_pubkey_parse (
ffi ::secp256k1_context_no_precomp ,
& mut pk ,
2019-08-16 18:49:24 +00:00
data . as_c_ptr ( ) ,
2018-12-27 13:39:54 +00:00
data . len ( ) as usize ,
2018-11-06 21:57:52 +00:00
) = = 1
{
2015-07-28 16:03:10 +00:00
Ok ( PublicKey ( pk ) )
} else {
Err ( InvalidPublicKey )
}
2014-08-10 01:03:17 +00:00
}
}
2021-11-11 02:41:57 +00:00
/// Creates a new compressed public key using data from BIP-340 [`KeyPair`].
2022-01-13 07:54:28 +00:00
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1, PublicKey, KeyPair};
///
/// let secp = Secp256k1::new();
/// let key_pair = KeyPair::new(&secp, &mut rand::thread_rng());
/// let public_key = PublicKey::from_keypair(&key_pair);
/// # }
/// ```
2021-06-20 15:07:44 +00:00
#[ inline ]
2021-09-09 09:34:48 +00:00
pub fn from_keypair ( keypair : & KeyPair ) -> Self {
2021-06-20 15:07:44 +00:00
unsafe {
let mut pk = ffi ::PublicKey ::new ( ) ;
let ret = ffi ::secp256k1_keypair_pub (
ffi ::secp256k1_context_no_precomp ,
& mut pk ,
2022-11-16 00:06:12 +00:00
keypair . as_c_ptr ( ) ,
2021-06-20 15:07:44 +00:00
) ;
debug_assert_eq! ( ret , 1 ) ;
PublicKey ( pk )
}
}
2022-03-24 03:53:40 +00:00
/// Creates a [`PublicKey`] using the key material from `pk` combined with the `parity`.
pub fn from_x_only_public_key ( pk : XOnlyPublicKey , parity : Parity ) -> PublicKey {
let mut buf = [ 0 u8 ; 33 ] ;
// First byte of a compressed key should be `0x02 AND parity`.
buf [ 0 ] = match parity {
Parity ::Even = > 0x02 ,
Parity ::Odd = > 0x03 ,
} ;
buf [ 1 .. ] . clone_from_slice ( & pk . serialize ( ) ) ;
PublicKey ::from_slice ( & buf ) . expect ( " we know the buffer is valid " )
}
2014-08-10 01:03:17 +00:00
#[ inline ]
2022-01-13 07:57:11 +00:00
/// Serializes 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 it up to one bit.
2017-12-19 20:36:46 +00:00
pub fn serialize ( & self ) -> [ u8 ; constants ::PUBLIC_KEY_SIZE ] {
2021-10-17 01:07:51 +00:00
let mut ret = [ 0 u8 ; constants ::PUBLIC_KEY_SIZE ] ;
2021-09-14 14:47:26 +00:00
self . serialize_internal ( & mut ret , ffi ::SECP256K1_SER_COMPRESSED ) ;
2017-12-19 20:36:46 +00:00
ret
}
2021-09-14 14:47:26 +00:00
#[ inline ]
2022-01-13 07:57:11 +00:00
/// Serializes the key as a byte-encoded pair of values, in uncompressed form.
2017-12-19 20:36:46 +00:00
pub fn serialize_uncompressed ( & self ) -> [ u8 ; constants ::UNCOMPRESSED_PUBLIC_KEY_SIZE ] {
2021-10-17 01:07:51 +00:00
let mut ret = [ 0 u8 ; constants ::UNCOMPRESSED_PUBLIC_KEY_SIZE ] ;
2021-09-14 14:47:26 +00:00
self . serialize_internal ( & mut ret , ffi ::SECP256K1_SER_UNCOMPRESSED ) ;
ret
}
2017-12-19 20:36:46 +00:00
2021-09-14 14:47:26 +00:00
#[ inline(always) ]
fn serialize_internal ( & self , ret : & mut [ u8 ] , flag : c_uint ) {
let mut ret_len = ret . len ( ) ;
let res = unsafe {
ffi ::secp256k1_ec_pubkey_serialize (
2018-11-06 21:57:52 +00:00
ffi ::secp256k1_context_no_precomp ,
2019-08-16 18:49:24 +00:00
ret . as_mut_c_ptr ( ) ,
2017-12-19 20:36:46 +00:00
& mut ret_len ,
2019-08-16 18:49:24 +00:00
self . as_c_ptr ( ) ,
2021-09-14 14:47:26 +00:00
flag ,
)
} ;
debug_assert_eq! ( res , 1 ) ;
debug_assert_eq! ( ret_len , ret . len ( ) ) ;
2014-08-10 01:03:17 +00:00
}
2014-08-28 16:16:53 +00:00
2022-04-06 04:39:15 +00:00
/// Negates the public key.
#[ inline ]
2022-06-28 03:18:57 +00:00
#[ must_use = " you forgot to use the negated public key " ]
2022-04-06 04:39:15 +00:00
pub fn negate < C : Verification > ( mut self , secp : & Secp256k1 < C > ) -> PublicKey {
2020-02-07 04:31:43 +00:00
unsafe {
2020-11-30 02:47:34 +00:00
let res = ffi ::secp256k1_ec_pubkey_negate ( secp . ctx , & mut self . 0 ) ;
2020-06-10 00:59:55 +00:00
debug_assert_eq! ( res , 1 ) ;
2020-02-07 04:31:43 +00:00
}
2022-04-06 04:39:15 +00:00
self
2020-02-07 04:31:43 +00:00
}
2022-04-06 04:05:04 +00:00
/// Tweaks a [`PublicKey`] by adding `tweak * G` modulo the curve order.
///
/// # Errors
///
/// Returns an error if the resulting key would be invalid.
#[ inline ]
pub fn add_exp_tweak < C : Verification > (
mut self ,
secp : & Secp256k1 < C > ,
2022-11-16 00:06:12 +00:00
tweak : & Scalar ,
2022-04-06 04:05:04 +00:00
) -> Result < PublicKey , Error > {
2014-08-28 16:16:53 +00:00
unsafe {
2022-04-06 04:05:04 +00:00
if ffi ::secp256k1_ec_pubkey_tweak_add ( secp . ctx , & mut self . 0 , tweak . as_c_ptr ( ) ) = = 1 {
Ok ( self )
2015-07-28 16:03:10 +00:00
} else {
2018-08-15 17:11:32 +00:00
Err ( Error ::InvalidTweak )
2014-08-28 16:16:53 +00:00
}
}
}
2016-08-20 17:00:39 +00:00
2022-04-06 04:05:04 +00:00
/// Tweaks a [`PublicKey`] by multiplying by `tweak` modulo the curve order.
///
/// # Errors
///
/// Returns an error if the resulting key would be invalid.
#[ inline ]
pub fn mul_tweak < C : Verification > (
mut self ,
secp : & Secp256k1 < C > ,
other : & Scalar ,
) -> Result < PublicKey , Error > {
2016-08-20 17:00:39 +00:00
unsafe {
2020-11-30 02:47:34 +00:00
if ffi ::secp256k1_ec_pubkey_tweak_mul ( secp . ctx , & mut self . 0 , other . as_c_ptr ( ) ) = = 1 {
2022-04-06 04:05:04 +00:00
Ok ( self )
2016-08-20 17:00:39 +00:00
} else {
2018-08-15 17:11:32 +00:00
Err ( Error ::InvalidTweak )
2016-08-20 17:00:39 +00:00
}
}
}
2018-08-22 20:18:25 +00:00
2022-01-13 07:54:28 +00:00
/// Adds a second key to this one, returning the sum.
///
/// # Errors
///
/// If the result would be the point at infinity, i.e. adding this point to its own negation.
///
/// # Examples
///
/// ```
2022-02-01 03:00:10 +00:00
/// # #[cfg(all(feature = "rand-std", any(feature = "alloc", feature = "std")))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1};
///
/// let secp = Secp256k1::new();
/// let mut rng = rand::thread_rng();
/// let (_, pk1) = secp.generate_keypair(&mut rng);
/// let (_, pk2) = secp.generate_keypair(&mut rng);
/// let sum = pk1.combine(&pk2).expect("It's improbable to fail for 2 random public keys");
/// # }
///```
2018-11-06 21:57:52 +00:00
pub fn combine ( & self , other : & PublicKey ) -> Result < PublicKey , Error > {
2021-03-31 01:07:20 +00:00
PublicKey ::combine_keys ( & [ self , other ] )
}
2022-01-13 07:54:28 +00:00
/// Adds the keys in the provided slice together, returning the sum.
///
/// # Errors
///
/// Errors under any of the following conditions:
/// - The result would be the point at infinity, i.e. adding a point to its own negation.
/// - The provided slice is empty.
/// - The number of elements in the provided slice is greater than `i32::MAX`.
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1, PublicKey};
///
/// let secp = Secp256k1::new();
/// let mut rng = rand::thread_rng();
/// let (_, pk1) = secp.generate_keypair(&mut rng);
/// let (_, pk2) = secp.generate_keypair(&mut rng);
/// let (_, pk3) = secp.generate_keypair(&mut rng);
/// let sum = PublicKey::combine_keys(&[&pk1, &pk2, &pk3]).expect("It's improbable to fail for 3 random public keys");
/// # }
/// ```
2021-03-31 01:07:20 +00:00
pub fn combine_keys ( keys : & [ & PublicKey ] ) -> Result < PublicKey , Error > {
use core ::i32 ::MAX ;
2022-11-16 00:06:12 +00:00
use core ::mem ::transmute ;
2021-03-31 01:07:20 +00:00
2021-06-10 12:06:48 +00:00
if keys . is_empty ( ) | | keys . len ( ) > MAX as usize {
return Err ( InvalidPublicKeySum ) ;
}
2018-08-22 20:18:25 +00:00
unsafe {
2019-08-08 21:19:31 +00:00
let mut ret = ffi ::PublicKey ::new ( ) ;
2022-11-16 00:06:12 +00:00
let ptrs : & [ * const ffi ::PublicKey ] =
2021-03-31 01:07:20 +00:00
transmute ::< & [ & PublicKey ] , & [ * const ffi ::PublicKey ] > ( keys ) ;
2018-11-06 21:57:52 +00:00
if ffi ::secp256k1_ec_pubkey_combine (
ffi ::secp256k1_context_no_precomp ,
& mut ret ,
2019-08-16 18:49:24 +00:00
ptrs . as_c_ptr ( ) ,
2022-11-16 00:06:12 +00:00
keys . len ( ) as i32 ,
2018-11-06 21:57:52 +00:00
) = = 1
{
2018-08-22 20:18:25 +00:00
Ok ( PublicKey ( ret ) )
} else {
2021-06-10 12:06:48 +00:00
Err ( InvalidPublicKeySum )
2018-08-22 20:18:25 +00:00
}
}
}
2022-03-24 03:53:40 +00:00
/// Returns the [`XOnlyPublicKey`] (and it's [`Parity`]) for this [`PublicKey`].
#[ inline ]
pub fn x_only_public_key ( & self ) -> ( XOnlyPublicKey , Parity ) {
let mut pk_parity = 0 ;
unsafe {
let mut xonly_pk = ffi ::XOnlyPublicKey ::new ( ) ;
let ret = ffi ::secp256k1_xonly_pubkey_from_pubkey (
ffi ::secp256k1_context_no_precomp ,
& mut xonly_pk ,
& mut pk_parity ,
2022-11-07 01:09:57 +00:00
self . as_c_ptr ( ) ,
2022-03-24 03:53:40 +00:00
) ;
debug_assert_eq! ( ret , 1 ) ;
2022-11-16 00:06:12 +00:00
let parity =
Parity ::from_i32 ( pk_parity ) . expect ( " should not panic, pk_parity is 0 or 1 " ) ;
2022-03-24 03:53:40 +00:00
( XOnlyPublicKey ( xonly_pk ) , parity )
}
}
2014-08-10 01:03:17 +00:00
}
2022-11-07 01:09:57 +00:00
/// This trait enables interaction with the FFI layer and even though it is part of the public API
/// normal users should never need to directly interact with FFI types.
2019-08-16 18:48:03 +00:00
impl CPtr for PublicKey {
type Target = ffi ::PublicKey ;
2022-11-07 01:09:57 +00:00
/// Obtains a const pointer suitable for use with FFI functions.
2022-11-16 00:06:12 +00:00
fn as_c_ptr ( & self ) -> * const Self ::Target { & self . 0 }
2019-08-16 18:48:03 +00:00
2022-11-07 01:09:57 +00:00
/// Obtains a mutable pointer suitable for use with FFI functions.
2022-11-16 00:06:12 +00:00
fn as_mut_c_ptr ( & mut self ) -> * mut Self ::Target { & mut self . 0 }
2019-08-16 18:48:03 +00:00
}
2022-11-07 01:09:57 +00:00
/// Creates a new public key from a FFI public key.
///
/// Note, normal users should never need to interact directly with FFI types.
2015-10-14 14:35:02 +00:00
impl From < ffi ::PublicKey > for PublicKey {
#[ inline ]
2022-11-16 00:06:12 +00:00
fn from ( pk : ffi ::PublicKey ) -> PublicKey { PublicKey ( pk ) }
2015-10-14 14:35:02 +00:00
}
2020-05-15 12:37:08 +00:00
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl serde ::Serialize for PublicKey {
fn serialize < S : serde ::Serializer > ( & self , s : S ) -> Result < S ::Ok , S ::Error > {
2020-05-15 12:37:08 +00:00
if s . is_human_readable ( ) {
s . collect_str ( self )
} else {
2022-03-01 18:20:56 +00:00
let mut tuple = s . serialize_tuple ( constants ::PUBLIC_KEY_SIZE ) ? ;
2022-11-03 00:09:32 +00:00
// Serialize in compressed form.
for byte in self . serialize ( ) . iter ( ) {
2022-03-01 18:20:56 +00:00
tuple . serialize_element ( & byte ) ? ;
}
tuple . end ( )
2020-05-15 12:37:08 +00:00
}
}
}
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl < ' de > serde ::Deserialize < ' de > for PublicKey {
fn deserialize < D : serde ::Deserializer < ' de > > ( d : D ) -> Result < PublicKey , D ::Error > {
2020-05-15 12:37:08 +00:00
if d . is_human_readable ( ) {
2021-01-12 22:54:33 +00:00
d . deserialize_str ( super ::serde_util ::FromStrVisitor ::new (
2022-11-16 00:06:12 +00:00
" an ASCII hex string representing a public key " ,
2020-05-15 12:37:08 +00:00
) )
} else {
2022-03-01 18:20:56 +00:00
let visitor = super ::serde_util ::Tuple33Visitor ::new (
" 33 bytes compressed public key " ,
2022-11-16 00:06:12 +00:00
PublicKey ::from_slice ,
2022-03-01 18:20:56 +00:00
) ;
d . deserialize_tuple ( constants ::PUBLIC_KEY_SIZE , visitor )
2020-05-15 12:37:08 +00:00
}
}
}
2018-07-25 13:57:36 +00:00
2021-06-29 11:19:18 +00:00
#[ cfg(not(fuzzing)) ]
2020-11-09 17:30:57 +00:00
impl PartialOrd for PublicKey {
2021-09-14 09:18:22 +00:00
fn partial_cmp ( & self , other : & PublicKey ) -> Option < core ::cmp ::Ordering > {
2021-06-19 09:25:06 +00:00
Some ( self . cmp ( other ) )
2020-11-09 17:30:57 +00:00
}
}
2021-06-29 11:19:18 +00:00
#[ cfg(not(fuzzing)) ]
2020-11-09 17:30:57 +00:00
impl Ord for PublicKey {
2021-09-14 09:18:22 +00:00
fn cmp ( & self , other : & PublicKey ) -> core ::cmp ::Ordering {
2021-06-19 09:25:06 +00:00
let ret = unsafe {
2022-11-16 00:06:12 +00:00
ffi ::secp256k1_ec_pubkey_cmp (
ffi ::secp256k1_context_no_precomp ,
self . as_c_ptr ( ) ,
other . as_c_ptr ( ) ,
)
2021-06-19 09:25:06 +00:00
} ;
ret . cmp ( & 0 i32 )
2020-11-09 17:30:57 +00:00
}
}
2022-11-07 01:23:43 +00:00
#[ cfg(not(fuzzing)) ]
impl PartialEq for PublicKey {
2022-11-16 00:06:12 +00:00
fn eq ( & self , other : & Self ) -> bool { self . cmp ( other ) = = core ::cmp ::Ordering ::Equal }
2022-11-07 01:23:43 +00:00
}
#[ cfg(not(fuzzing)) ]
impl Eq for PublicKey { }
#[ cfg(not(fuzzing)) ]
impl core ::hash ::Hash for PublicKey {
fn hash < H : core ::hash ::Hasher > ( & self , state : & mut H ) {
let ser = self . serialize ( ) ;
ser . hash ( state ) ;
}
}
2021-09-09 09:34:48 +00:00
/// Opaque data structure that holds a keypair consisting of a secret and a public key.
2022-01-18 15:56:17 +00:00
///
/// # Serde support
2022-01-13 07:54:28 +00:00
///
2022-03-08 01:26:43 +00:00
/// Implements de/serialization with the `serde` and_`global-context` features enabled. Serializes
/// the secret bytes only. We treat the byte value as a tuple of 32 `u8`s for non-human-readable
/// formats. This representation is optimal for for some formats (e.g. [`bincode`]) however other
/// formats may be less optimal (e.g. [`cbor`]). For human-readable formats we use a hex string.
2022-01-18 15:56:17 +00:00
///
2022-01-13 07:54:28 +00:00
/// # Examples
///
/// Basic usage:
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, KeyPair, Secp256k1};
///
/// let secp = Secp256k1::new();
/// let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
2022-03-24 02:23:12 +00:00
/// let key_pair = KeyPair::from_secret_key(&secp, &secret_key);
2022-01-13 07:54:28 +00:00
/// # }
/// ```
2022-03-08 01:26:43 +00:00
/// [`bincode`]: https://docs.rs/bincode
/// [`cbor`]: https://docs.rs/cbor
2022-01-06 23:01:11 +00:00
#[ derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash) ]
2021-09-09 09:34:48 +00:00
pub struct KeyPair ( ffi ::KeyPair ) ;
impl_display_secret! ( KeyPair ) ;
impl KeyPair {
2022-01-13 07:54:28 +00:00
/// Obtains a raw const pointer suitable for use with FFI functions.
2021-09-09 09:34:48 +00:00
#[ inline ]
2022-11-07 01:09:57 +00:00
#[ deprecated(since = " 0.25.0 " , note = " Use Self::as_c_ptr if you need to access the FFI layer " ) ]
2022-11-16 00:06:12 +00:00
pub fn as_ptr ( & self ) -> * const ffi ::KeyPair { self . as_c_ptr ( ) }
2021-09-09 09:34:48 +00:00
2022-01-13 07:54:28 +00:00
/// Obtains a raw mutable pointer suitable for use with FFI functions.
2021-09-09 09:34:48 +00:00
#[ inline ]
2022-11-16 00:06:12 +00:00
#[ deprecated(
since = " 0.25.0 " ,
note = " Use Self::as_mut_c_ptr if you need to access the FFI layer "
) ]
pub fn as_mut_ptr ( & mut self ) -> * mut ffi ::KeyPair { self . as_mut_c_ptr ( ) }
2021-09-09 09:34:48 +00:00
2022-03-21 23:29:30 +00:00
/// Creates a [`KeyPair`] directly from a Secp256k1 secret key.
2021-09-09 09:34:48 +00:00
#[ inline ]
2022-11-16 00:06:12 +00:00
pub fn from_secret_key < C : Signing > ( secp : & Secp256k1 < C > , sk : & SecretKey ) -> KeyPair {
2021-09-09 09:34:48 +00:00
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 " )
}
}
}
2022-03-21 23:32:19 +00:00
/// Creates a [`KeyPair`] directly from a secret key slice.
2021-09-09 09:34:48 +00:00
///
/// # 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 )
}
}
}
2022-03-21 23:32:19 +00:00
/// Creates a [`KeyPair`] directly from a secret key string.
2021-09-09 09:34:48 +00:00
///
/// # 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 = [ 0 u8 ; constants ::SECRET_KEY_SIZE ] ;
match from_hex ( s , & mut res ) {
2022-11-16 00:06:12 +00:00
Ok ( constants ::SECRET_KEY_SIZE ) = >
KeyPair ::from_seckey_slice ( secp , & res [ 0 .. constants ::SECRET_KEY_SIZE ] ) ,
2021-09-09 09:34:48 +00:00
_ = > Err ( Error ::InvalidPublicKey ) ,
}
}
2022-03-21 23:32:19 +00:00
/// Creates a [`KeyPair`] directly from a secret key string and the global [`SECP256K1`] context.
2022-02-08 06:11:05 +00:00
///
/// # Errors
///
/// [`Error::InvalidSecretKey`] if corresponding public key for the provided secret key is not even.
#[ inline ]
#[ cfg(feature = " global-context " ) ]
#[ cfg_attr(docsrs, doc(cfg(feature = " global-context " ))) ]
pub fn from_seckey_str_global ( s : & str ) -> Result < KeyPair , Error > {
KeyPair ::from_seckey_str ( SECP256K1 , s )
}
2022-01-04 15:55:01 +00:00
/// Generates a new random secret key.
2022-01-13 07:54:28 +00:00
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1, SecretKey, KeyPair};
///
/// let secp = Secp256k1::new();
/// let key_pair = KeyPair::new(&secp, &mut rand::thread_rng());
/// # }
/// ```
2021-09-09 09:34:48 +00:00
#[ inline ]
#[ cfg(any(test, feature = " rand " )) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " rand " ))) ]
2021-09-14 09:18:22 +00:00
pub fn new < R : rand ::Rng + ? Sized , C : Signing > ( secp : & Secp256k1 < C > , rng : & mut R ) -> KeyPair {
2021-09-09 09:34:48 +00:00
let mut random_32_bytes = | | {
let mut ret = [ 0 u8 ; 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 )
}
}
2022-02-08 06:11:05 +00:00
/// Generates a new random secret key using the global [`SECP256K1`] context.
#[ inline ]
#[ cfg(all(feature = " global-context " , feature = " rand " )) ]
#[ cfg_attr(docsrs, doc(cfg(all(feature = " global-context " , feature = " rand " )))) ]
pub fn new_global < R : ::rand ::Rng + ? Sized > ( rng : & mut R ) -> KeyPair {
KeyPair ::new ( SECP256K1 , rng )
}
2022-02-18 11:48:56 +00:00
/// Returns the secret bytes for this key pair.
2021-09-09 09:34:48 +00:00
#[ inline ]
2022-02-18 11:48:56 +00:00
pub fn secret_bytes ( & self ) -> [ u8 ; constants ::SECRET_KEY_SIZE ] {
2021-09-09 09:34:48 +00:00
* SecretKey ::from_keypair ( self ) . as_ref ( )
}
2022-04-06 05:24:23 +00:00
/// Tweaks a keypair by first converting the public key to an xonly key and tweaking it.
2021-09-09 09:34:48 +00:00
///
2022-01-13 07:54:28 +00:00
/// # Errors
///
2022-06-09 12:35:41 +00:00
/// Returns an error if the resulting key would be invalid.
2021-09-09 09:34:48 +00:00
///
/// NB: Will not error if the tweaked public key has an odd value and can't be used for
/// BIP 340-342 purposes.
2022-01-13 07:54:28 +00:00
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-06-09 12:35:41 +00:00
/// use secp256k1::{Secp256k1, KeyPair, Scalar};
2022-01-13 07:54:28 +00:00
/// use secp256k1::rand::{RngCore, thread_rng};
///
/// let secp = Secp256k1::new();
2022-06-09 12:35:41 +00:00
/// let tweak = Scalar::random();
2022-01-13 07:54:28 +00:00
///
/// let mut key_pair = KeyPair::new(&secp, &mut thread_rng());
2022-04-06 05:24:23 +00:00
/// let tweaked = key_pair.add_xonly_tweak(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
2022-01-13 07:54:28 +00:00
/// # }
/// ```
2021-09-09 09:34:48 +00:00
// TODO: Add checked implementation
#[ inline ]
2022-04-06 05:24:23 +00:00
pub fn add_xonly_tweak < C : Verification > (
mut self ,
2021-09-09 09:34:48 +00:00
secp : & Secp256k1 < C > ,
2022-06-09 12:35:41 +00:00
tweak : & Scalar ,
2022-04-06 05:24:23 +00:00
) -> Result < KeyPair , Error > {
2021-09-09 09:34:48 +00:00
unsafe {
2022-11-16 00:06:12 +00:00
let err =
ffi ::secp256k1_keypair_xonly_tweak_add ( secp . ctx , & mut self . 0 , tweak . as_c_ptr ( ) ) ;
2022-01-03 21:36:46 +00:00
if err ! = 1 {
return Err ( Error ::InvalidTweak ) ;
2021-09-09 09:34:48 +00:00
}
2022-01-03 21:36:46 +00:00
2022-04-06 05:24:23 +00:00
Ok ( self )
2021-09-09 09:34:48 +00:00
}
}
2022-01-12 07:11:55 +00:00
2022-03-24 03:53:40 +00:00
/// Returns the [`SecretKey`] for this [`KeyPair`].
///
/// This is equivalent to using [`SecretKey::from_keypair`].
#[ inline ]
2022-11-16 00:06:12 +00:00
pub fn secret_key ( & self ) -> SecretKey { SecretKey ::from_keypair ( self ) }
2022-03-24 03:53:40 +00:00
/// Returns the [`PublicKey`] for this [`KeyPair`].
///
/// This is equivalent to using [`PublicKey::from_keypair`].
#[ inline ]
2022-11-16 00:06:12 +00:00
pub fn public_key ( & self ) -> PublicKey { PublicKey ::from_keypair ( self ) }
2022-03-24 03:53:40 +00:00
/// Returns the [`XOnlyPublicKey`] (and it's [`Parity`]) for this [`KeyPair`].
///
/// This is equivalent to using [`XOnlyPublicKey::from_keypair`].
2022-01-12 07:11:55 +00:00
#[ inline ]
2022-03-24 03:53:40 +00:00
pub fn x_only_public_key ( & self ) -> ( XOnlyPublicKey , Parity ) {
2022-01-12 07:11:55 +00:00
XOnlyPublicKey ::from_keypair ( self )
}
2022-02-08 06:11:05 +00:00
/// Constructs an schnorr signature for `msg` using the global [`SECP256K1`] context.
#[ inline ]
#[ cfg(all(feature = " global-context " , feature = " rand-std " )) ]
#[ cfg_attr(docsrs, doc(cfg(all(feature = " global-context " , feature = " rand-std " )))) ]
pub fn sign_schnorr ( & self , msg : Message ) -> schnorr ::Signature {
SECP256K1 . sign_schnorr ( & msg , self )
}
2021-09-09 09:34:48 +00:00
}
impl From < KeyPair > for SecretKey {
#[ inline ]
2022-11-16 00:06:12 +00:00
fn from ( pair : KeyPair ) -> Self { SecretKey ::from_keypair ( & pair ) }
2021-09-09 09:34:48 +00:00
}
impl < ' a > From < & ' a KeyPair > for SecretKey {
#[ inline ]
2022-11-16 00:06:12 +00:00
fn from ( pair : & ' a KeyPair ) -> Self { SecretKey ::from_keypair ( pair ) }
2021-09-09 09:34:48 +00:00
}
impl From < KeyPair > for PublicKey {
#[ inline ]
2022-11-16 00:06:12 +00:00
fn from ( pair : KeyPair ) -> Self { PublicKey ::from_keypair ( & pair ) }
2021-09-09 09:34:48 +00:00
}
impl < ' a > From < & ' a KeyPair > for PublicKey {
#[ inline ]
2022-11-16 00:06:12 +00:00
fn from ( pair : & ' a KeyPair ) -> Self { PublicKey ::from_keypair ( pair ) }
2021-09-09 09:34:48 +00:00
}
2021-09-27 11:28:53 +00:00
impl str ::FromStr for KeyPair {
type Err = Error ;
fn from_str ( s : & str ) -> Result < Self , Self ::Err > {
2022-10-21 18:35:59 +00:00
#[ cfg(feature = " global-context " ) ]
let ctx = SECP256K1 ;
#[ cfg(all(not(feature = " global-context " ), feature = " alloc " )) ]
let ctx = Secp256k1 ::signing_only ( ) ;
#[ cfg(not(any(feature = " global-context " , feature = " alloc " ))) ]
let ctx : Secp256k1 < crate ::SignOnlyPreallocated > = panic! ( " The previous implementation was panicking too, please enable the global-context feature of rust-secp256k1 " ) ;
#[ allow(clippy::needless_borrow) ]
2021-09-27 11:28:53 +00:00
KeyPair ::from_seckey_str ( & ctx , s )
}
}
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl serde ::Serialize for KeyPair {
fn serialize < S : serde ::Serializer > ( & self , s : S ) -> Result < S ::Ok , S ::Error > {
2021-09-27 11:28:53 +00:00
if s . is_human_readable ( ) {
2022-02-08 08:41:43 +00:00
let mut buf = [ 0 u8 ; constants ::SECRET_KEY_SIZE * 2 ] ;
2022-11-16 00:06:12 +00:00
s . serialize_str (
crate ::to_hex ( & self . secret_bytes ( ) , & mut buf )
. expect ( " fixed-size hex serialization " ) ,
)
2021-09-27 11:28:53 +00:00
} else {
2022-03-01 18:20:56 +00:00
let mut tuple = s . serialize_tuple ( constants ::SECRET_KEY_SIZE ) ? ;
for byte in self . secret_bytes ( ) . iter ( ) {
tuple . serialize_element ( & byte ) ? ;
}
tuple . end ( )
2021-09-27 11:28:53 +00:00
}
}
}
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl < ' de > serde ::Deserialize < ' de > for KeyPair {
fn deserialize < D : serde ::Deserializer < ' de > > ( d : D ) -> Result < Self , D ::Error > {
2021-09-27 11:28:53 +00:00
if d . is_human_readable ( ) {
d . deserialize_str ( super ::serde_util ::FromStrVisitor ::new (
2022-11-16 00:06:12 +00:00
" a hex string representing 32 byte KeyPair " ,
2021-09-27 11:28:53 +00:00
) )
} else {
2022-11-16 00:06:12 +00:00
let visitor = super ::serde_util ::Tuple32Visitor ::new ( " raw 32 bytes KeyPair " , | data | {
#[ cfg(feature = " global-context " ) ]
let ctx = SECP256K1 ;
2022-10-21 18:35:59 +00:00
2022-11-16 00:06:12 +00:00
#[ cfg(all(not(feature = " global-context " ), feature = " alloc " )) ]
let ctx = Secp256k1 ::signing_only ( ) ;
2022-10-21 18:35:59 +00:00
2022-11-16 00:06:12 +00:00
#[ cfg(not(any(feature = " global-context " , feature = " alloc " ))) ]
let ctx : Secp256k1 < crate ::SignOnlyPreallocated > = panic! ( " The previous implementation was panicking too, please enable the global-context feature of rust-secp256k1 " ) ;
2022-10-21 18:35:59 +00:00
2022-11-16 00:06:12 +00:00
#[ allow(clippy::needless_borrow) ]
KeyPair ::from_seckey_slice ( & ctx , data )
} ) ;
2022-03-01 18:20:56 +00:00
d . deserialize_tuple ( constants ::SECRET_KEY_SIZE , visitor )
2021-09-27 11:28:53 +00:00
}
}
}
2022-11-07 01:09:57 +00:00
impl CPtr for KeyPair {
type Target = ffi ::KeyPair ;
2022-11-16 00:06:12 +00:00
fn as_c_ptr ( & self ) -> * const Self ::Target { & self . 0 }
2022-11-07 01:09:57 +00:00
2022-11-16 00:06:12 +00:00
fn as_mut_c_ptr ( & mut self ) -> * mut Self ::Target { & mut self . 0 }
2022-11-07 01:09:57 +00:00
}
2022-01-13 07:54:28 +00:00
/// An x-only public key, used for verification of Schnorr signatures and serialized according to BIP-340.
///
2022-03-08 01:01:55 +00:00
/// # Serde support
///
/// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
/// of 32 `u8`s for non-human-readable formats. This representation is optimal for for some formats
/// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
///
2022-01-13 07:54:28 +00:00
/// # Examples
///
/// Basic usage:
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-01-13 07:54:28 +00:00
/// use secp256k1::{rand, Secp256k1, KeyPair, XOnlyPublicKey};
///
/// let secp = Secp256k1::new();
/// let key_pair = KeyPair::new(&secp, &mut rand::thread_rng());
/// let xonly = XOnlyPublicKey::from_keypair(&key_pair);
/// # }
/// ```
2022-03-08 01:01:55 +00:00
/// [`bincode`]: https://docs.rs/bincode
/// [`cbor`]: https://docs.rs/cbor
2021-09-09 09:41:11 +00:00
#[ derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash) ]
pub struct XOnlyPublicKey ( ffi ::XOnlyPublicKey ) ;
impl fmt ::LowerHex for XOnlyPublicKey {
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
let ser = self . serialize ( ) ;
for ch in & ser [ .. ] {
write! ( f , " {:02x} " , * ch ) ? ;
}
Ok ( ( ) )
}
}
impl fmt ::Display for XOnlyPublicKey {
2022-11-16 00:06:12 +00:00
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result { fmt ::LowerHex ::fmt ( self , f ) }
2021-09-09 09:41:11 +00:00
}
impl str ::FromStr for XOnlyPublicKey {
type Err = Error ;
fn from_str ( s : & str ) -> Result < XOnlyPublicKey , Error > {
2022-03-01 18:34:49 +00:00
let mut res = [ 0 u8 ; constants ::SCHNORR_PUBLIC_KEY_SIZE ] ;
2021-09-09 09:41:11 +00:00
match from_hex ( s , & mut res ) {
2022-11-16 00:06:12 +00:00
Ok ( constants ::SCHNORR_PUBLIC_KEY_SIZE ) = >
XOnlyPublicKey ::from_slice ( & res [ 0 .. constants ::SCHNORR_PUBLIC_KEY_SIZE ] ) ,
2021-09-09 09:41:11 +00:00
_ = > Err ( Error ::InvalidPublicKey ) ,
}
}
}
impl XOnlyPublicKey {
2022-01-13 07:57:11 +00:00
/// Obtains a raw const pointer suitable for use with FFI functions.
2021-09-09 09:41:11 +00:00
#[ inline ]
2022-11-07 01:09:57 +00:00
#[ deprecated(since = " 0.25.0 " , note = " Use Self::as_c_ptr if you need to access the FFI layer " ) ]
2022-11-16 00:06:12 +00:00
pub fn as_ptr ( & self ) -> * const ffi ::XOnlyPublicKey { self . as_c_ptr ( ) }
2021-09-09 09:41:11 +00:00
2022-01-13 07:57:11 +00:00
/// Obtains a raw mutable pointer suitable for use with FFI functions.
2021-09-09 09:41:11 +00:00
#[ inline ]
2022-11-16 00:06:12 +00:00
#[ deprecated(
since = " 0.25.0 " ,
note = " Use Self::as_mut_c_ptr if you need to access the FFI layer "
) ]
pub fn as_mut_ptr ( & mut self ) -> * mut ffi ::XOnlyPublicKey { self . as_mut_c_ptr ( ) }
2021-09-09 09:41:11 +00:00
2022-03-24 03:53:40 +00:00
/// Returns the [`XOnlyPublicKey`] (and it's [`Parity`]) for `keypair`.
2021-09-09 09:41:11 +00:00
#[ inline ]
2022-03-24 03:53:40 +00:00
pub fn from_keypair ( keypair : & KeyPair ) -> ( XOnlyPublicKey , Parity ) {
2021-09-09 09:41:11 +00:00
let mut pk_parity = 0 ;
unsafe {
let mut xonly_pk = ffi ::XOnlyPublicKey ::new ( ) ;
let ret = ffi ::secp256k1_keypair_xonly_pub (
2021-12-23 19:16:33 +00:00
ffi ::secp256k1_context_no_precomp ,
2021-09-09 09:41:11 +00:00
& mut xonly_pk ,
& mut pk_parity ,
2022-11-07 01:09:57 +00:00
keypair . as_c_ptr ( ) ,
2021-09-09 09:41:11 +00:00
) ;
debug_assert_eq! ( ret , 1 ) ;
2022-11-16 00:06:12 +00:00
let parity =
Parity ::from_i32 ( pk_parity ) . expect ( " should not panic, pk_parity is 0 or 1 " ) ;
2022-03-24 03:53:40 +00:00
( XOnlyPublicKey ( xonly_pk ) , parity )
2021-09-09 09:41:11 +00:00
}
}
2022-01-13 07:57:11 +00:00
/// Creates a Schnorr public key directly from a slice.
2021-09-09 09:41:11 +00:00
///
/// # Errors
///
/// Returns [`Error::InvalidPublicKey`] if the length of the data slice is not 32 bytes or the
2022-01-13 07:57:11 +00:00
/// slice does not represent a valid Secp256k1 point x coordinate.
2021-09-09 09:41:11 +00:00
#[ inline ]
pub fn from_slice ( data : & [ u8 ] ) -> Result < XOnlyPublicKey , Error > {
2022-03-01 18:34:49 +00:00
if data . is_empty ( ) | | data . len ( ) ! = constants ::SCHNORR_PUBLIC_KEY_SIZE {
2021-09-09 09:41:11 +00:00
return Err ( Error ::InvalidPublicKey ) ;
}
unsafe {
let mut pk = ffi ::XOnlyPublicKey ::new ( ) ;
if ffi ::secp256k1_xonly_pubkey_parse (
ffi ::secp256k1_context_no_precomp ,
& mut pk ,
data . as_c_ptr ( ) ,
) = = 1
{
Ok ( XOnlyPublicKey ( pk ) )
} else {
Err ( Error ::InvalidPublicKey )
}
}
}
#[ inline ]
2022-01-13 07:57:11 +00:00
/// Serializes the key as a byte-encoded x coordinate value (32 bytes).
2022-03-01 18:34:49 +00:00
pub fn serialize ( & self ) -> [ u8 ; constants ::SCHNORR_PUBLIC_KEY_SIZE ] {
let mut ret = [ 0 u8 ; constants ::SCHNORR_PUBLIC_KEY_SIZE ] ;
2021-09-09 09:41:11 +00:00
unsafe {
let err = ffi ::secp256k1_xonly_pubkey_serialize (
ffi ::secp256k1_context_no_precomp ,
ret . as_mut_c_ptr ( ) ,
self . as_c_ptr ( ) ,
) ;
debug_assert_eq! ( err , 1 ) ;
}
ret
}
2022-04-06 05:24:23 +00:00
/// Tweaks an [`XOnlyPublicKey`] by adding the generator multiplied with the given tweak to it.
2022-01-13 07:54:28 +00:00
///
/// # Returns
2021-09-09 09:41:11 +00:00
///
2022-04-06 05:24:23 +00:00
/// The newly tweaked key plus an opaque type representing the parity of the tweaked key, this
/// should be provided to `tweak_add_check` which can be used to verify a tweak more efficiently
/// than regenerating it and checking equality.
2022-01-03 21:49:08 +00:00
///
2022-01-13 07:54:28 +00:00
/// # Errors
///
2022-06-21 16:37:35 +00:00
/// If the resulting key would be invalid.
2022-01-13 07:54:28 +00:00
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-04-06 05:24:23 +00:00
/// use secp256k1::{Secp256k1, KeyPair, Scalar, XOnlyPublicKey};
2022-01-13 07:54:28 +00:00
/// use secp256k1::rand::{RngCore, thread_rng};
///
/// let secp = Secp256k1::new();
2022-06-09 12:35:41 +00:00
/// let tweak = Scalar::random();
2022-01-13 07:54:28 +00:00
///
/// let mut key_pair = KeyPair::new(&secp, &mut thread_rng());
2022-04-06 05:24:23 +00:00
/// let (xonly, _parity) = key_pair.x_only_public_key();
/// let tweaked = xonly.add_tweak(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
2022-01-13 07:54:28 +00:00
/// # }
/// ```
2022-04-06 05:24:23 +00:00
pub fn add_tweak < V : Verification > (
mut self ,
2021-09-09 09:41:11 +00:00
secp : & Secp256k1 < V > ,
2022-06-09 12:35:41 +00:00
tweak : & Scalar ,
2022-04-06 05:24:23 +00:00
) -> Result < ( XOnlyPublicKey , Parity ) , Error > {
2022-03-24 03:30:57 +00:00
let mut pk_parity = 0 ;
2021-09-09 09:41:11 +00:00
unsafe {
let mut pubkey = ffi ::PublicKey ::new ( ) ;
let mut err = ffi ::secp256k1_xonly_pubkey_tweak_add (
secp . ctx ,
& mut pubkey ,
self . as_c_ptr ( ) ,
tweak . as_c_ptr ( ) ,
) ;
if err ! = 1 {
return Err ( Error ::InvalidTweak ) ;
}
err = ffi ::secp256k1_xonly_pubkey_from_pubkey (
secp . ctx ,
& mut self . 0 ,
2022-03-24 03:30:57 +00:00
& mut pk_parity ,
2021-09-09 09:41:11 +00:00
& pubkey ,
) ;
if err = = 0 {
2022-01-03 21:49:08 +00:00
return Err ( Error ::InvalidPublicKey ) ;
2021-09-09 09:41:11 +00:00
}
2022-01-03 21:49:08 +00:00
2022-04-06 05:24:23 +00:00
let parity = Parity ::from_i32 ( pk_parity ) ? ;
Ok ( ( self , parity ) )
2021-09-09 09:41:11 +00:00
}
}
2022-11-16 22:42:22 +00:00
/// Verifies that a tweak produced by [`XOnlyPublicKey::add_tweak`] was computed correctly.
2022-01-13 07:54:28 +00:00
///
/// Should be called on the original untweaked key. Takes the tweaked key and output parity from
2022-11-16 22:42:22 +00:00
/// [`XOnlyPublicKey::add_tweak`] as input.
2021-09-09 09:41:11 +00:00
///
2022-01-13 07:54:28 +00:00
/// Currently this is not much more efficient than just recomputing the tweak and checking
/// equality. However, in future this API will support batch verification, which is
/// significantly faster, so it is wise to design protocols with this in mind.
2021-09-09 09:41:11 +00:00
///
2022-01-13 07:54:28 +00:00
/// # Returns
2022-01-03 21:52:56 +00:00
///
/// True if tweak and check is successful, false otherwise.
2022-01-13 07:54:28 +00:00
///
/// # Examples
///
/// ```
2022-02-11 07:44:16 +00:00
/// # #[cfg(all(feature = "std", feature = "rand-std"))] {
2022-06-09 12:35:41 +00:00
/// use secp256k1::{Secp256k1, KeyPair, Scalar};
2022-01-13 07:54:28 +00:00
/// use secp256k1::rand::{thread_rng, RngCore};
///
/// let secp = Secp256k1::new();
2022-06-09 12:35:41 +00:00
/// let tweak = Scalar::random();
2022-01-13 07:54:28 +00:00
///
/// let mut key_pair = KeyPair::new(&secp, &mut thread_rng());
2022-03-24 03:53:40 +00:00
/// let (mut public_key, _) = key_pair.x_only_public_key();
2022-01-13 07:54:28 +00:00
/// let original = public_key;
2022-11-10 00:26:26 +00:00
/// let (tweaked, parity) = public_key.add_tweak(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
/// assert!(original.tweak_add_check(&secp, &tweaked, parity, tweak));
2022-01-13 07:54:28 +00:00
/// # }
/// ```
2021-09-09 09:41:11 +00:00
pub fn tweak_add_check < V : Verification > (
& self ,
secp : & Secp256k1 < V > ,
tweaked_key : & Self ,
2022-01-03 21:49:08 +00:00
tweaked_parity : Parity ,
2022-06-09 12:35:41 +00:00
tweak : Scalar ,
2021-09-09 09:41:11 +00:00
) -> bool {
let tweaked_ser = tweaked_key . serialize ( ) ;
unsafe {
let err = ffi ::secp256k1_xonly_pubkey_tweak_add_check (
secp . ctx ,
tweaked_ser . as_c_ptr ( ) ,
2022-01-19 05:20:07 +00:00
tweaked_parity . to_i32 ( ) ,
2021-09-09 09:41:11 +00:00
& self . 0 ,
tweak . as_c_ptr ( ) ,
) ;
err = = 1
}
}
2022-03-24 03:53:40 +00:00
/// Returns the [`PublicKey`] for this [`XOnlyPublicKey`].
///
/// This is equivalent to using [`PublicKey::from_xonly_and_parity(self, parity)`].
#[ inline ]
pub fn public_key ( & self , parity : Parity ) -> PublicKey {
PublicKey ::from_x_only_public_key ( * self , parity )
}
2021-09-09 09:41:11 +00:00
}
2022-01-19 05:20:07 +00:00
/// Represents the parity passed between FFI function calls.
2022-01-06 17:17:26 +00:00
#[ derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash) ]
2022-01-19 05:20:07 +00:00
pub enum Parity {
/// Even parity.
Even = 0 ,
/// Odd parity.
Odd = 1 ,
}
impl Parity {
2022-02-09 14:33:25 +00:00
/// Converts parity into an integer (byte) value.
///
/// This returns `0` for even parity and `1` for odd parity.
2022-11-16 00:06:12 +00:00
pub fn to_u8 ( self ) -> u8 { self as u8 }
2022-01-19 05:20:07 +00:00
2022-02-09 14:33:25 +00:00
/// Converts parity into an integer value.
///
/// This returns `0` for even parity and `1` for odd parity.
2022-11-16 00:06:12 +00:00
pub fn to_i32 ( self ) -> i32 { self as i32 }
2022-01-19 05:20:07 +00:00
/// Constructs a [`Parity`] from a byte.
2022-02-09 14:33:25 +00:00
///
/// The only allowed values are `0` meaning even parity and `1` meaning odd.
/// Other values result in error being returned.
2022-02-10 22:50:02 +00:00
pub fn from_u8 ( parity : u8 ) -> Result < Parity , InvalidParityValue > {
2022-02-09 14:33:25 +00:00
Parity ::from_i32 ( parity . into ( ) )
2022-01-19 05:20:07 +00:00
}
/// Constructs a [`Parity`] from a signed integer.
2022-02-09 14:33:25 +00:00
///
/// The only allowed values are `0` meaning even parity and `1` meaning odd.
/// Other values result in error being returned.
2022-02-10 22:50:02 +00:00
pub fn from_i32 ( parity : i32 ) -> Result < Parity , InvalidParityValue > {
2022-01-19 05:20:07 +00:00
match parity {
0 = > Ok ( Parity ::Even ) ,
1 = > Ok ( Parity ::Odd ) ,
2022-02-10 22:50:02 +00:00
_ = > Err ( InvalidParityValue ( parity ) ) ,
2022-01-19 05:20:07 +00:00
}
2022-01-03 21:49:08 +00:00
}
}
2022-02-24 15:27:38 +00:00
/// `Even` for `0`, `Odd` for `1`, error for anything else
impl TryFrom < i32 > for Parity {
type Error = InvalidParityValue ;
2022-11-16 00:06:12 +00:00
fn try_from ( parity : i32 ) -> Result < Self , Self ::Error > { Self ::from_i32 ( parity ) }
2022-02-24 15:27:38 +00:00
}
/// `Even` for `0`, `Odd` for `1`, error for anything else
impl TryFrom < u8 > for Parity {
type Error = InvalidParityValue ;
2022-11-16 00:06:12 +00:00
fn try_from ( parity : u8 ) -> Result < Self , Self ::Error > { Self ::from_u8 ( parity ) }
2022-02-24 15:27:38 +00:00
}
2022-02-09 14:33:25 +00:00
/// The conversion returns `0` for even parity and `1` for odd.
2022-01-03 21:49:08 +00:00
impl From < Parity > for i32 {
2022-11-16 00:06:12 +00:00
fn from ( parity : Parity ) -> i32 { parity . to_i32 ( ) }
2022-01-19 05:20:07 +00:00
}
2022-02-10 22:50:02 +00:00
/// The conversion returns `0` for even parity and `1` for odd.
impl From < Parity > for u8 {
2022-11-16 00:06:12 +00:00
fn from ( parity : Parity ) -> u8 { parity . to_u8 ( ) }
2022-02-10 22:50:02 +00:00
}
2022-02-09 14:33:25 +00:00
/// Returns even parity if the operands are equal, odd otherwise.
2022-01-19 05:20:07 +00:00
impl BitXor for Parity {
type Output = Parity ;
fn bitxor ( self , rhs : Parity ) -> Self ::Output {
// This works because Parity has only two values (i.e. only 1 bit of information).
if self = = rhs {
2022-11-16 00:06:12 +00:00
Parity ::Even // 1^1==0 and 0^0==0
2022-01-19 05:20:07 +00:00
} else {
2022-11-16 00:06:12 +00:00
Parity ::Odd // 1^0==1 and 0^1==1
2022-01-19 05:20:07 +00:00
}
2022-01-03 21:49:08 +00:00
}
}
2022-02-10 22:50:02 +00:00
/// Error returned when conversion from an integer to `Parity` fails.
//
// Note that we don't allow inspecting the value because we may change the type.
// Yes, this comment is intentionally NOT doc comment.
// Too many derives for compatibility with current Error type.
#[ derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd) ]
pub struct InvalidParityValue ( i32 ) ;
impl fmt ::Display for InvalidParityValue {
fn fmt ( & self , f : & mut fmt ::Formatter ) -> fmt ::Result {
write! ( f , " invalid value {} for Parity - must be 0 or 1 " , self . 0 )
}
}
#[ cfg(feature = " std " ) ]
#[ cfg_attr(docsrs, doc(cfg(feature = " std " ))) ]
2021-09-14 09:18:22 +00:00
impl std ::error ::Error for InvalidParityValue { }
2022-02-10 22:50:02 +00:00
impl From < InvalidParityValue > for Error {
2022-11-16 00:06:12 +00:00
fn from ( error : InvalidParityValue ) -> Self { Error ::InvalidParityValue ( error ) }
2022-02-10 22:50:02 +00:00
}
2022-02-09 19:35:06 +00:00
/// The parity is serialized as `u8` - `0` for even, `1` for odd.
2022-01-06 17:17:26 +00:00
#[ cfg(feature = " serde " ) ]
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl serde ::Serialize for Parity {
fn serialize < S : serde ::Serializer > ( & self , s : S ) -> Result < S ::Ok , S ::Error > {
2022-02-09 19:35:06 +00:00
s . serialize_u8 ( self . to_u8 ( ) )
2022-01-06 17:17:26 +00:00
}
}
2022-02-09 19:35:06 +00:00
/// The parity is deserialized as `u8` - `0` for even, `1` for odd.
2022-01-06 17:17:26 +00:00
#[ cfg(feature = " serde " ) ]
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl < ' de > serde ::Deserialize < ' de > for Parity {
fn deserialize < D : serde ::Deserializer < ' de > > ( d : D ) -> Result < Self , D ::Error > {
2022-02-09 19:35:06 +00:00
struct Visitor ;
2022-01-06 17:17:26 +00:00
2022-11-16 00:06:12 +00:00
impl < ' de > serde ::de ::Visitor < ' de > for Visitor {
2022-01-06 17:17:26 +00:00
type Value = Parity ;
fn expecting ( & self , formatter : & mut fmt ::Formatter ) -> fmt ::Result {
2022-02-09 19:35:06 +00:00
formatter . write_str ( " 8-bit integer (byte) with value 0 or 1 " )
2022-01-06 17:17:26 +00:00
}
2022-02-09 19:35:06 +00:00
fn visit_u8 < E > ( self , v : u8 ) -> Result < Self ::Value , E >
2022-11-16 00:06:12 +00:00
where
E : serde ::de ::Error ,
2022-01-06 17:17:26 +00:00
{
2022-02-09 19:25:29 +00:00
use serde ::de ::Unexpected ;
2022-02-09 19:35:06 +00:00
Parity ::from_u8 ( v )
. map_err ( | _ | E ::invalid_value ( Unexpected ::Unsigned ( v . into ( ) ) , & " 0 or 1 " ) )
2022-01-06 17:17:26 +00:00
}
}
2022-02-09 19:35:06 +00:00
d . deserialize_u8 ( Visitor )
2022-01-06 17:17:26 +00:00
}
}
2021-09-09 09:41:11 +00:00
impl CPtr for XOnlyPublicKey {
type Target = ffi ::XOnlyPublicKey ;
2022-11-16 00:06:12 +00:00
fn as_c_ptr ( & self ) -> * const Self ::Target { & self . 0 }
2021-09-09 09:41:11 +00:00
2022-11-16 00:06:12 +00:00
fn as_mut_c_ptr ( & mut self ) -> * mut Self ::Target { & mut self . 0 }
2021-09-09 09:41:11 +00:00
}
2022-01-13 07:57:11 +00:00
/// Creates a new Schnorr public key from a FFI x-only public key.
2021-09-09 09:41:11 +00:00
impl From < ffi ::XOnlyPublicKey > for XOnlyPublicKey {
#[ inline ]
2022-11-16 00:06:12 +00:00
fn from ( pk : ffi ::XOnlyPublicKey ) -> XOnlyPublicKey { XOnlyPublicKey ( pk ) }
2021-09-09 09:41:11 +00:00
}
2021-09-14 09:18:22 +00:00
impl From < PublicKey > for XOnlyPublicKey {
fn from ( src : PublicKey ) -> XOnlyPublicKey {
2021-09-09 09:41:11 +00:00
unsafe {
let mut pk = ffi ::XOnlyPublicKey ::new ( ) ;
assert_eq! (
1 ,
ffi ::secp256k1_xonly_pubkey_from_pubkey (
ffi ::secp256k1_context_no_precomp ,
& mut pk ,
ptr ::null_mut ( ) ,
src . as_c_ptr ( ) ,
)
) ;
XOnlyPublicKey ( pk )
}
}
}
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl serde ::Serialize for XOnlyPublicKey {
fn serialize < S : serde ::Serializer > ( & self , s : S ) -> Result < S ::Ok , S ::Error > {
2021-09-09 09:41:11 +00:00
if s . is_human_readable ( ) {
s . collect_str ( self )
} else {
2022-03-01 18:20:56 +00:00
let mut tuple = s . serialize_tuple ( constants ::SCHNORR_PUBLIC_KEY_SIZE ) ? ;
for byte in self . serialize ( ) . iter ( ) {
tuple . serialize_element ( & byte ) ? ;
}
tuple . end ( )
2021-09-09 09:41:11 +00:00
}
}
}
#[ cfg(feature = " serde " ) ]
2022-01-04 15:55:01 +00:00
#[ cfg_attr(docsrs, doc(cfg(feature = " serde " ))) ]
2021-09-14 09:18:22 +00:00
impl < ' de > serde ::Deserialize < ' de > for XOnlyPublicKey {
fn deserialize < D : serde ::Deserializer < ' de > > ( d : D ) -> Result < Self , D ::Error > {
2021-09-09 09:41:11 +00:00
if d . is_human_readable ( ) {
d . deserialize_str ( super ::serde_util ::FromStrVisitor ::new (
2022-11-16 00:06:12 +00:00
" a hex string representing 32 byte schnorr public key " ,
2021-09-09 09:41:11 +00:00
) )
} else {
2022-03-01 18:20:56 +00:00
let visitor = super ::serde_util ::Tuple32Visitor ::new (
2021-09-09 09:41:11 +00:00
" raw 32 bytes schnorr public key " ,
2022-11-16 00:06:12 +00:00
XOnlyPublicKey ::from_slice ,
2022-03-01 18:20:56 +00:00
) ;
d . deserialize_tuple ( constants ::SCHNORR_PUBLIC_KEY_SIZE , visitor )
2021-09-09 09:41:11 +00:00
}
}
}
2022-01-18 15:56:17 +00:00
/// Serde implementation for the [`KeyPair`] type.
///
/// Only the secret key part of the [`KeyPair`] is serialized using the [`SecretKey`] serde
/// implementation, meaning the public key has to be regenerated on deserialization.
///
/// **Attention:** The deserialization algorithm uses the [global context] to generate the public key
/// belonging to the secret key to form a [`KeyPair`]. The typical caveats regarding use of the
/// [global context] with secret data apply.
///
/// [`SecretKey`]: crate::SecretKey
/// [global context]: crate::SECP256K1
2022-02-01 04:43:46 +00:00
#[ cfg(all(feature = " global-context " , feature = " serde " )) ]
2022-01-18 15:56:17 +00:00
pub mod serde_keypair {
use serde ::{ Deserialize , Deserializer , Serialize , Serializer } ;
2022-11-16 00:06:12 +00:00
2021-09-14 09:18:22 +00:00
use crate ::key ::{ KeyPair , SecretKey } ;
2022-01-18 15:56:17 +00:00
#[ allow(missing_docs) ]
pub fn serialize < S > ( key : & KeyPair , serializer : S ) -> Result < S ::Ok , S ::Error >
2022-11-16 00:06:12 +00:00
where
S : Serializer ,
2022-01-18 15:56:17 +00:00
{
SecretKey ::from_keypair ( key ) . serialize ( serializer )
}
#[ allow(missing_docs) ]
pub fn deserialize < ' de , D > ( deserializer : D ) -> Result < KeyPair , D ::Error >
2022-11-16 00:06:12 +00:00
where
D : Deserializer < ' de > ,
2022-01-18 15:56:17 +00:00
{
let secret_key = SecretKey ::deserialize ( deserializer ) ? ;
2022-11-16 00:06:12 +00:00
Ok ( KeyPair ::from_secret_key ( crate ::SECP256K1 , & secret_key ) )
2022-01-18 15:56:17 +00:00
}
}
2014-08-10 01:46:38 +00:00
#[ cfg(test) ]
2022-02-01 02:43:42 +00:00
#[ allow(unused_imports) ]
2014-08-10 01:46:38 +00:00
mod test {
2022-02-01 02:43:42 +00:00
use core ::str ::FromStr ;
2014-08-10 02:02:09 +00:00
2022-11-16 00:06:12 +00:00
use bitcoin_hashes ::hex ::ToHex ;
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2022-11-16 00:06:12 +00:00
use rand ::{ rngs ::mock ::StepRng , thread_rng , Error , RngCore } ;
2022-10-21 18:35:59 +00:00
use serde_test ::{ Configure , Token } ;
2020-12-21 23:27:55 +00:00
#[ cfg(target_arch = " wasm32 " ) ]
use wasm_bindgen_test ::wasm_bindgen_test as test ;
2022-11-16 00:06:12 +00:00
use super ::{ KeyPair , Parity , PublicKey , Secp256k1 , SecretKey , XOnlyPublicKey , * } ;
2021-09-14 09:18:22 +00:00
use crate ::Error ::{ InvalidPublicKey , InvalidSecretKey } ;
2022-11-16 00:06:12 +00:00
use crate ::{ constants , from_hex , to_hex , Scalar } ;
2021-09-14 09:18:22 +00:00
2022-06-29 01:11:39 +00:00
#[ cfg(not(fuzzing)) ]
2018-03-21 22:01:08 +00:00
macro_rules ! hex {
2022-11-16 00:06:12 +00:00
( $hex :expr ) = > { {
2018-08-26 18:39:41 +00:00
let mut result = vec! [ 0 ; $hex . len ( ) / 2 ] ;
from_hex ( $hex , & mut result ) . expect ( " valid hex string " ) ;
result
2022-11-16 00:06:12 +00:00
} } ;
2018-03-21 22:01:08 +00:00
}
2017-12-21 00:59:22 +00:00
2014-08-10 02:02:09 +00:00
#[ test ]
fn skey_from_slice ( ) {
2018-11-06 21:57:52 +00:00
let sk = SecretKey ::from_slice ( & [ 1 ; 31 ] ) ;
2014-09-12 13:28:35 +00:00
assert_eq! ( sk , Err ( InvalidSecretKey ) ) ;
2018-11-06 21:57:52 +00:00
let sk = SecretKey ::from_slice ( & [ 1 ; 32 ] ) ;
2014-09-12 13:28:35 +00:00
assert! ( sk . is_ok ( ) ) ;
2014-08-10 02:02:09 +00:00
}
#[ test ]
fn pubkey_from_slice ( ) {
2018-11-06 21:57:52 +00:00
assert_eq! ( PublicKey ::from_slice ( & [ ] ) , Err ( InvalidPublicKey ) ) ;
assert_eq! ( PublicKey ::from_slice ( & [ 1 , 2 , 3 ] ) , Err ( InvalidPublicKey ) ) ;
2014-08-10 01:46:38 +00:00
2022-11-16 00:06:12 +00:00
let uncompressed = PublicKey ::from_slice ( & [
4 , 54 , 57 , 149 , 239 , 162 , 148 , 175 , 246 , 254 , 239 , 75 , 154 , 152 , 10 , 82 , 234 , 224 , 85 ,
220 , 40 , 100 , 57 , 121 , 30 , 162 , 94 , 156 , 135 , 67 , 74 , 49 , 179 , 57 , 236 , 53 , 162 , 124 ,
149 , 144 , 168 , 77 , 74 , 30 , 72 , 211 , 229 , 110 , 111 , 55 , 96 , 193 , 86 , 227 , 183 , 152 , 195 ,
155 , 51 , 247 , 123 , 113 , 60 , 228 , 188 ,
] ) ;
2014-08-10 01:46:38 +00:00
assert! ( uncompressed . is_ok ( ) ) ;
2022-11-16 00:06:12 +00:00
let compressed = PublicKey ::from_slice ( & [
3 , 23 , 183 , 225 , 206 , 31 , 159 , 148 , 195 , 42 , 67 , 115 , 146 , 41 , 248 , 140 , 11 , 3 , 51 , 41 ,
111 , 180 , 110 , 143 , 114 , 134 , 88 , 73 , 198 , 174 , 52 , 184 , 78 ,
] ) ;
2014-08-10 01:46:38 +00:00
assert! ( compressed . is_ok ( ) ) ;
}
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2014-08-10 01:46:38 +00:00
fn keypair_slice_round_trip ( ) {
2015-04-12 20:54:22 +00:00
let s = Secp256k1 ::new ( ) ;
2014-08-10 01:46:38 +00:00
2018-06-03 09:08:09 +00:00
let ( sk1 , pk1 ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
2018-11-06 21:57:52 +00:00
assert_eq! ( SecretKey ::from_slice ( & sk1 [ .. ] ) , Ok ( sk1 ) ) ;
assert_eq! ( PublicKey ::from_slice ( & pk1 . serialize ( ) [ .. ] ) , Ok ( pk1 ) ) ;
assert_eq! ( PublicKey ::from_slice ( & pk1 . serialize_uncompressed ( ) [ .. ] ) , Ok ( pk1 ) ) ;
2014-08-10 01:46:38 +00:00
}
2014-08-10 02:02:09 +00:00
2014-08-24 23:13:08 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2014-08-24 23:13:08 +00:00
fn invalid_secret_key ( ) {
// Zero
2018-11-06 21:57:52 +00:00
assert_eq! ( SecretKey ::from_slice ( & [ 0 ; 32 ] ) , Err ( InvalidSecretKey ) ) ;
2021-04-26 05:43:54 +00:00
assert_eq! (
2022-01-06 22:01:01 +00:00
SecretKey ::from_str ( " 0000000000000000000000000000000000000000000000000000000000000000 " ) ,
2021-04-26 05:43:54 +00:00
Err ( InvalidSecretKey )
) ;
2014-08-24 23:13:08 +00:00
// -1
2018-11-06 21:57:52 +00:00
assert_eq! ( SecretKey ::from_slice ( & [ 0xff ; 32 ] ) , Err ( InvalidSecretKey ) ) ;
2014-08-24 23:13:08 +00:00
// Top of range
2018-11-06 21:57:52 +00:00
assert! ( SecretKey ::from_slice ( & [
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE ,
0xBA , 0xAE , 0xDC , 0xE6 , 0xAF , 0x48 , 0xA0 , 0x3B ,
0xBF , 0xD2 , 0x5E , 0x8C , 0xD0 , 0x36 , 0x41 , 0x40 ,
] ) . is_ok ( ) ) ;
2014-08-24 23:13:08 +00:00
// One past top of range
2018-11-06 21:57:52 +00:00
assert! ( SecretKey ::from_slice ( & [
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE ,
0xBA , 0xAE , 0xDC , 0xE6 , 0xAF , 0x48 , 0xA0 , 0x3B ,
0xBF , 0xD2 , 0x5E , 0x8C , 0xD0 , 0x36 , 0x41 , 0x41 ,
] ) . is_err ( ) ) ;
2014-08-24 23:13:08 +00:00
}
2014-08-28 16:16:53 +00:00
2015-04-12 15:51:15 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2015-04-12 15:51:15 +00:00
fn test_out_of_range ( ) {
struct BadRng ( u8 ) ;
2019-01-11 20:57:34 +00:00
impl RngCore for BadRng {
2015-04-12 15:51:15 +00:00
fn next_u32 ( & mut self ) -> u32 { unimplemented! ( ) }
2019-01-11 20:57:34 +00:00
fn next_u64 ( & mut self ) -> u64 { unimplemented! ( ) }
2015-04-12 15:51:15 +00:00
// This will set a secret key to a little over the
// group order, then decrement with repeated calls
// until it returns a valid key
fn fill_bytes ( & mut self , data : & mut [ u8 ] ) {
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2015-04-12 15:51:15 +00:00
let group_order : [ u8 ; 32 ] = [
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xfe ,
0xba , 0xae , 0xdc , 0xe6 , 0xaf , 0x48 , 0xa0 , 0x3b ,
0xbf , 0xd2 , 0x5e , 0x8c , 0xd0 , 0x36 , 0x41 , 0x41 ] ;
assert_eq! ( data . len ( ) , 32 ) ;
2017-05-08 11:18:35 +00:00
data . copy_from_slice ( & group_order [ .. ] ) ;
2015-04-12 15:51:15 +00:00
data [ 31 ] = self . 0 ;
self . 0 - = 1 ;
}
2019-01-11 20:57:34 +00:00
fn try_fill_bytes ( & mut self , dest : & mut [ u8 ] ) -> Result < ( ) , Error > {
2020-12-22 02:45:19 +00:00
self . fill_bytes ( dest ) ;
Ok ( ( ) )
2019-01-11 20:57:34 +00:00
}
2015-04-12 15:51:15 +00:00
}
2015-04-12 20:54:22 +00:00
let s = Secp256k1 ::new ( ) ;
2018-06-03 09:08:09 +00:00
s . generate_keypair ( & mut BadRng ( 0xff ) ) ;
2015-04-12 15:51:15 +00:00
}
#[ test ]
fn test_pubkey_from_bad_slice ( ) {
// Bad sizes
2018-11-06 21:57:52 +00:00
assert_eq! (
PublicKey ::from_slice ( & [ 0 ; constants ::PUBLIC_KEY_SIZE - 1 ] ) ,
Err ( InvalidPublicKey )
) ;
assert_eq! (
PublicKey ::from_slice ( & [ 0 ; constants ::PUBLIC_KEY_SIZE + 1 ] ) ,
Err ( InvalidPublicKey )
) ;
assert_eq! (
PublicKey ::from_slice ( & [ 0 ; constants ::UNCOMPRESSED_PUBLIC_KEY_SIZE - 1 ] ) ,
Err ( InvalidPublicKey )
) ;
assert_eq! (
PublicKey ::from_slice ( & [ 0 ; constants ::UNCOMPRESSED_PUBLIC_KEY_SIZE + 1 ] ) ,
Err ( InvalidPublicKey )
) ;
2015-04-12 15:51:15 +00:00
// Bad parse
2018-11-06 21:57:52 +00:00
assert_eq! (
PublicKey ::from_slice ( & [ 0xff ; constants ::UNCOMPRESSED_PUBLIC_KEY_SIZE ] ) ,
Err ( InvalidPublicKey )
) ;
assert_eq! (
PublicKey ::from_slice ( & [ 0x55 ; constants ::PUBLIC_KEY_SIZE ] ) ,
Err ( InvalidPublicKey )
) ;
2022-11-16 00:06:12 +00:00
assert_eq! ( PublicKey ::from_slice ( & [ ] ) , Err ( InvalidPublicKey ) ) ;
2019-08-21 21:58:55 +00:00
}
#[ test ]
fn test_seckey_from_bad_slice ( ) {
// Bad sizes
assert_eq! (
SecretKey ::from_slice ( & [ 0 ; constants ::SECRET_KEY_SIZE - 1 ] ) ,
Err ( InvalidSecretKey )
) ;
assert_eq! (
SecretKey ::from_slice ( & [ 0 ; constants ::SECRET_KEY_SIZE + 1 ] ) ,
Err ( InvalidSecretKey )
) ;
// Bad parse
assert_eq! (
SecretKey ::from_slice ( & [ 0xff ; constants ::SECRET_KEY_SIZE ] ) ,
Err ( InvalidSecretKey )
) ;
assert_eq! (
SecretKey ::from_slice ( & [ 0x00 ; constants ::SECRET_KEY_SIZE ] ) ,
Err ( InvalidSecretKey )
) ;
2022-11-16 00:06:12 +00:00
assert_eq! ( SecretKey ::from_slice ( & [ ] ) , Err ( InvalidSecretKey ) ) ;
2015-04-12 15:51:15 +00:00
}
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(all(feature = " rand " , any(feature = " alloc " , feature = " std " ))) ]
2015-04-12 15:51:15 +00:00
fn test_debug_output ( ) {
2015-04-12 20:54:22 +00:00
let s = Secp256k1 ::new ( ) ;
2021-09-14 10:36:50 +00:00
let ( sk , _ ) = s . generate_keypair ( & mut StepRng ::new ( 1 , 1 ) ) ;
2015-04-12 15:51:15 +00:00
2022-11-16 00:06:12 +00:00
assert_eq! ( & format! ( " {:?} " , sk ) , " SecretKey(#d3e0c51a23169bb5) " ) ;
2021-08-09 15:06:05 +00:00
let mut buf = [ 0 u8 ; constants ::SECRET_KEY_SIZE * 2 ] ;
2022-11-16 00:06:12 +00:00
assert_eq! (
to_hex ( & sk [ .. ] , & mut buf ) . unwrap ( ) ,
" 0100000000000000020000000000000003000000000000000400000000000000 "
) ;
2015-07-28 16:03:10 +00:00
}
2018-08-15 20:40:15 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2018-08-15 20:40:15 +00:00
fn test_display_output ( ) {
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2018-08-15 20:40:15 +00:00
static SK_BYTES : [ u8 ; 32 ] = [
0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 ,
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0xff , 0xff , 0x00 , 0x00 , 0xff , 0xff , 0x00 , 0x00 ,
0x63 , 0x63 , 0x63 , 0x63 , 0x63 , 0x63 , 0x63 , 0x63 ,
] ;
2022-02-01 01:49:07 +00:00
#[ cfg(not(fuzzing)) ]
2018-08-15 20:40:15 +00:00
let s = Secp256k1 ::signing_only ( ) ;
2018-11-06 21:57:52 +00:00
let sk = SecretKey ::from_slice ( & SK_BYTES ) . expect ( " sk " ) ;
2021-02-18 14:50:58 +00:00
// In fuzzing mode secret->public key derivation is different, so
2022-02-02 21:36:36 +00:00
// hard-code the expected result.
2021-02-18 14:50:58 +00:00
#[ cfg(not(fuzzing)) ]
2018-08-15 20:40:15 +00:00
let pk = PublicKey ::from_secret_key ( & s , & sk ) ;
2021-02-18 14:50:58 +00:00
#[ cfg(fuzzing) ]
2022-11-16 00:06:12 +00:00
let pk = PublicKey ::from_slice ( & [
0x02 , 0x18 , 0x84 , 0x57 , 0x81 , 0xf6 , 0x31 , 0xc4 , 0x8f , 0x1c , 0x97 , 0x09 , 0xe2 , 0x30 ,
0x92 , 0x06 , 0x7d , 0x06 , 0x83 , 0x7f , 0x30 , 0xaa , 0x0c , 0xd0 , 0x54 , 0x4a , 0xc8 , 0x87 ,
0xfe , 0x91 , 0xdd , 0xd1 , 0x66 ,
] )
. expect ( " pk " ) ;
2018-08-15 20:40:15 +00:00
assert_eq! (
2021-08-09 15:06:05 +00:00
sk . display_secret ( ) . to_string ( ) ,
2018-08-15 20:40:15 +00:00
" 01010101010101010001020304050607ffff0000ffff00006363636363636363 "
) ;
2018-08-26 18:39:41 +00:00
assert_eq! (
2022-11-16 00:06:12 +00:00
SecretKey ::from_str ( " 01010101010101010001020304050607ffff0000ffff00006363636363636363 " )
. unwrap ( ) ,
2018-08-26 18:39:41 +00:00
sk
) ;
2018-08-15 20:40:15 +00:00
assert_eq! (
pk . to_string ( ) ,
" 0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166 "
) ;
2018-08-26 18:39:41 +00:00
assert_eq! (
2022-11-16 00:06:12 +00:00
PublicKey ::from_str (
" 0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166 "
)
. unwrap ( ) ,
2018-08-26 18:39:41 +00:00
pk
) ;
assert_eq! (
2022-11-16 00:06:12 +00:00
PublicKey ::from_str (
" 04 \
2018-08-26 18:39:41 +00:00
18845781 f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166 \
84 B84DB303A340CD7D6823EE88174747D12A67D2F8F2F9BA40846EE5EE7A44F6 "
2022-11-16 00:06:12 +00:00
)
. unwrap ( ) ,
2018-08-26 18:39:41 +00:00
pk
) ;
2022-11-16 00:06:12 +00:00
assert! ( SecretKey ::from_str (
" fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff "
)
. is_err ( ) ) ;
assert! ( SecretKey ::from_str (
" 01010101010101010001020304050607ffff0000ffff0000636363636363636363 "
)
. is_err ( ) ) ;
assert! ( SecretKey ::from_str (
" 01010101010101010001020304050607ffff0000ffff0000636363636363636 "
)
. is_err ( ) ) ;
assert! ( SecretKey ::from_str (
" 01010101010101010001020304050607ffff0000ffff000063636363636363 "
)
. is_err ( ) ) ;
assert! ( SecretKey ::from_str (
" 01010101010101010001020304050607ffff0000ffff000063636363636363xx "
)
. is_err ( ) ) ;
assert! ( PublicKey ::from_str (
" 0300000000000000000000000000000000000000000000000000000000000000000 "
)
. is_err ( ) ) ;
assert! ( PublicKey ::from_str (
" 0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601 "
)
. is_err ( ) ) ;
assert! ( PublicKey ::from_str (
" 0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16 "
)
. is_err ( ) ) ;
assert! ( PublicKey ::from_str (
" 0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1 "
)
. is_err ( ) ) ;
assert! ( PublicKey ::from_str (
" xx0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1 "
)
. is_err ( ) ) ;
2018-08-26 18:39:41 +00:00
2022-06-10 02:52:17 +00:00
let long_str = " a " . repeat ( 1024 * 1024 ) ;
2018-08-26 18:39:41 +00:00
assert! ( SecretKey ::from_str ( & long_str ) . is_err ( ) ) ;
assert! ( PublicKey ::from_str ( & long_str ) . is_err ( ) ) ;
2018-08-15 20:40:15 +00:00
}
2015-07-28 16:03:10 +00:00
#[ test ]
2021-02-18 14:50:58 +00:00
// In fuzzing mode the Y coordinate is expected to match the X, so this
// test uses invalid public keys.
#[ cfg(not(fuzzing)) ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2015-07-28 16:03:10 +00:00
fn test_pubkey_serialize ( ) {
let s = Secp256k1 ::new ( ) ;
2022-11-16 00:06:12 +00:00
let ( _ , pk1 ) = s . generate_keypair ( & mut StepRng ::new ( 1 , 1 ) ) ;
assert_eq! (
& pk1 . serialize_uncompressed ( ) [ .. ] ,
& [
4 , 124 , 121 , 49 , 14 , 253 , 63 , 197 , 50 , 39 , 194 , 107 , 17 , 193 , 219 , 108 , 154 , 126 ,
9 , 181 , 248 , 2 , 12 , 149 , 233 , 198 , 71 , 149 , 134 , 250 , 184 , 154 , 229 , 185 , 28 , 165 ,
110 , 27 , 3 , 162 , 126 , 238 , 167 , 157 , 242 , 221 , 76 , 251 , 237 , 34 , 231 , 72 , 39 , 245 ,
3 , 191 , 64 , 111 , 170 , 117 , 103 , 82 , 28 , 102 , 163
] [ .. ]
) ;
assert_eq! (
& pk1 . serialize ( ) [ .. ] ,
& [
3 , 124 , 121 , 49 , 14 , 253 , 63 , 197 , 50 , 39 , 194 , 107 , 17 , 193 , 219 , 108 , 154 , 126 ,
9 , 181 , 248 , 2 , 12 , 149 , 233 , 198 , 71 , 149 , 134 , 250 , 184 , 154 , 229
] [ .. ]
) ;
2015-04-12 15:51:15 +00:00
}
2014-08-28 16:16:53 +00:00
#[ test ]
2022-04-06 04:05:04 +00:00
#[ cfg(feature = " rand-std " ) ]
fn tweak_add_arbitrary_data ( ) {
2015-04-12 20:54:22 +00:00
let s = Secp256k1 ::new ( ) ;
2014-08-28 16:16:53 +00:00
2022-04-06 04:05:04 +00:00
let ( sk , pk ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
assert_eq! ( PublicKey ::from_secret_key ( & s , & sk ) , pk ) ; // Sanity check.
2014-08-28 16:16:53 +00:00
2022-04-06 04:05:04 +00:00
// TODO: This would be better tested with a _lot_ of different tweaks.
let tweak = Scalar ::random ( ) ;
2014-08-28 17:59:44 +00:00
2022-04-06 04:05:04 +00:00
let tweaked_sk = sk . add_tweak ( & tweak ) . unwrap ( ) ;
assert_ne! ( sk , tweaked_sk ) ; // Make sure we did something.
let tweaked_pk = pk . add_exp_tweak ( & s , & tweak ) . unwrap ( ) ;
assert_ne! ( pk , tweaked_pk ) ;
2014-08-28 17:59:44 +00:00
2022-04-06 04:05:04 +00:00
assert_eq! ( PublicKey ::from_secret_key ( & s , & tweaked_sk ) , tweaked_pk ) ;
2014-08-28 16:16:53 +00:00
}
2016-01-09 03:45:20 +00:00
2016-08-20 17:00:39 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2022-04-06 04:05:04 +00:00
fn tweak_add_zero ( ) {
2016-08-20 17:00:39 +00:00
let s = Secp256k1 ::new ( ) ;
2022-04-06 04:05:04 +00:00
let ( sk , pk ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
2016-08-20 17:00:39 +00:00
2022-04-06 04:05:04 +00:00
let tweak = Scalar ::ZERO ;
2016-08-20 17:00:39 +00:00
2022-04-06 04:05:04 +00:00
let tweaked_sk = sk . add_tweak ( & tweak ) . unwrap ( ) ;
assert_eq! ( sk , tweaked_sk ) ; // Tweak by zero does nothing.
let tweaked_pk = pk . add_exp_tweak ( & s , & tweak ) . unwrap ( ) ;
assert_eq! ( pk , tweaked_pk ) ;
2016-08-20 17:00:39 +00:00
}
2020-02-07 04:31:43 +00:00
#[ test ]
2022-04-06 04:05:04 +00:00
#[ cfg(feature = " rand-std " ) ]
fn tweak_mul_arbitrary_data ( ) {
2016-08-20 17:00:39 +00:00
let s = Secp256k1 ::new ( ) ;
2022-04-06 04:05:04 +00:00
let ( sk , pk ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
assert_eq! ( PublicKey ::from_secret_key ( & s , & sk ) , pk ) ; // Sanity check.
2016-08-20 17:00:39 +00:00
2022-04-06 04:05:04 +00:00
// TODO: This would be better tested with a _lot_ of different tweaks.
let tweak = Scalar ::random ( ) ;
2016-08-20 17:00:39 +00:00
2022-04-06 04:05:04 +00:00
let tweaked_sk = sk . mul_tweak ( & tweak ) . unwrap ( ) ;
assert_ne! ( sk , tweaked_sk ) ; // Make sure we did something.
let tweaked_pk = pk . mul_tweak ( & s , & tweak ) . unwrap ( ) ;
assert_ne! ( pk , tweaked_pk ) ;
assert_eq! ( PublicKey ::from_secret_key ( & s , & tweaked_sk ) , tweaked_pk ) ;
2016-08-20 17:00:39 +00:00
}
2020-02-07 04:31:43 +00:00
#[ test ]
2022-04-06 04:05:04 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
fn tweak_mul_zero ( ) {
let s = Secp256k1 ::new ( ) ;
let ( sk , _ ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
let tweak = Scalar ::ZERO ;
assert! ( sk . mul_tweak ( & tweak ) . is_err ( ) )
}
2022-11-16 00:06:12 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2020-02-07 04:31:43 +00:00
fn test_negation ( ) {
let s = Secp256k1 ::new ( ) ;
2022-04-06 04:39:15 +00:00
let ( sk , pk ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
assert_eq! ( PublicKey ::from_secret_key ( & s , & sk ) , pk ) ; // Sanity check.
let neg = sk . negate ( ) ;
assert_ne! ( sk , neg ) ;
let back_sk = neg . negate ( ) ;
assert_eq! ( sk , back_sk ) ;
2020-02-07 04:31:43 +00:00
2022-04-06 04:39:15 +00:00
let neg = pk . negate ( & s ) ;
assert_ne! ( pk , neg ) ;
let back_pk = neg . negate ( & s ) ;
assert_eq! ( pk , back_pk ) ;
2020-02-07 04:31:43 +00:00
2022-04-06 04:39:15 +00:00
assert_eq! ( PublicKey ::from_secret_key ( & s , & back_sk ) , pk ) ;
2020-02-07 04:31:43 +00:00
}
2016-01-09 03:45:20 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2016-01-09 03:45:20 +00:00
fn pubkey_hash ( ) {
2017-04-27 19:46:28 +00:00
use std ::collections ::hash_map ::DefaultHasher ;
2016-01-09 03:45:20 +00:00
use std ::collections ::HashSet ;
2022-11-16 00:06:12 +00:00
use std ::hash ::{ Hash , Hasher } ;
2016-01-09 03:45:20 +00:00
fn hash < T : Hash > ( t : & T ) -> u64 {
2017-04-27 19:46:28 +00:00
let mut s = DefaultHasher ::new ( ) ;
2016-01-09 03:45:20 +00:00
t . hash ( & mut s ) ;
s . finish ( )
}
let s = Secp256k1 ::new ( ) ;
let mut set = HashSet ::new ( ) ;
2022-11-16 00:06:12 +00:00
const COUNT : usize = 1024 ;
2020-12-22 03:02:31 +00:00
for _ in 0 .. COUNT {
2018-06-03 09:08:09 +00:00
let ( _ , pk ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
2016-01-09 03:45:20 +00:00
let hash = hash ( & pk ) ;
assert! ( ! set . contains ( & hash ) ) ;
set . insert ( hash ) ;
2022-11-16 00:06:12 +00:00
}
2020-12-22 03:02:31 +00:00
assert_eq! ( set . len ( ) , COUNT ) ;
2016-01-09 03:45:20 +00:00
}
2017-12-21 00:59:22 +00:00
2022-02-01 01:49:07 +00:00
#[ test ]
#[ cfg(not(fuzzing)) ]
2018-08-22 20:18:25 +00:00
fn pubkey_combine ( ) {
2022-11-16 00:06:12 +00:00
let compressed1 = PublicKey ::from_slice ( & hex! (
" 0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba "
) )
. unwrap ( ) ;
let compressed2 = PublicKey ::from_slice ( & hex! (
" 02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443 "
) )
. unwrap ( ) ;
let exp_sum = PublicKey ::from_slice ( & hex! (
" 0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07 "
) )
. unwrap ( ) ;
2018-08-22 20:18:25 +00:00
2018-11-06 21:57:52 +00:00
let sum1 = compressed1 . combine ( & compressed2 ) ;
2018-08-22 20:18:25 +00:00
assert! ( sum1 . is_ok ( ) ) ;
2018-11-06 21:57:52 +00:00
let sum2 = compressed2 . combine ( & compressed1 ) ;
2018-08-22 20:18:25 +00:00
assert! ( sum2 . is_ok ( ) ) ;
assert_eq! ( sum1 , sum2 ) ;
assert_eq! ( sum1 . unwrap ( ) , exp_sum ) ;
}
2022-02-01 01:49:07 +00:00
#[ test ]
#[ cfg(not(fuzzing)) ]
2021-03-31 01:07:20 +00:00
fn pubkey_combine_keys ( ) {
2022-11-16 00:06:12 +00:00
let compressed1 = PublicKey ::from_slice ( & hex! (
" 0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba "
) )
. unwrap ( ) ;
let compressed2 = PublicKey ::from_slice ( & hex! (
" 02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443 "
) )
. unwrap ( ) ;
let compressed3 = PublicKey ::from_slice ( & hex! (
" 03e74897d8644eb3e5b391ca2ab257aec2080f4d1a95cad57e454e47f021168eb0 "
) )
. unwrap ( ) ;
let exp_sum = PublicKey ::from_slice ( & hex! (
" 0252d73a47f66cf341e5651542f0348f452b7c793af62a6d8bff75ade703a451ad "
) )
. unwrap ( ) ;
2021-03-31 01:07:20 +00:00
let sum1 = PublicKey ::combine_keys ( & [ & compressed1 , & compressed2 , & compressed3 ] ) ;
assert! ( sum1 . is_ok ( ) ) ;
let sum2 = PublicKey ::combine_keys ( & [ & compressed1 , & compressed2 , & compressed3 ] ) ;
assert! ( sum2 . is_ok ( ) ) ;
assert_eq! ( sum1 , sum2 ) ;
assert_eq! ( sum1 . unwrap ( ) , exp_sum ) ;
2018-08-22 20:18:25 +00:00
}
2022-02-01 01:49:07 +00:00
#[ test ]
#[ cfg(not(fuzzing)) ]
2021-06-10 12:06:48 +00:00
fn pubkey_combine_keys_empty_slice ( ) {
assert! ( PublicKey ::combine_keys ( & [ ] ) . is_err ( ) ) ;
}
2021-02-18 14:50:58 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2021-02-18 14:50:58 +00:00
fn create_pubkey_combine ( ) {
let s = Secp256k1 ::new ( ) ;
2022-04-06 04:05:04 +00:00
let ( sk1 , pk1 ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
2021-02-18 14:50:58 +00:00
let ( sk2 , pk2 ) = s . generate_keypair ( & mut thread_rng ( ) ) ;
let sum1 = pk1 . combine ( & pk2 ) ;
assert! ( sum1 . is_ok ( ) ) ;
let sum2 = pk2 . combine ( & pk1 ) ;
assert! ( sum2 . is_ok ( ) ) ;
assert_eq! ( sum1 , sum2 ) ;
2022-04-06 04:05:04 +00:00
let tweaked = sk1 . add_tweak ( & Scalar ::from ( sk2 ) ) . unwrap ( ) ;
let sksum = PublicKey ::from_secret_key ( & s , & tweaked ) ;
2021-02-18 14:50:58 +00:00
assert_eq! ( Ok ( sksum ) , sum1 ) ;
}
2021-06-29 11:19:18 +00:00
#[ cfg(not(fuzzing)) ]
2018-05-29 11:11:18 +00:00
#[ test ]
2022-06-10 02:57:30 +00:00
#[ allow(clippy::nonminimal_bool) ]
2018-05-29 11:11:18 +00:00
fn pubkey_equal ( ) {
2022-11-16 00:06:12 +00:00
let pk1 = PublicKey ::from_slice ( & hex! (
" 0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba "
) )
. unwrap ( ) ;
2020-12-22 03:10:46 +00:00
let pk2 = pk1 ;
2022-11-16 00:06:12 +00:00
let pk3 = PublicKey ::from_slice ( & hex! (
" 02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443 "
) )
. unwrap ( ) ;
2018-05-29 11:11:18 +00:00
2021-06-29 11:19:18 +00:00
assert_eq! ( pk1 , pk2 ) ;
2018-05-29 11:11:18 +00:00
assert! ( pk1 < = pk2 ) ;
assert! ( pk2 < = pk1 ) ;
assert! ( ! ( pk2 < pk1 ) ) ;
assert! ( ! ( pk1 < pk2 ) ) ;
2018-06-03 02:35:12 +00:00
2020-11-09 17:30:57 +00:00
assert! ( pk3 > pk1 ) ;
assert! ( pk1 < pk3 ) ;
assert! ( pk3 > = pk1 ) ;
assert! ( pk1 < = pk3 ) ;
2018-05-29 11:11:18 +00:00
}
2018-07-25 13:57:36 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(all(feature = " serde " , any(feature = " alloc " , feature = " std " ))) ]
2021-01-12 00:49:44 +00:00
fn test_serde ( ) {
2022-11-16 00:06:12 +00:00
use serde_test ::{ assert_tokens , Configure , Token } ;
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2018-07-25 13:57:36 +00:00
static SK_BYTES : [ u8 ; 32 ] = [
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
0xff , 0xff , 0 , 0 , 0xff , 0xff , 0 , 0 ,
99 , 99 , 99 , 99 , 99 , 99 , 99 , 99
] ;
2022-06-10 02:25:03 +00:00
static SK_STR : & str = " 01010101010101010001020304050607ffff0000ffff00006363636363636363 " ;
2022-03-01 18:20:56 +00:00
#[ cfg(fuzzing) ]
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2018-07-25 13:57:36 +00:00
static PK_BYTES : [ u8 ; 33 ] = [
0x02 ,
0x18 , 0x84 , 0x57 , 0x81 , 0xf6 , 0x31 , 0xc4 , 0x8f ,
0x1c , 0x97 , 0x09 , 0xe2 , 0x30 , 0x92 , 0x06 , 0x7d ,
0x06 , 0x83 , 0x7f , 0x30 , 0xaa , 0x0c , 0xd0 , 0x54 ,
0x4a , 0xc8 , 0x87 , 0xfe , 0x91 , 0xdd , 0xd1 , 0x66 ,
] ;
2022-06-10 02:25:03 +00:00
static PK_STR : & str = " 0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166 " ;
2018-07-25 13:57:36 +00:00
2022-02-01 01:49:07 +00:00
#[ cfg(not(fuzzing)) ]
2018-07-25 13:57:36 +00:00
let s = Secp256k1 ::new ( ) ;
2018-11-06 21:57:52 +00:00
let sk = SecretKey ::from_slice ( & SK_BYTES ) . unwrap ( ) ;
2021-02-18 14:55:46 +00:00
// In fuzzing mode secret->public key derivation is different, so
2022-02-02 21:36:36 +00:00
// hard-code the expected result.
2021-02-18 14:55:46 +00:00
#[ cfg(not(fuzzing)) ]
2018-07-25 13:57:36 +00:00
let pk = PublicKey ::from_secret_key ( & s , & sk ) ;
2021-02-18 14:55:46 +00:00
#[ cfg(fuzzing) ]
let pk = PublicKey ::from_slice ( & PK_BYTES ) . expect ( " pk " ) ;
2018-07-25 13:57:36 +00:00
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-03-01 18:20:56 +00:00
assert_tokens ( & sk . compact ( ) , & [
Token ::Tuple { len : 32 } ,
Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) ,
Token ::U8 ( 0 ) , Token ::U8 ( 1 ) , Token ::U8 ( 2 ) , Token ::U8 ( 3 ) , Token ::U8 ( 4 ) , Token ::U8 ( 5 ) , Token ::U8 ( 6 ) , Token ::U8 ( 7 ) ,
Token ::U8 ( 0xff ) , Token ::U8 ( 0xff ) , Token ::U8 ( 0 ) , Token ::U8 ( 0 ) , Token ::U8 ( 0xff ) , Token ::U8 ( 0xff ) , Token ::U8 ( 0 ) , Token ::U8 ( 0 ) ,
Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) ,
Token ::TupleEnd
] ) ;
2020-05-15 12:37:08 +00:00
2019-05-13 22:22:37 +00:00
assert_tokens ( & sk . readable ( ) , & [ Token ::BorrowedStr ( SK_STR ) ] ) ;
2020-05-15 12:37:08 +00:00
assert_tokens ( & sk . readable ( ) , & [ Token ::Str ( SK_STR ) ] ) ;
assert_tokens ( & sk . readable ( ) , & [ Token ::String ( SK_STR ) ] ) ;
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-03-01 18:20:56 +00:00
assert_tokens ( & pk . compact ( ) , & [
Token ::Tuple { len : 33 } ,
Token ::U8 ( 0x02 ) ,
Token ::U8 ( 0x18 ) , Token ::U8 ( 0x84 ) , Token ::U8 ( 0x57 ) , Token ::U8 ( 0x81 ) , Token ::U8 ( 0xf6 ) , Token ::U8 ( 0x31 ) , Token ::U8 ( 0xc4 ) , Token ::U8 ( 0x8f ) ,
Token ::U8 ( 0x1c ) , Token ::U8 ( 0x97 ) , Token ::U8 ( 0x09 ) , Token ::U8 ( 0xe2 ) , Token ::U8 ( 0x30 ) , Token ::U8 ( 0x92 ) , Token ::U8 ( 0x06 ) , Token ::U8 ( 0x7d ) ,
Token ::U8 ( 0x06 ) , Token ::U8 ( 0x83 ) , Token ::U8 ( 0x7f ) , Token ::U8 ( 0x30 ) , Token ::U8 ( 0xaa ) , Token ::U8 ( 0x0c ) , Token ::U8 ( 0xd0 ) , Token ::U8 ( 0x54 ) ,
Token ::U8 ( 0x4a ) , Token ::U8 ( 0xc8 ) , Token ::U8 ( 0x87 ) , Token ::U8 ( 0xfe ) , Token ::U8 ( 0x91 ) , Token ::U8 ( 0xdd ) , Token ::U8 ( 0xd1 ) , Token ::U8 ( 0x66 ) ,
Token ::TupleEnd
] ) ;
2020-05-15 12:37:08 +00:00
2019-07-23 09:56:40 +00:00
assert_tokens ( & pk . readable ( ) , & [ Token ::BorrowedStr ( PK_STR ) ] ) ;
2020-05-15 12:37:08 +00:00
assert_tokens ( & pk . readable ( ) , & [ Token ::Str ( PK_STR ) ] ) ;
assert_tokens ( & pk . readable ( ) , & [ Token ::String ( PK_STR ) ] ) ;
2018-07-25 13:57:36 +00:00
}
2022-01-03 21:23:05 +00:00
#[ test ]
2022-02-01 02:43:42 +00:00
#[ cfg(any(feature = " alloc " , feature = " std " )) ]
2022-04-06 05:24:23 +00:00
fn test_tweak_add_then_tweak_add_check ( ) {
2022-01-03 21:23:05 +00:00
let s = Secp256k1 ::new ( ) ;
2022-04-06 05:24:23 +00:00
// TODO: 10 times is arbitrary, we should test this a _lot_ of times.
2022-01-03 21:23:05 +00:00
for _ in 0 .. 10 {
2022-06-09 12:35:41 +00:00
let tweak = Scalar ::random ( ) ;
2022-01-12 07:01:02 +00:00
2022-04-06 05:24:23 +00:00
let kp = KeyPair ::new ( & s , & mut thread_rng ( ) ) ;
let ( xonly , _ ) = XOnlyPublicKey ::from_keypair ( & kp ) ;
let tweaked_kp = kp . add_xonly_tweak ( & s , & tweak ) . expect ( " keypair tweak add failed " ) ;
2022-11-16 00:06:12 +00:00
let ( tweaked_xonly , parity ) =
xonly . add_tweak ( & s , & tweak ) . expect ( " xonly pubkey tweak failed " ) ;
2022-04-06 05:24:23 +00:00
let ( want_tweaked_xonly , tweaked_kp_parity ) = XOnlyPublicKey ::from_keypair ( & tweaked_kp ) ;
2022-01-12 07:01:02 +00:00
2022-04-06 05:24:23 +00:00
assert_eq! ( tweaked_xonly , want_tweaked_xonly ) ;
assert_eq! ( parity , tweaked_kp_parity ) ;
2022-03-24 03:53:40 +00:00
2022-04-06 05:24:23 +00:00
assert! ( xonly . tweak_add_check ( & s , & tweaked_xonly , parity , tweak ) ) ;
2022-01-03 21:23:05 +00:00
}
}
#[ test ]
fn test_from_key_pubkey ( ) {
let kpk1 = PublicKey ::from_str (
" 02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443 " ,
)
. unwrap ( ) ;
let kpk2 = PublicKey ::from_str (
" 0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07 " ,
)
. unwrap ( ) ;
let pk1 = XOnlyPublicKey ::from ( kpk1 ) ;
let pk2 = XOnlyPublicKey ::from ( kpk2 ) ;
assert_eq! ( pk1 . serialize ( ) [ .. ] , kpk1 . serialize ( ) [ 1 .. ] ) ;
assert_eq! ( pk2 . serialize ( ) [ .. ] , kpk2 . serialize ( ) [ 1 .. ] ) ;
}
2022-01-18 15:56:17 +00:00
#[ test ]
2022-02-01 04:43:46 +00:00
#[ cfg(all(feature = " global-context " , feature = " serde " )) ]
2022-01-18 15:56:17 +00:00
fn test_serde_keypair ( ) {
use serde ::{ Deserialize , Deserializer , Serialize , Serializer } ;
2022-11-16 00:06:12 +00:00
use serde_test ::{ assert_tokens , Configure , Token } ;
2022-01-18 15:56:17 +00:00
use super ::serde_keypair ;
2021-09-14 09:18:22 +00:00
use crate ::key ::KeyPair ;
2022-01-18 15:56:17 +00:00
// Normally users would derive the serde traits, but we can't easily enable the serde macros
// here, so they are implemented manually to be able to test the behaviour.
#[ derive(Debug, Copy, Clone, Eq, PartialEq) ]
struct KeyPairWrapper ( KeyPair ) ;
impl < ' de > Deserialize < ' de > for KeyPairWrapper {
fn deserialize < D > ( deserializer : D ) -> Result < Self , D ::Error >
2022-11-16 00:06:12 +00:00
where
D : Deserializer < ' de > ,
{
2022-01-18 15:56:17 +00:00
serde_keypair ::deserialize ( deserializer ) . map ( KeyPairWrapper )
}
}
impl Serialize for KeyPairWrapper {
2022-11-16 00:06:12 +00:00
fn serialize < S > ( & self , serializer : S ) -> Result < S ::Ok , S ::Error >
where
S : Serializer ,
{
2022-01-18 15:56:17 +00:00
serde_keypair ::serialize ( & self . 0 , serializer )
}
}
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-01-18 15:56:17 +00:00
static SK_BYTES : [ u8 ; 32 ] = [
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
0xff , 0xff , 0 , 0 , 0xff , 0xff , 0 , 0 ,
99 , 99 , 99 , 99 , 99 , 99 , 99 , 99
] ;
2022-06-10 02:25:03 +00:00
static SK_STR : & str = " 01010101010101010001020304050607ffff0000ffff00006363636363636363 " ;
2022-01-18 15:56:17 +00:00
2021-09-14 09:18:22 +00:00
let sk = KeyPairWrapper ( KeyPair ::from_seckey_slice ( & crate ::SECP256K1 , & SK_BYTES ) . unwrap ( ) ) ;
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-03-01 18:20:56 +00:00
assert_tokens ( & sk . compact ( ) , & [
Token ::Tuple { len : 32 } ,
Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) , Token ::U8 ( 1 ) ,
Token ::U8 ( 0 ) , Token ::U8 ( 1 ) , Token ::U8 ( 2 ) , Token ::U8 ( 3 ) , Token ::U8 ( 4 ) , Token ::U8 ( 5 ) , Token ::U8 ( 6 ) , Token ::U8 ( 7 ) ,
Token ::U8 ( 0xff ) , Token ::U8 ( 0xff ) , Token ::U8 ( 0 ) , Token ::U8 ( 0 ) , Token ::U8 ( 0xff ) , Token ::U8 ( 0xff ) , Token ::U8 ( 0 ) , Token ::U8 ( 0 ) ,
Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) , Token ::U8 ( 99 ) ,
Token ::TupleEnd
] ) ;
2022-01-18 15:56:17 +00:00
assert_tokens ( & sk . readable ( ) , & [ Token ::BorrowedStr ( SK_STR ) ] ) ;
assert_tokens ( & sk . readable ( ) , & [ Token ::Str ( SK_STR ) ] ) ;
assert_tokens ( & sk . readable ( ) , & [ Token ::String ( SK_STR ) ] ) ;
}
2022-03-24 03:53:40 +00:00
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn keys ( ) -> ( SecretKey , PublicKey , KeyPair , XOnlyPublicKey ) {
let secp = Secp256k1 ::new ( ) ;
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-03-24 03:53:40 +00:00
static SK_BYTES : [ u8 ; 32 ] = [
0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 ,
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0xff , 0xff , 0x00 , 0x00 , 0xff , 0xff , 0x00 , 0x00 ,
0x63 , 0x63 , 0x63 , 0x63 , 0x63 , 0x63 , 0x63 , 0x63 ,
] ;
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-03-24 03:53:40 +00:00
static PK_BYTES : [ u8 ; 32 ] = [
0x18 , 0x84 , 0x57 , 0x81 , 0xf6 , 0x31 , 0xc4 , 0x8f ,
0x1c , 0x97 , 0x09 , 0xe2 , 0x30 , 0x92 , 0x06 , 0x7d ,
0x06 , 0x83 , 0x7f , 0x30 , 0xaa , 0x0c , 0xd0 , 0x54 ,
0x4a , 0xc8 , 0x87 , 0xfe , 0x91 , 0xdd , 0xd1 , 0x66
] ;
let mut pk_bytes = [ 0 u8 ; 33 ] ;
2022-11-16 00:06:12 +00:00
pk_bytes [ 0 ] = 0x02 ; // Use positive Y co-ordinate.
2022-03-24 03:53:40 +00:00
pk_bytes [ 1 .. ] . clone_from_slice ( & PK_BYTES ) ;
let sk = SecretKey ::from_slice ( & SK_BYTES ) . expect ( " failed to parse sk bytes " ) ;
let pk = PublicKey ::from_slice ( & pk_bytes ) . expect ( " failed to create pk from iterator " ) ;
let kp = KeyPair ::from_secret_key ( & secp , & sk ) ;
let xonly = XOnlyPublicKey ::from_slice ( & PK_BYTES ) . expect ( " failed to get xonly from slice " ) ;
( sk , pk , kp , xonly )
}
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn convert_public_key_to_xonly_public_key ( ) {
let ( _sk , pk , _kp , want ) = keys ( ) ;
let ( got , parity ) = pk . x_only_public_key ( ) ;
assert_eq! ( parity , Parity ::Even ) ;
assert_eq! ( got , want )
}
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn convert_secret_key_to_public_key ( ) {
let secp = Secp256k1 ::new ( ) ;
let ( sk , want , _kp , _xonly ) = keys ( ) ;
let got = sk . public_key ( & secp ) ;
assert_eq! ( got , want )
}
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn convert_secret_key_to_x_only_public_key ( ) {
let secp = Secp256k1 ::new ( ) ;
let ( sk , _pk , _kp , want ) = keys ( ) ;
let ( got , parity ) = sk . x_only_public_key ( & secp ) ;
assert_eq! ( parity , Parity ::Even ) ;
assert_eq! ( got , want )
}
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn convert_keypair_to_public_key ( ) {
let ( _sk , want , kp , _xonly ) = keys ( ) ;
let got = kp . public_key ( ) ;
assert_eq! ( got , want )
}
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn convert_keypair_to_x_only_public_key ( ) {
let ( _sk , _pk , kp , want ) = keys ( ) ;
let ( got , parity ) = kp . x_only_public_key ( ) ;
assert_eq! ( parity , Parity ::Even ) ;
assert_eq! ( got , want )
}
// SecretKey -> KeyPair -> SecretKey
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn roundtrip_secret_key_via_keypair ( ) {
let secp = Secp256k1 ::new ( ) ;
let ( sk , _pk , _kp , _xonly ) = keys ( ) ;
let kp = sk . keypair ( & secp ) ;
let back = kp . secret_key ( ) ;
assert_eq! ( back , sk )
}
// KeyPair -> SecretKey -> KeyPair
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn roundtrip_keypair_via_secret_key ( ) {
let secp = Secp256k1 ::new ( ) ;
let ( _sk , _pk , kp , _xonly ) = keys ( ) ;
let sk = kp . secret_key ( ) ;
let back = sk . keypair ( & secp ) ;
assert_eq! ( back , kp )
}
// XOnlyPublicKey -> PublicKey -> XOnlyPublicKey
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn roundtrip_x_only_public_key_via_public_key ( ) {
let ( _sk , _pk , _kp , xonly ) = keys ( ) ;
let pk = xonly . public_key ( Parity ::Even ) ;
let ( back , parity ) = pk . x_only_public_key ( ) ;
assert_eq! ( parity , Parity ::Even ) ;
assert_eq! ( back , xonly )
}
// PublicKey -> XOnlyPublicKey -> PublicKey
#[ test ]
#[ cfg(all(not(fuzzing), any(feature = " alloc " , feature = " std " ))) ]
fn roundtrip_public_key_via_x_only_public_key ( ) {
let ( _sk , pk , _kp , _xonly ) = keys ( ) ;
let ( xonly , parity ) = pk . x_only_public_key ( ) ;
let back = xonly . public_key ( parity ) ;
assert_eq! ( back , pk )
}
#[ test ]
fn public_key_from_x_only_public_key_and_odd_parity ( ) {
let s = " 18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166 " ;
let mut want = String ::from ( " 03 " ) ;
want . push_str ( s ) ;
let xonly = XOnlyPublicKey ::from_str ( s ) . expect ( " failed to parse xonly pubkey string " ) ;
let pk = xonly . public_key ( Parity ::Odd ) ;
let got = format! ( " {} " , pk ) ;
assert_eq! ( got , want )
}
2022-03-01 18:20:56 +00:00
#[ test ]
#[ cfg(not(fuzzing)) ]
#[ cfg(all(feature = " global-context " , feature = " serde " )) ]
fn test_serde_x_only_pubkey ( ) {
2022-11-16 00:06:12 +00:00
use serde_test ::{ assert_tokens , Configure , Token } ;
2022-03-01 18:20:56 +00:00
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-03-01 18:20:56 +00:00
static SK_BYTES : [ u8 ; 32 ] = [
1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
0xff , 0xff , 0 , 0 , 0xff , 0xff , 0 , 0 ,
99 , 99 , 99 , 99 , 99 , 99 , 99 , 99
] ;
static PK_STR : & 'static str = " \
18845781 f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166 \
" ;
let kp = KeyPair ::from_seckey_slice ( & crate ::SECP256K1 , & SK_BYTES ) . unwrap ( ) ;
let ( pk , _parity ) = XOnlyPublicKey ::from_keypair ( & kp ) ;
2022-11-03 00:09:32 +00:00
#[ rustfmt::skip ]
2022-03-01 18:20:56 +00:00
assert_tokens ( & pk . compact ( ) , & [
Token ::Tuple { len : 32 } ,
Token ::U8 ( 0x18 ) , Token ::U8 ( 0x84 ) , Token ::U8 ( 0x57 ) , Token ::U8 ( 0x81 ) , Token ::U8 ( 0xf6 ) , Token ::U8 ( 0x31 ) , Token ::U8 ( 0xc4 ) , Token ::U8 ( 0x8f ) ,
Token ::U8 ( 0x1c ) , Token ::U8 ( 0x97 ) , Token ::U8 ( 0x09 ) , Token ::U8 ( 0xe2 ) , Token ::U8 ( 0x30 ) , Token ::U8 ( 0x92 ) , Token ::U8 ( 0x06 ) , Token ::U8 ( 0x7d ) ,
Token ::U8 ( 0x06 ) , Token ::U8 ( 0x83 ) , Token ::U8 ( 0x7f ) , Token ::U8 ( 0x30 ) , Token ::U8 ( 0xaa ) , Token ::U8 ( 0x0c ) , Token ::U8 ( 0xd0 ) , Token ::U8 ( 0x54 ) ,
Token ::U8 ( 0x4a ) , Token ::U8 ( 0xc8 ) , Token ::U8 ( 0x87 ) , Token ::U8 ( 0xfe ) , Token ::U8 ( 0x91 ) , Token ::U8 ( 0xdd ) , Token ::U8 ( 0xd1 ) , Token ::U8 ( 0x66 ) ,
Token ::TupleEnd
] ) ;
assert_tokens ( & pk . readable ( ) , & [ Token ::BorrowedStr ( PK_STR ) ] ) ;
assert_tokens ( & pk . readable ( ) , & [ Token ::Str ( PK_STR ) ] ) ;
assert_tokens ( & pk . readable ( ) , & [ Token ::String ( PK_STR ) ] ) ;
}
2022-10-21 18:35:59 +00:00
#[ test ]
#[ cfg(any(feature = " alloc " , feature = " global-context " )) ]
fn test_keypair_from_str ( ) {
let ctx = crate ::Secp256k1 ::new ( ) ;
let keypair = KeyPair ::new ( & ctx , & mut thread_rng ( ) ) ;
let msg = keypair . secret_key ( ) . secret_bytes ( ) . to_hex ( ) ;
let parsed_key : KeyPair = msg . parse ( ) . unwrap ( ) ;
assert_eq! ( parsed_key , keypair ) ;
}
#[ test ]
2022-11-16 00:06:12 +00:00
#[ cfg(all(any(feature = " alloc " , feature = " global-context " ), feature = " serde " )) ]
2022-10-21 18:35:59 +00:00
fn test_keypair_deserialize_serde ( ) {
let ctx = crate ::Secp256k1 ::new ( ) ;
let sec_key_str = " 4242424242424242424242424242424242424242424242424242424242424242 " ;
let keypair = KeyPair ::from_seckey_str ( & ctx , sec_key_str ) . unwrap ( ) ;
serde_test ::assert_tokens ( & keypair . readable ( ) , & [ Token ::String ( & sec_key_str ) ] ) ;
let sec_key_bytes = keypair . secret_key ( ) . secret_bytes ( ) ;
let tokens = std ::iter ::once ( Token ::Tuple { len : 32 } )
. chain ( sec_key_bytes . iter ( ) . copied ( ) . map ( Token ::U8 ) )
. chain ( std ::iter ::once ( Token ::TupleEnd ) )
. collect ::< Vec < _ > > ( ) ;
serde_test ::assert_tokens ( & keypair . compact ( ) , & tokens ) ;
}
#[ test ]
#[ should_panic(expected = " The previous implementation was panicking too " ) ]
#[ cfg(not(any(feature = " alloc " , feature = " global-context " ))) ]
fn test_parse_keypair_no_alloc_panic ( ) {
let key_hex = " 4242424242424242424242424242424242424242424242424242424242424242 " ;
let _ : KeyPair = key_hex . parse ( ) . expect ( " We shouldn't even get this far " ) ;
}
2014-08-10 01:46:38 +00:00
}
2021-06-20 15:58:50 +00:00
2022-07-13 04:40:49 +00:00
#[ cfg(bench) ]
2021-06-20 15:58:50 +00:00
mod benches {
use std ::collections ::BTreeSet ;
2022-11-16 00:06:12 +00:00
use test ::Bencher ;
2021-06-20 15:58:50 +00:00
use crate ::constants ::GENERATOR_X ;
2022-11-16 00:06:12 +00:00
use crate ::PublicKey ;
2021-06-20 15:58:50 +00:00
#[ bench ]
fn bench_pk_ordering ( b : & mut Bencher ) {
let mut map = BTreeSet ::new ( ) ;
let mut g_slice = [ 02 u8 ; 33 ] ;
g_slice [ 1 .. ] . copy_from_slice ( & GENERATOR_X ) ;
let g = PublicKey ::from_slice ( & g_slice ) . unwrap ( ) ;
let mut pk = g ;
b . iter ( | | {
map . insert ( pk ) ;
pk = pk . combine ( & pk ) . unwrap ( ) ;
} )
}
}