Add `from_byte_array` functions
Functions have been added to PrivateKey, PublicKey and XOnlyPublicKey to allow the creation of a key directly from a byte array.
This commit is contained in:
		
							parent
							
								
									18654c30c6
								
							
						
					
					
						commit
						1661f57d84
					
				
							
								
								
									
										90
									
								
								src/key.rs
								
								
								
								
							
							
						
						
									
										90
									
								
								src/key.rs
								
								
								
								
							|  | @ -203,7 +203,7 @@ impl SecretKey { | |||
|         SecretKey(data) | ||||
|     } | ||||
| 
 | ||||
|     /// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key.
 | ||||
|     /// Converts a 32-byte slice to a secret key.
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|     ///
 | ||||
|  | @ -214,22 +214,31 @@ impl SecretKey { | |||
|     #[inline] | ||||
|     pub fn from_slice(data: &[u8]) -> Result<SecretKey, Error> { | ||||
|         match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) { | ||||
|             Ok(data) => { | ||||
|                 unsafe { | ||||
|                     if ffi::secp256k1_ec_seckey_verify( | ||||
|                         ffi::secp256k1_context_no_precomp, | ||||
|                         data.as_c_ptr(), | ||||
|                     ) == 0 | ||||
|                     { | ||||
|                         return Err(InvalidSecretKey); | ||||
|                     } | ||||
|                 } | ||||
|                 Ok(SecretKey(data)) | ||||
|             } | ||||
|             Ok(data) => Self::from_byte_array(&data), | ||||
|             Err(_) => Err(InvalidSecretKey), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Converts a 32-byte array to a secret key.
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|     ///
 | ||||
|     /// ```
 | ||||
|     /// use secp256k1::SecretKey;
 | ||||
|     /// let sk = SecretKey::from_byte_array(&[0xcd; 32]).expect("32 bytes, within curve order");
 | ||||
|     /// ```
 | ||||
|     #[inline] | ||||
|     pub fn from_byte_array(data: &[u8; constants::SECRET_KEY_SIZE]) -> Result<SecretKey, Error> { | ||||
|         unsafe { | ||||
|             if ffi::secp256k1_ec_seckey_verify(ffi::secp256k1_context_no_precomp, data.as_c_ptr()) | ||||
|                 == 0 | ||||
|             { | ||||
|                 return Err(InvalidSecretKey); | ||||
|             } | ||||
|         } | ||||
|         Ok(SecretKey(*data)) | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a new secret key using data from BIP-340 [`Keypair`].
 | ||||
|     ///
 | ||||
|     /// # Examples
 | ||||
|  | @ -442,17 +451,50 @@ impl PublicKey { | |||
|     /// Creates a public key directly from a slice.
 | ||||
|     #[inline] | ||||
|     pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> { | ||||
|         if data.is_empty() { | ||||
|             return Err(Error::InvalidPublicKey); | ||||
|         match data.len() { | ||||
|             constants::PUBLIC_KEY_SIZE => PublicKey::from_byte_array_compressed( | ||||
|                 &<[u8; constants::PUBLIC_KEY_SIZE]>::try_from(data).unwrap(), | ||||
|             ), | ||||
|             constants::UNCOMPRESSED_PUBLIC_KEY_SIZE => PublicKey::from_byte_array_uncompressed( | ||||
|                 &<[u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]>::try_from(data).unwrap(), | ||||
|             ), | ||||
|             _ => Err(InvalidPublicKey), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a public key from a serialized array in compressed format.
 | ||||
|     #[inline] | ||||
|     pub fn from_byte_array_compressed( | ||||
|         data: &[u8; constants::PUBLIC_KEY_SIZE], | ||||
|     ) -> Result<PublicKey, Error> { | ||||
|         unsafe { | ||||
|             let mut pk = ffi::PublicKey::new(); | ||||
|             if ffi::secp256k1_ec_pubkey_parse( | ||||
|                 ffi::secp256k1_context_no_precomp, | ||||
|                 &mut pk, | ||||
|                 data.as_c_ptr(), | ||||
|                 data.len(), | ||||
|                 constants::PUBLIC_KEY_SIZE, | ||||
|             ) == 1 | ||||
|             { | ||||
|                 Ok(PublicKey(pk)) | ||||
|             } else { | ||||
|                 Err(InvalidPublicKey) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a public key from a serialized array in uncompressed format.
 | ||||
|     #[inline] | ||||
|     pub fn from_byte_array_uncompressed( | ||||
|         data: &[u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE], | ||||
|     ) -> Result<PublicKey, Error> { | ||||
|         unsafe { | ||||
|             let mut pk = ffi::PublicKey::new(); | ||||
|             if ffi::secp256k1_ec_pubkey_parse( | ||||
|                 ffi::secp256k1_context_no_precomp, | ||||
|                 &mut pk, | ||||
|                 data.as_c_ptr(), | ||||
|                 constants::UNCOMPRESSED_PUBLIC_KEY_SIZE, | ||||
|             ) == 1 | ||||
|             { | ||||
|                 Ok(PublicKey(pk)) | ||||
|  | @ -1163,10 +1205,22 @@ impl XOnlyPublicKey { | |||
|     /// slice does not represent a valid Secp256k1 point x coordinate.
 | ||||
|     #[inline] | ||||
|     pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> { | ||||
|         if data.is_empty() || data.len() != constants::SCHNORR_PUBLIC_KEY_SIZE { | ||||
|             return Err(Error::InvalidPublicKey); | ||||
|         match <[u8; constants::SCHNORR_PUBLIC_KEY_SIZE]>::try_from(data) { | ||||
|             Ok(data) => Self::from_byte_array(&data), | ||||
|             Err(_) => Err(InvalidPublicKey), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a schnorr public key directly from a byte array.
 | ||||
|     ///
 | ||||
|     /// # Errors
 | ||||
|     ///
 | ||||
|     /// Returns [`Error::InvalidPublicKey`] if the array does not represent a valid Secp256k1 point
 | ||||
|     /// x coordinate.
 | ||||
|     #[inline] | ||||
|     pub fn from_byte_array( | ||||
|         data: &[u8; constants::SCHNORR_PUBLIC_KEY_SIZE], | ||||
|     ) -> Result<XOnlyPublicKey, Error> { | ||||
|         unsafe { | ||||
|             let mut pk = ffi::XOnlyPublicKey::new(); | ||||
|             if ffi::secp256k1_xonly_pubkey_parse( | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue