@@ -13,9 +13,10 @@ use std::result::Result::{Err, Ok};
13
13
use std:: str:: FromStr ;
14
14
15
15
use self :: cfd_sys:: {
16
- CfdAdaptEcdsaAdaptor , CfdComputeSchnorrSigPoint , CfdExtractEcdsaAdaptorSecret ,
17
- CfdSignEcdsaAdaptor , CfdSignSchnorr , CfdSignSchnorrWithNonce , CfdSplitSchnorrSignature ,
18
- CfdVerifyEcdsaAdaptor , CfdVerifySchnorr , CfdGetSchnorrPubkeyFromPrivkey ,
16
+ CfdAdaptEcdsaAdaptor , CfdCheckTweakAddFromSchnorrPubkey , CfdComputeSchnorrSigPoint ,
17
+ CfdExtractEcdsaAdaptorSecret , CfdGetSchnorrPubkeyFromPrivkey , CfdGetSchnorrPubkeyFromPubkey ,
18
+ CfdSchnorrKeyPairTweakAdd , CfdSchnorrPubkeyTweakAdd , CfdSignEcdsaAdaptor , CfdSignSchnorr ,
19
+ CfdSignSchnorrWithNonce , CfdSplitSchnorrSignature , CfdVerifyEcdsaAdaptor , CfdVerifySchnorr ,
19
20
} ;
20
21
21
22
/// adaptor signature size.
@@ -590,23 +591,115 @@ impl SchnorrPubkey {
590
591
/// use cfd_rust::{SchnorrPubkey, Privkey};
591
592
/// use std::str::FromStr;
592
593
/// let key = Privkey::from_str("475697a71a74ff3f2a8f150534e9b67d4b0b6561fab86fcaa51f8c9d6c9db8c6").expect("Fail");
593
- /// let pubkey = SchnorrPubkey::from_privkey(&key).expect("Fail");
594
+ /// let pubkey_ret = SchnorrPubkey::from_privkey(&key).expect("Fail");
595
+ /// let (pubkey, parity) = pubkey_ret;
594
596
/// ```
595
- pub fn from_privkey ( key : & Privkey ) -> Result < SchnorrPubkey , CfdError > {
597
+ pub fn from_privkey ( key : & Privkey ) -> Result < ( SchnorrPubkey , bool ) , CfdError > {
596
598
let key_hex = alloc_c_string ( & key. to_hex ( ) ) ?;
597
599
let handle = ErrorHandle :: new ( ) ?;
598
600
let mut pubkey_hex: * mut c_char = ptr:: null_mut ( ) ;
601
+ let mut parity = false ;
599
602
let error_code = unsafe {
600
603
CfdGetSchnorrPubkeyFromPrivkey (
601
604
handle. as_handle ( ) ,
602
605
key_hex. as_ptr ( ) ,
603
606
& mut pubkey_hex,
607
+ & mut parity,
604
608
)
605
609
} ;
606
610
let result = match error_code {
607
611
0 => {
608
612
let pubkey = unsafe { collect_cstring_and_free ( pubkey_hex) } ?;
609
- SchnorrPubkey :: from_str ( & pubkey)
613
+ let pubkey_obj = SchnorrPubkey :: from_str ( & pubkey) ?;
614
+ Ok ( ( pubkey_obj, parity) )
615
+ }
616
+ _ => Err ( handle. get_error ( error_code) ) ,
617
+ } ;
618
+ handle. free_handle ( ) ;
619
+ result
620
+ }
621
+
622
+ /// Generate from pubkey.
623
+ ///
624
+ /// # Arguments
625
+ /// * `key` - A public key.
626
+ ///
627
+ /// # Example
628
+ ///
629
+ /// ```
630
+ /// use cfd_rust::{SchnorrPubkey, Pubkey};
631
+ /// use std::str::FromStr;
632
+ /// let key = Pubkey::from_str("03b33cc9edc096d0a83416964bd3c6247b8fecd256e4efa7870d2c854bdeb33390").expect("Fail");
633
+ /// let pubkey_ret = SchnorrPubkey::from_pubkey(&key).expect("Fail");
634
+ /// let (pubkey, parity) = pubkey_ret;
635
+ /// ```
636
+ pub fn from_pubkey ( key : & Pubkey ) -> Result < ( SchnorrPubkey , bool ) , CfdError > {
637
+ let key_hex = alloc_c_string ( & key. to_hex ( ) ) ?;
638
+ let handle = ErrorHandle :: new ( ) ?;
639
+ let mut pubkey_hex: * mut c_char = ptr:: null_mut ( ) ;
640
+ let mut parity = false ;
641
+ let error_code = unsafe {
642
+ CfdGetSchnorrPubkeyFromPubkey (
643
+ handle. as_handle ( ) ,
644
+ key_hex. as_ptr ( ) ,
645
+ & mut pubkey_hex,
646
+ & mut parity,
647
+ )
648
+ } ;
649
+ let result = match error_code {
650
+ 0 => {
651
+ let pubkey = unsafe { collect_cstring_and_free ( pubkey_hex) } ?;
652
+ let pubkey_obj = SchnorrPubkey :: from_str ( & pubkey) ?;
653
+ Ok ( ( pubkey_obj, parity) )
654
+ }
655
+ _ => Err ( handle. get_error ( error_code) ) ,
656
+ } ;
657
+ handle. free_handle ( ) ;
658
+ result
659
+ }
660
+
661
+ /// Generate tweaked key pair from privkey.
662
+ ///
663
+ /// # Arguments
664
+ /// * `key` - A private key.
665
+ /// * `data` - A tweaked 32 byte buffer.
666
+ ///
667
+ /// # Example
668
+ ///
669
+ /// ```
670
+ /// use cfd_rust::{SchnorrPubkey, Privkey, ByteData};
671
+ /// use std::str::FromStr;
672
+ /// let key = Privkey::from_str("475697a71a74ff3f2a8f150534e9b67d4b0b6561fab86fcaa51f8c9d6c9db8c6").expect("Fail");
673
+ /// let tweak = ByteData::from_str("e48441762fb75010b2aa31a512b62b4148aa3fb08eb0765d76b252559064a614").expect("Fail");
674
+ /// let pubkey_ret = SchnorrPubkey::get_tweak_add_from_privkey(&key, tweak.to_slice()).expect("Fail");
675
+ /// let (pubkey, parity, privkey) = pubkey_ret;
676
+ /// ```
677
+ pub fn get_tweak_add_from_privkey (
678
+ key : & Privkey ,
679
+ data : & [ u8 ] ,
680
+ ) -> Result < ( SchnorrPubkey , bool , Privkey ) , CfdError > {
681
+ let key_hex = alloc_c_string ( & key. to_hex ( ) ) ?;
682
+ let tweak_hex = alloc_c_string ( & hex_from_bytes ( data) ) ?;
683
+ let handle = ErrorHandle :: new ( ) ?;
684
+ let mut pubkey_hex: * mut c_char = ptr:: null_mut ( ) ;
685
+ let mut privkey_hex: * mut c_char = ptr:: null_mut ( ) ;
686
+ let mut parity = false ;
687
+ let error_code = unsafe {
688
+ CfdSchnorrKeyPairTweakAdd (
689
+ handle. as_handle ( ) ,
690
+ key_hex. as_ptr ( ) ,
691
+ tweak_hex. as_ptr ( ) ,
692
+ & mut pubkey_hex,
693
+ & mut parity,
694
+ & mut privkey_hex,
695
+ )
696
+ } ;
697
+ let result = match error_code {
698
+ 0 => {
699
+ let str_list = unsafe { collect_multi_cstring_and_free ( & [ pubkey_hex, privkey_hex] ) } ?;
700
+ let pubkey_obj = SchnorrPubkey :: from_str ( & str_list[ 0 ] ) ?;
701
+ let privkey_obj = Privkey :: from_str ( & str_list[ 1 ] ) ?;
702
+ Ok ( ( pubkey_obj, parity, privkey_obj) )
610
703
}
611
704
_ => Err ( handle. get_error ( error_code) ) ,
612
705
} ;
@@ -632,6 +725,91 @@ impl SchnorrPubkey {
632
725
pub fn as_key ( & self ) -> Result < Privkey , CfdError > {
633
726
Privkey :: from_slice ( & self . data )
634
727
}
728
+
729
+ /// Generate tweaked schnorr pubkey.
730
+ ///
731
+ /// # Arguments
732
+ /// * `data` - A tweaked 32 byte buffer.
733
+ ///
734
+ /// # Example
735
+ ///
736
+ /// ```
737
+ /// use cfd_rust::{SchnorrPubkey, ByteData};
738
+ /// use std::str::FromStr;
739
+ /// let key = SchnorrPubkey::from_str("b33cc9edc096d0a83416964bd3c6247b8fecd256e4efa7870d2c854bdeb33390").expect("Fail");
740
+ /// let tweak = ByteData::from_str("e48441762fb75010b2aa31a512b62b4148aa3fb08eb0765d76b252559064a614").expect("Fail");
741
+ /// let pubkey_ret = key.tweak_add(tweak.to_slice()).expect("Fail");
742
+ /// let (pubkey, parity) = pubkey_ret;
743
+ /// ```
744
+ pub fn tweak_add ( & self , data : & [ u8 ] ) -> Result < ( SchnorrPubkey , bool ) , CfdError > {
745
+ let key_hex = alloc_c_string ( & self . to_hex ( ) ) ?;
746
+ let tweak_hex = alloc_c_string ( & hex_from_bytes ( data) ) ?;
747
+ let handle = ErrorHandle :: new ( ) ?;
748
+ let mut pubkey_hex: * mut c_char = ptr:: null_mut ( ) ;
749
+ let mut parity = false ;
750
+ let error_code = unsafe {
751
+ CfdSchnorrPubkeyTweakAdd (
752
+ handle. as_handle ( ) ,
753
+ key_hex. as_ptr ( ) ,
754
+ tweak_hex. as_ptr ( ) ,
755
+ & mut pubkey_hex,
756
+ & mut parity,
757
+ )
758
+ } ;
759
+ let result = match error_code {
760
+ 0 => {
761
+ let pubkey = unsafe { collect_cstring_and_free ( pubkey_hex) } ?;
762
+ let pubkey_obj = SchnorrPubkey :: from_str ( & pubkey) ?;
763
+ Ok ( ( pubkey_obj, parity) )
764
+ }
765
+ _ => Err ( handle. get_error ( error_code) ) ,
766
+ } ;
767
+ handle. free_handle ( ) ;
768
+ result
769
+ }
770
+
771
+ /// Generate tweaked schnorr pubkey.
772
+ ///
773
+ /// # Arguments
774
+ /// * `data` - A tweaked 32 byte buffer.
775
+ ///
776
+ /// # Example
777
+ ///
778
+ /// ```
779
+ /// use cfd_rust::{SchnorrPubkey, ByteData};
780
+ /// use std::str::FromStr;
781
+ /// let key = SchnorrPubkey::from_str("b33cc9edc096d0a83416964bd3c6247b8fecd256e4efa7870d2c854bdeb33390").expect("Fail");
782
+ /// let tweak = ByteData::from_str("e48441762fb75010b2aa31a512b62b4148aa3fb08eb0765d76b252559064a614").expect("Fail");
783
+ /// let tweaked_key = SchnorrPubkey::from_str("1fc8e882e34cc7942a15f39ffaebcbdf58a19239bcb17b7f5aa88e0eb808f906").expect("Fail");
784
+ /// let is_valid = tweaked_key.is_tweaked(true, &key, tweak.to_slice()).expect("Fail");
785
+ /// ```
786
+ pub fn is_tweaked (
787
+ & self ,
788
+ parity : bool ,
789
+ base_pubkey : & SchnorrPubkey ,
790
+ data : & [ u8 ] ,
791
+ ) -> Result < bool , CfdError > {
792
+ let key_hex = alloc_c_string ( & self . to_hex ( ) ) ?;
793
+ let base_key_hex = alloc_c_string ( & base_pubkey. to_hex ( ) ) ?;
794
+ let tweak_hex = alloc_c_string ( & hex_from_bytes ( data) ) ?;
795
+ let handle = ErrorHandle :: new ( ) ?;
796
+ let error_code = unsafe {
797
+ CfdCheckTweakAddFromSchnorrPubkey (
798
+ handle. as_handle ( ) ,
799
+ key_hex. as_ptr ( ) ,
800
+ parity,
801
+ base_key_hex. as_ptr ( ) ,
802
+ tweak_hex. as_ptr ( ) ,
803
+ )
804
+ } ;
805
+ let result = match error_code {
806
+ 0 => Ok ( true ) ,
807
+ 7 => Ok ( false ) ,
808
+ _ => Err ( handle. get_error ( error_code) ) ,
809
+ } ;
810
+ handle. free_handle ( ) ;
811
+ result
812
+ }
635
813
}
636
814
637
815
impl fmt:: Display for SchnorrPubkey {
0 commit comments