@@ -13,6 +13,7 @@ use core::{fmt, ptr, str};
1313use ffi:: { self , CPtr } ;
1414use { constants, Secp256k1 } ;
1515use { Message , Signing , Verification } ;
16+ use SecretKey ;
1617
1718/// Represents a Schnorr signature.
1819pub struct Signature ( [ u8 ; constants:: SCHNORRSIG_SIGNATURE_SIZE ] ) ;
@@ -449,6 +450,38 @@ impl<'de> ::serde::Deserialize<'de> for PublicKey {
449450 }
450451}
451452
453+ impl SecretKey {
454+ /// Creates a new secret key using data from BIP-340 [`KeyPair`]
455+ pub fn from_keypair < V : Verification > ( secp : & Secp256k1 < V > , keypair : & KeyPair ) -> Self {
456+ let mut sk = [ 0 ; constants:: SECRET_KEY_SIZE ] ;
457+ unsafe {
458+ let ret = ffi:: secp256k1_keypair_sec (
459+ secp. ctx ,
460+ sk. as_mut_c_ptr ( ) ,
461+ keypair. as_ptr ( )
462+ ) ;
463+ debug_assert_eq ! ( ret, 1 ) ;
464+ }
465+ SecretKey ( sk)
466+ }
467+ }
468+
469+ impl :: key:: PublicKey {
470+ /// Creates a new compressed public key key using data from BIP-340 [`KeyPair`]
471+ pub fn from_keypair < C : Signing > ( secp : & Secp256k1 < C > , keypair : & KeyPair ) -> Self {
472+ unsafe {
473+ let mut pk = ffi:: PublicKey :: new ( ) ;
474+ let ret = ffi:: secp256k1_keypair_pub (
475+ secp. ctx ,
476+ & mut pk,
477+ keypair. as_ptr ( )
478+ ) ;
479+ debug_assert_eq ! ( ret, 1 ) ;
480+ :: key:: PublicKey ( pk)
481+ }
482+ }
483+ }
484+
452485impl < C : Signing > Secp256k1 < C > {
453486 fn schnorrsig_sign_helper (
454487 & self ,
@@ -573,6 +606,7 @@ mod tests {
573606
574607 #[ cfg( target_arch = "wasm32" ) ]
575608 use wasm_bindgen_test:: wasm_bindgen_test as test;
609+ use SecretKey ;
576610
577611 macro_rules! hex_32 {
578612 ( $hex: expr) => { {
@@ -669,7 +703,7 @@ mod tests {
669703 }
670704
671705 #[ test]
672- fn pubkey_from_slice ( ) {
706+ fn test_pubkey_from_slice ( ) {
673707 assert_eq ! ( PublicKey :: from_slice( & [ ] ) , Err ( InvalidPublicKey ) ) ;
674708 assert_eq ! ( PublicKey :: from_slice( & [ 1 , 2 , 3 ] ) , Err ( InvalidPublicKey ) ) ;
675709 let pk = PublicKey :: from_slice ( & [
@@ -681,14 +715,27 @@ mod tests {
681715 }
682716
683717 #[ test]
684- fn pubkey_serialize_roundtrip ( ) {
718+ fn test_pubkey_serialize_roundtrip ( ) {
685719 let secp = Secp256k1 :: new ( ) ;
686720 let ( _, pubkey) = secp. generate_schnorrsig_keypair ( & mut thread_rng ( ) ) ;
687721 let ser = pubkey. serialize ( ) ;
688722 let pubkey2 = PublicKey :: from_slice ( & ser) . unwrap ( ) ;
689723 assert_eq ! ( pubkey, pubkey2) ;
690724 }
691725
726+ #[ test]
727+ fn test_xonly_key_extraction ( ) {
728+ let secp = Secp256k1 :: new ( ) ;
729+ let sk_str = "688C77BC2D5AAFF5491CF309D4753B732135470D05B7B2CD21ADD0744FE97BEF" ;
730+ let keypair = KeyPair :: from_seckey_str ( & secp, sk_str) . unwrap ( ) ;
731+ let sk = SecretKey :: from_keypair ( & secp, & keypair) ;
732+ assert_eq ! ( SecretKey :: from_str( sk_str) . unwrap( ) , sk) ;
733+ let pk = :: key:: PublicKey :: from_keypair ( & secp, & keypair) ;
734+ assert_eq ! ( :: key:: PublicKey :: from_secret_key( & secp, & sk) , pk) ;
735+ let xpk = PublicKey :: from_keypair ( & secp, & keypair) ;
736+ assert_eq ! ( PublicKey :: from( pk) , xpk) ;
737+ }
738+
692739 #[ test]
693740 fn test_pubkey_from_bad_slice ( ) {
694741 // Bad sizes
0 commit comments