@@ -134,9 +134,9 @@ impl SecretKey {
134
134
}
135
135
}
136
136
137
- /// Creates a new secret key using data from BIP-340 [`::schnorrsig:: KeyPair`]
137
+ /// Creates a new secret key using data from BIP-340 [`KeyPair`]
138
138
#[ inline]
139
- pub fn from_keypair ( keypair : & :: schnorrsig :: KeyPair ) -> Self {
139
+ pub fn from_keypair ( keypair : & KeyPair ) -> Self {
140
140
let mut sk = [ 0u8 ; constants:: SECRET_KEY_SIZE ] ;
141
141
unsafe {
142
142
let ret = ffi:: secp256k1_keypair_sec (
@@ -297,9 +297,9 @@ impl PublicKey {
297
297
}
298
298
}
299
299
300
- /// Creates a new compressed public key key using data from BIP-340 [`::schnorrsig:: KeyPair`]
300
+ /// Creates a new compressed public key key using data from BIP-340 [`KeyPair`]
301
301
#[ inline]
302
- pub fn from_keypair ( keypair : & :: schnorrsig :: KeyPair ) -> Self {
302
+ pub fn from_keypair ( keypair : & KeyPair ) -> Self {
303
303
unsafe {
304
304
let mut pk = ffi:: PublicKey :: new ( ) ;
305
305
let ret = ffi:: secp256k1_keypair_pub (
@@ -505,6 +505,175 @@ impl Ord for PublicKey {
505
505
}
506
506
}
507
507
508
+ /// Opaque data structure that holds a keypair consisting of a secret and a public key.
509
+ #[ derive( Clone ) ]
510
+ pub struct KeyPair ( ffi:: KeyPair ) ;
511
+ impl_display_secret ! ( KeyPair ) ;
512
+
513
+ impl KeyPair {
514
+ /// Obtains a raw const pointer suitable for use with FFI functions
515
+ #[ inline]
516
+ pub fn as_ptr ( & self ) -> * const ffi:: KeyPair {
517
+ & self . 0
518
+ }
519
+
520
+ /// Obtains a raw mutable pointer suitable for use with FFI functions
521
+ #[ inline]
522
+ pub fn as_mut_ptr ( & mut self ) -> * mut ffi:: KeyPair {
523
+ & mut self . 0
524
+ }
525
+
526
+ /// Creates a Schnorr KeyPair directly from generic Secp256k1 secret key
527
+ ///
528
+ /// # Panic
529
+ ///
530
+ /// Panics if internal representation of the provided [`SecretKey`] does not hold correct secret
531
+ /// key value obtained from Secp256k1 library previously, specifically when secret key value is
532
+ /// out-of-range (0 or in excess of the group order).
533
+ #[ inline]
534
+ pub fn from_secret_key < C : Signing > (
535
+ secp : & Secp256k1 < C > ,
536
+ sk : SecretKey ,
537
+ ) -> KeyPair {
538
+ unsafe {
539
+ let mut kp = ffi:: KeyPair :: new ( ) ;
540
+ if ffi:: secp256k1_keypair_create ( secp. ctx , & mut kp, sk. as_c_ptr ( ) ) == 1 {
541
+ KeyPair ( kp)
542
+ } else {
543
+ panic ! ( "the provided secret key is invalid: it is corrupted or was not produced by Secp256k1 library" )
544
+ }
545
+ }
546
+ }
547
+
548
+ /// Creates a Schnorr KeyPair directly from a secret key slice.
549
+ ///
550
+ /// # Errors
551
+ ///
552
+ /// [`Error::InvalidSecretKey`] if the provided data has an incorrect length, exceeds Secp256k1
553
+ /// field `p` value or the corresponding public key is not even.
554
+ #[ inline]
555
+ pub fn from_seckey_slice < C : Signing > (
556
+ secp : & Secp256k1 < C > ,
557
+ data : & [ u8 ] ,
558
+ ) -> Result < KeyPair , Error > {
559
+ if data. is_empty ( ) || data. len ( ) != constants:: SECRET_KEY_SIZE {
560
+ return Err ( Error :: InvalidSecretKey ) ;
561
+ }
562
+
563
+ unsafe {
564
+ let mut kp = ffi:: KeyPair :: new ( ) ;
565
+ if ffi:: secp256k1_keypair_create ( secp. ctx , & mut kp, data. as_c_ptr ( ) ) == 1 {
566
+ Ok ( KeyPair ( kp) )
567
+ } else {
568
+ Err ( Error :: InvalidSecretKey )
569
+ }
570
+ }
571
+ }
572
+
573
+ /// Creates a Schnorr KeyPair directly from a secret key string
574
+ ///
575
+ /// # Errors
576
+ ///
577
+ /// [`Error::InvalidSecretKey`] if corresponding public key for the provided secret key is not even.
578
+ #[ inline]
579
+ pub fn from_seckey_str < C : Signing > ( secp : & Secp256k1 < C > , s : & str ) -> Result < KeyPair , Error > {
580
+ let mut res = [ 0u8 ; constants:: SECRET_KEY_SIZE ] ;
581
+ match from_hex ( s, & mut res) {
582
+ Ok ( constants:: SECRET_KEY_SIZE ) => {
583
+ KeyPair :: from_seckey_slice ( secp, & res[ 0 ..constants:: SECRET_KEY_SIZE ] )
584
+ }
585
+ _ => Err ( Error :: InvalidPublicKey ) ,
586
+ }
587
+ }
588
+
589
+ /// Creates a new random secret key. Requires compilation with the "rand" feature.
590
+ #[ inline]
591
+ #[ cfg( any( test, feature = "rand" ) ) ]
592
+ pub fn new < R : Rng + ?Sized , C : Signing > ( secp : & Secp256k1 < C > , rng : & mut R ) -> KeyPair {
593
+ let mut random_32_bytes = || {
594
+ let mut ret = [ 0u8 ; 32 ] ;
595
+ rng. fill_bytes ( & mut ret) ;
596
+ ret
597
+ } ;
598
+ let mut data = random_32_bytes ( ) ;
599
+ unsafe {
600
+ let mut keypair = ffi:: KeyPair :: new ( ) ;
601
+ while ffi:: secp256k1_keypair_create ( secp. ctx , & mut keypair, data. as_c_ptr ( ) ) == 0 {
602
+ data = random_32_bytes ( ) ;
603
+ }
604
+ KeyPair ( keypair)
605
+ }
606
+ }
607
+
608
+ /// Serialize the key pair as a secret key byte value
609
+ #[ inline]
610
+ pub fn serialize_secret ( & self ) -> [ u8 ; constants:: SECRET_KEY_SIZE ] {
611
+ * SecretKey :: from_keypair ( self ) . as_ref ( )
612
+ }
613
+
614
+ /// Tweak a keypair by adding the given tweak to the secret key and updating the public key
615
+ /// accordingly.
616
+ ///
617
+ /// Will return an error if the resulting key would be invalid or if the tweak was not a 32-byte
618
+ /// length slice.
619
+ ///
620
+ /// NB: Will not error if the tweaked public key has an odd value and can't be used for
621
+ /// BIP 340-342 purposes.
622
+ // TODO: Add checked implementation
623
+ #[ inline]
624
+ pub fn tweak_add_assign < C : Verification > (
625
+ & mut self ,
626
+ secp : & Secp256k1 < C > ,
627
+ tweak : & [ u8 ] ,
628
+ ) -> Result < ( ) , Error > {
629
+ if tweak. len ( ) != 32 {
630
+ return Err ( Error :: InvalidTweak ) ;
631
+ }
632
+
633
+ unsafe {
634
+ let err = ffi:: secp256k1_keypair_xonly_tweak_add (
635
+ secp. ctx ,
636
+ & mut self . 0 ,
637
+ tweak. as_c_ptr ( ) ,
638
+ ) ;
639
+
640
+ if err == 1 {
641
+ Ok ( ( ) )
642
+ } else {
643
+ Err ( Error :: InvalidTweak )
644
+ }
645
+ }
646
+ }
647
+ }
648
+
649
+ impl From < KeyPair > for SecretKey {
650
+ #[ inline]
651
+ fn from ( pair : KeyPair ) -> Self {
652
+ SecretKey :: from_keypair ( & pair)
653
+ }
654
+ }
655
+
656
+ impl < ' a > From < & ' a KeyPair > for SecretKey {
657
+ #[ inline]
658
+ fn from ( pair : & ' a KeyPair ) -> Self {
659
+ SecretKey :: from_keypair ( pair)
660
+ }
661
+ }
662
+
663
+ impl From < KeyPair > for PublicKey {
664
+ #[ inline]
665
+ fn from ( pair : KeyPair ) -> Self {
666
+ PublicKey :: from_keypair ( & pair)
667
+ }
668
+ }
669
+
670
+ impl < ' a > From < & ' a KeyPair > for PublicKey {
671
+ #[ inline]
672
+ fn from ( pair : & ' a KeyPair ) -> Self {
673
+ PublicKey :: from_keypair ( pair)
674
+ }
675
+ }
676
+
508
677
#[ cfg( test) ]
509
678
mod test {
510
679
use Secp256k1 ;
0 commit comments