@@ -845,12 +845,25 @@ impl str::FromStr for XOnlyPublicKey {
845845 fn from_str ( s : & str ) -> Result < XOnlyPublicKey , Error > {
846846 let mut res = [ 0u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] ;
847847 match from_hex ( s, & mut res) {
848- Ok ( constants:: SCHNORR_PUBLIC_KEY_SIZE ) => XOnlyPublicKey :: from_byte_array ( res) ,
848+ Ok ( constants:: SCHNORR_PUBLIC_KEY_SIZE ) => XOnlyPublicKey :: parse_byte_array ( res) ,
849849 _ => Err ( Error :: InvalidPublicKey ) ,
850850 }
851851 }
852852}
853853
854+ impl TryFrom < [ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] > for XOnlyPublicKey {
855+ type Error = Error ;
856+
857+ /// Attempts to create an x-only public key from a 32-byte array.
858+ ///
859+ /// # Errors
860+ /// Returns [`Error::InvalidPublicKey`] if the bytes do not represent a valid
861+ /// point on the secp256k1 curve.
862+ fn try_from ( data : [ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] ) -> Result < Self , Self :: Error > {
863+ Self :: parse_byte_array ( data)
864+ }
865+ }
866+
854867impl XOnlyPublicKey {
855868 /// Returns the [`XOnlyPublicKey`] (and its [`Parity`]) for `keypair`.
856869 #[ inline]
@@ -882,19 +895,33 @@ impl XOnlyPublicKey {
882895 #[ inline]
883896 pub fn from_slice ( data : & [ u8 ] ) -> Result < XOnlyPublicKey , Error > {
884897 match <[ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] >:: try_from ( data) {
885- Ok ( data) => Self :: from_byte_array ( data) ,
898+ Ok ( data) => Self :: parse_byte_array ( data) ,
886899 Err ( _) => Err ( InvalidPublicKey ) ,
887900 }
888901 }
889902
890- /// Creates a schnorr public key directly from a byte array.
903+ /// Creates an x-only public key from a byte array.
891904 ///
892- /// # Errors
905+ /// # Panics
893906 ///
894- /// Returns [`Error::InvalidPublicKey`] if the array does not represent a valid Secp256k1 point
895- /// x coordinate.
896- #[ inline]
897- pub fn from_byte_array (
907+ /// In debug builds, this function will panic if the input does not represent
908+ /// a valid point on the curve. In release builds, it assumes the input is
909+ /// valid. For untrusted input, use [`TryFrom`].
910+ pub fn from_byte_array ( data : [ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] ) -> XOnlyPublicKey {
911+ unsafe {
912+ let mut pk = ffi:: XOnlyPublicKey :: new ( ) ;
913+ let ret = ffi:: secp256k1_xonly_pubkey_parse (
914+ ffi:: secp256k1_context_no_precomp,
915+ & mut pk,
916+ data. as_c_ptr ( ) ,
917+ ) ;
918+ debug_assert_eq ! ( ret, 1 ) ;
919+ XOnlyPublicKey ( pk)
920+ }
921+ }
922+
923+ /// Fallible version of `from_byte_array` for parsing untrusted input.
924+ fn parse_byte_array (
898925 data : [ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] ,
899926 ) -> Result < XOnlyPublicKey , Error > {
900927 unsafe {
@@ -912,7 +939,26 @@ impl XOnlyPublicKey {
912939 }
913940 }
914941
942+ /// Serializes the `XOnlyPublicKey` into a 32-byte array.
943+ ///
944+ /// This represents the x-coordinate of the point on the curve.
945+ #[ inline]
946+ pub fn to_byte_array ( & self ) -> [ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] {
947+ let mut ret = [ 0u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] ;
948+
949+ unsafe {
950+ let err = ffi:: secp256k1_xonly_pubkey_serialize (
951+ ffi:: secp256k1_context_no_precomp,
952+ ret. as_mut_c_ptr ( ) ,
953+ self . as_c_ptr ( ) ,
954+ ) ;
955+ debug_assert_eq ! ( err, 1 ) ;
956+ }
957+ ret
958+ }
959+
915960 #[ inline]
961+ #[ deprecated( since = "TBD" , note = "use XOnlyPublicKey::to_byte_array instead" ) ]
916962 /// Serializes the key as a byte-encoded x coordinate value (32 bytes).
917963 pub fn serialize ( & self ) -> [ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] {
918964 let mut ret = [ 0u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] ;
@@ -1255,7 +1301,7 @@ impl<'de> serde::Deserialize<'de> for XOnlyPublicKey {
12551301 } else {
12561302 let visitor = super :: serde_util:: Tuple32Visitor :: new (
12571303 "raw 32 bytes schnorr public key" ,
1258- XOnlyPublicKey :: from_byte_array ,
1304+ XOnlyPublicKey :: parse_byte_array ,
12591305 ) ;
12601306 d. deserialize_tuple ( constants:: SCHNORR_PUBLIC_KEY_SIZE , visitor)
12611307 }
@@ -1348,7 +1394,7 @@ impl<'a> Arbitrary<'a> for XOnlyPublicKey {
13481394 }
13491395
13501396 u. fill_buffer ( & mut bytes[ ..] ) ?;
1351- if let Ok ( pk) = XOnlyPublicKey :: from_byte_array ( bytes) {
1397+ if let Ok ( pk) = XOnlyPublicKey :: parse_byte_array ( bytes) {
13521398 return Ok ( pk) ;
13531399 }
13541400 }
@@ -1998,7 +2044,7 @@ mod test {
19982044 let pk = PublicKey :: from_slice ( & pk_bytes) . expect ( "failed to create pk from iterator" ) ;
19992045 let kp = Keypair :: from_secret_key ( & sk) ;
20002046 let xonly =
2001- XOnlyPublicKey :: from_byte_array ( PK_BYTES ) . expect ( "failed to get xonly from slice" ) ;
2047+ XOnlyPublicKey :: parse_byte_array ( PK_BYTES ) . expect ( "failed to get xonly from slice" ) ;
20022048
20032049 ( sk, pk, kp, xonly)
20042050 }
0 commit comments