@@ -203,7 +203,7 @@ impl SecretKey {
203
203
SecretKey ( data)
204
204
}
205
205
206
- /// Converts a `SECRET_KEY_SIZE` -byte slice to a secret key.
206
+ /// Converts a 32 -byte slice to a secret key.
207
207
///
208
208
/// # Examples
209
209
///
@@ -214,22 +214,31 @@ impl SecretKey {
214
214
#[ inline]
215
215
pub fn from_slice ( data : & [ u8 ] ) -> Result < SecretKey , Error > {
216
216
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) ,
229
218
Err ( _) => Err ( InvalidSecretKey ) ,
230
219
}
231
220
}
232
221
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
+
233
242
/// Creates a new secret key using data from BIP-340 [`Keypair`].
234
243
///
235
244
/// # Examples
@@ -442,17 +451,50 @@ impl PublicKey {
442
451
/// Creates a public key directly from a slice.
443
452
#[ inline]
444
453
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
+ }
447
483
}
484
+ }
448
485
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 > {
449
491
unsafe {
450
492
let mut pk = ffi:: PublicKey :: new ( ) ;
451
493
if ffi:: secp256k1_ec_pubkey_parse (
452
494
ffi:: secp256k1_context_no_precomp,
453
495
& mut pk,
454
496
data. as_c_ptr ( ) ,
455
- data . len ( ) ,
497
+ constants :: UNCOMPRESSED_PUBLIC_KEY_SIZE ,
456
498
) == 1
457
499
{
458
500
Ok ( PublicKey ( pk) )
@@ -1163,10 +1205,22 @@ impl XOnlyPublicKey {
1163
1205
/// slice does not represent a valid Secp256k1 point x coordinate.
1164
1206
#[ inline]
1165
1207
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 ) ,
1168
1211
}
1212
+ }
1169
1213
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 > {
1170
1224
unsafe {
1171
1225
let mut pk = ffi:: XOnlyPublicKey :: new ( ) ;
1172
1226
if ffi:: secp256k1_xonly_pubkey_parse (
0 commit comments