@@ -203,7 +203,7 @@ impl SecretKey {
203203 SecretKey ( data)
204204 }
205205
206- /// Converts a `SECRET_KEY_SIZE` -byte slice to a secret key.
206+ /// Converts a 32 -byte slice to a secret key.
207207 ///
208208 /// # Examples
209209 ///
@@ -214,22 +214,31 @@ impl SecretKey {
214214 #[ inline]
215215 pub fn from_slice ( data : & [ u8 ] ) -> Result < SecretKey , Error > {
216216 match <[ u8 ; constants:: SECRET_KEY_SIZE ] >:: try_from ( data) {
217- Ok ( data) => {
218- unsafe {
219- if ffi:: secp256k1_ec_seckey_verify (
220- ffi:: secp256k1_context_no_precomp,
221- data. as_c_ptr ( ) ,
222- ) == 0
223- {
224- return Err ( InvalidSecretKey ) ;
225- }
226- }
227- Ok ( SecretKey ( data) )
228- }
217+ Ok ( data) => Self :: from_byte_array ( & data) ,
229218 Err ( _) => Err ( InvalidSecretKey ) ,
230219 }
231220 }
232221
222+ /// Converts a 32-byte array to a secret key.
223+ ///
224+ /// # Examples
225+ ///
226+ /// ```
227+ /// use secp256k1::SecretKey;
228+ /// let sk = SecretKey::from_byte_array(&[0xcd; 32]).expect("32 bytes, within curve order");
229+ /// ```
230+ #[ inline]
231+ pub fn from_byte_array ( data : & [ u8 ; constants:: SECRET_KEY_SIZE ] ) -> Result < SecretKey , Error > {
232+ unsafe {
233+ if ffi:: secp256k1_ec_seckey_verify ( ffi:: secp256k1_context_no_precomp, data. as_c_ptr ( ) )
234+ == 0
235+ {
236+ return Err ( InvalidSecretKey ) ;
237+ }
238+ }
239+ Ok ( SecretKey ( * data) )
240+ }
241+
233242 /// Creates a new secret key using data from BIP-340 [`Keypair`].
234243 ///
235244 /// # Examples
@@ -442,17 +451,50 @@ impl PublicKey {
442451 /// Creates a public key directly from a slice.
443452 #[ inline]
444453 pub fn from_slice ( data : & [ u8 ] ) -> Result < PublicKey , Error > {
445- if data. is_empty ( ) {
446- return Err ( Error :: InvalidPublicKey ) ;
454+ match data. len ( ) {
455+ constants:: PUBLIC_KEY_SIZE => PublicKey :: from_byte_array_compressed (
456+ & <[ u8 ; constants:: PUBLIC_KEY_SIZE ] >:: try_from ( data) . unwrap ( ) ,
457+ ) ,
458+ constants:: UNCOMPRESSED_PUBLIC_KEY_SIZE => PublicKey :: from_byte_array_uncompressed (
459+ & <[ u8 ; constants:: UNCOMPRESSED_PUBLIC_KEY_SIZE ] >:: try_from ( data) . unwrap ( ) ,
460+ ) ,
461+ _ => Err ( InvalidPublicKey ) ,
462+ }
463+ }
464+
465+ /// Creates a public key from a serialized array in compressed format.
466+ #[ inline]
467+ pub fn from_byte_array_compressed (
468+ data : & [ u8 ; constants:: PUBLIC_KEY_SIZE ] ,
469+ ) -> Result < PublicKey , Error > {
470+ unsafe {
471+ let mut pk = ffi:: PublicKey :: new ( ) ;
472+ if ffi:: secp256k1_ec_pubkey_parse (
473+ ffi:: secp256k1_context_no_precomp,
474+ & mut pk,
475+ data. as_c_ptr ( ) ,
476+ constants:: PUBLIC_KEY_SIZE ,
477+ ) == 1
478+ {
479+ Ok ( PublicKey ( pk) )
480+ } else {
481+ Err ( InvalidPublicKey )
482+ }
447483 }
484+ }
448485
486+ /// Creates a public key from a serialized array in uncompressed format.
487+ #[ inline]
488+ pub fn from_byte_array_uncompressed (
489+ data : & [ u8 ; constants:: UNCOMPRESSED_PUBLIC_KEY_SIZE ] ,
490+ ) -> Result < PublicKey , Error > {
449491 unsafe {
450492 let mut pk = ffi:: PublicKey :: new ( ) ;
451493 if ffi:: secp256k1_ec_pubkey_parse (
452494 ffi:: secp256k1_context_no_precomp,
453495 & mut pk,
454496 data. as_c_ptr ( ) ,
455- data . len ( ) ,
497+ constants :: UNCOMPRESSED_PUBLIC_KEY_SIZE ,
456498 ) == 1
457499 {
458500 Ok ( PublicKey ( pk) )
@@ -1163,10 +1205,22 @@ impl XOnlyPublicKey {
11631205 /// slice does not represent a valid Secp256k1 point x coordinate.
11641206 #[ inline]
11651207 pub fn from_slice ( data : & [ u8 ] ) -> Result < XOnlyPublicKey , Error > {
1166- if data. is_empty ( ) || data. len ( ) != constants:: SCHNORR_PUBLIC_KEY_SIZE {
1167- return Err ( Error :: InvalidPublicKey ) ;
1208+ match <[ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] >:: try_from ( data) {
1209+ Ok ( data) => Self :: from_byte_array ( & data) ,
1210+ Err ( _) => Err ( InvalidPublicKey ) ,
11681211 }
1212+ }
11691213
1214+ /// Creates a schnorr public key directly from a byte array.
1215+ ///
1216+ /// # Errors
1217+ ///
1218+ /// Returns [`Error::InvalidPublicKey`] if the array does not represent a valid Secp256k1 point
1219+ /// x coordinate.
1220+ #[ inline]
1221+ pub fn from_byte_array (
1222+ data : & [ u8 ; constants:: SCHNORR_PUBLIC_KEY_SIZE ] ,
1223+ ) -> Result < XOnlyPublicKey , Error > {
11701224 unsafe {
11711225 let mut pk = ffi:: XOnlyPublicKey :: new ( ) ;
11721226 if ffi:: secp256k1_xonly_pubkey_parse (
0 commit comments