Merge rust-bitcoin/rust-secp256k1#737: Deprecate from_slice methods in favor of arrays
537b85b793
Deprecate and replace `from_slice` (Jamil Lambert, PhD)1661f57d84
Add `from_byte_array` functions (Jamil Lambert, PhD) Pull request description: As brought up in issue https://github.com/rust-bitcoin/rust-bitcoin/issues/3102 support for Rust arrays is now much better so slice-accepting methods that require a fixed length can be replaced with a method that accepts an array. `from_slice()` methods have been deprecated and calls to it from within the crate have been changed to use the equivalent array method. ACKs for top commit: apoelstra: ACK537b85b793
successfully ran local tests tcharding: ACK537b85b793
Kixunil: ACK537b85b793
Tree-SHA512: 8f8f807af0032130b64a93ff86cae0df1ccee83de052603968be9e30751c27dfc763a6128472e6d0f3a5c2016e7da8e4d06eefc86d8310bdaacc6be0f8fe3822
This commit is contained in:
commit
3453adb7c5
|
@ -64,6 +64,7 @@ impl SharedSecret {
|
||||||
pub fn from_bytes(bytes: [u8; SHARED_SECRET_SIZE]) -> SharedSecret { SharedSecret(bytes) }
|
pub fn from_bytes(bytes: [u8; SHARED_SECRET_SIZE]) -> SharedSecret { SharedSecret(bytes) }
|
||||||
|
|
||||||
/// Creates a shared secret from `bytes` slice.
|
/// Creates a shared secret from `bytes` slice.
|
||||||
|
#[deprecated(since = "TBD", note = "Use `from_bytes` instead.")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(bytes: &[u8]) -> Result<SharedSecret, Error> {
|
pub fn from_slice(bytes: &[u8]) -> Result<SharedSecret, Error> {
|
||||||
match bytes.len() {
|
match bytes.len() {
|
||||||
|
|
113
src/key.rs
113
src/key.rs
|
@ -115,7 +115,7 @@ impl str::FromStr for SecretKey {
|
||||||
fn from_str(s: &str) -> Result<SecretKey, Error> {
|
fn from_str(s: &str) -> Result<SecretKey, Error> {
|
||||||
let mut res = [0u8; constants::SECRET_KEY_SIZE];
|
let mut res = [0u8; constants::SECRET_KEY_SIZE];
|
||||||
match from_hex(s, &mut res) {
|
match from_hex(s, &mut res) {
|
||||||
Ok(constants::SECRET_KEY_SIZE) => SecretKey::from_slice(&res),
|
Ok(constants::SECRET_KEY_SIZE) => SecretKey::from_byte_array(&res),
|
||||||
_ => Err(Error::InvalidSecretKey),
|
_ => Err(Error::InvalidSecretKey),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ impl str::FromStr for SecretKey {
|
||||||
/// use secp256k1::{SecretKey, Secp256k1, PublicKey};
|
/// use secp256k1::{SecretKey, Secp256k1, PublicKey};
|
||||||
///
|
///
|
||||||
/// let secp = Secp256k1::new();
|
/// let secp = Secp256k1::new();
|
||||||
/// let secret_key = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
|
/// let secret_key = SecretKey::from_byte_array(&[0xcd; 32]).expect("32 bytes, within curve order");
|
||||||
/// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
|
/// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -168,9 +168,13 @@ impl str::FromStr for PublicKey {
|
||||||
fn from_str(s: &str) -> Result<PublicKey, Error> {
|
fn from_str(s: &str) -> Result<PublicKey, Error> {
|
||||||
let mut res = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
|
let mut res = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
|
||||||
match from_hex(s, &mut res) {
|
match from_hex(s, &mut res) {
|
||||||
Ok(constants::PUBLIC_KEY_SIZE) =>
|
Ok(constants::PUBLIC_KEY_SIZE) => {
|
||||||
PublicKey::from_slice(&res[0..constants::PUBLIC_KEY_SIZE]),
|
let bytes: [u8; constants::PUBLIC_KEY_SIZE] =
|
||||||
Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) => PublicKey::from_slice(&res),
|
res[0..constants::PUBLIC_KEY_SIZE].try_into().unwrap();
|
||||||
|
PublicKey::from_byte_array_compressed(&bytes)
|
||||||
|
}
|
||||||
|
Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) =>
|
||||||
|
PublicKey::from_byte_array_uncompressed(&res),
|
||||||
_ => Err(Error::InvalidPublicKey),
|
_ => Err(Error::InvalidPublicKey),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +207,7 @@ impl SecretKey {
|
||||||
SecretKey(data)
|
SecretKey(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a `SECRET_KEY_SIZE`-byte slice to a secret key.
|
/// Converts a 32-byte slice to a secret key.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -211,25 +215,35 @@ impl SecretKey {
|
||||||
/// use secp256k1::SecretKey;
|
/// use secp256k1::SecretKey;
|
||||||
/// let sk = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
|
/// let sk = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
|
||||||
/// ```
|
/// ```
|
||||||
|
#[deprecated(since = "TBD", note = "Use `from_byte_array` instead.")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(data: &[u8]) -> Result<SecretKey, Error> {
|
pub fn from_slice(data: &[u8]) -> Result<SecretKey, Error> {
|
||||||
match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
|
match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
|
||||||
Ok(data) => {
|
Ok(data) => Self::from_byte_array(&data),
|
||||||
unsafe {
|
|
||||||
if ffi::secp256k1_ec_seckey_verify(
|
|
||||||
ffi::secp256k1_context_no_precomp,
|
|
||||||
data.as_c_ptr(),
|
|
||||||
) == 0
|
|
||||||
{
|
|
||||||
return Err(InvalidSecretKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(SecretKey(data))
|
|
||||||
}
|
|
||||||
Err(_) => Err(InvalidSecretKey),
|
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`].
|
/// Creates a new secret key using data from BIP-340 [`Keypair`].
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -353,7 +367,7 @@ impl SecretKey {
|
||||||
impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
|
impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
|
||||||
/// Converts a 32-byte hash directly to a secret key without error paths.
|
/// Converts a 32-byte hash directly to a secret key without error paths.
|
||||||
fn from(t: T) -> SecretKey {
|
fn from(t: T) -> SecretKey {
|
||||||
SecretKey::from_slice(&t.into_32()).expect("failed to create secret key")
|
SecretKey::from_byte_array(&t.into_32()).expect("failed to create secret key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,17 +456,50 @@ impl PublicKey {
|
||||||
/// Creates a public key directly from a slice.
|
/// Creates a public key directly from a slice.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> {
|
pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> {
|
||||||
if data.is_empty() {
|
match data.len() {
|
||||||
return Err(Error::InvalidPublicKey);
|
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 {
|
unsafe {
|
||||||
let mut pk = ffi::PublicKey::new();
|
let mut pk = ffi::PublicKey::new();
|
||||||
if ffi::secp256k1_ec_pubkey_parse(
|
if ffi::secp256k1_ec_pubkey_parse(
|
||||||
ffi::secp256k1_context_no_precomp,
|
ffi::secp256k1_context_no_precomp,
|
||||||
&mut pk,
|
&mut pk,
|
||||||
data.as_c_ptr(),
|
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
|
) == 1
|
||||||
{
|
{
|
||||||
Ok(PublicKey(pk))
|
Ok(PublicKey(pk))
|
||||||
|
@ -500,7 +547,7 @@ impl PublicKey {
|
||||||
};
|
};
|
||||||
buf[1..].clone_from_slice(&pk.serialize());
|
buf[1..].clone_from_slice(&pk.serialize());
|
||||||
|
|
||||||
PublicKey::from_slice(&buf).expect("we know the buffer is valid")
|
PublicKey::from_byte_array_compressed(&buf).expect("we know the buffer is valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1114,8 +1161,7 @@ impl str::FromStr for XOnlyPublicKey {
|
||||||
fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
|
fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
|
||||||
let mut res = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
|
let mut res = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
|
||||||
match from_hex(s, &mut res) {
|
match from_hex(s, &mut res) {
|
||||||
Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) =>
|
Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) => XOnlyPublicKey::from_byte_array(&res),
|
||||||
XOnlyPublicKey::from_slice(&res[0..constants::SCHNORR_PUBLIC_KEY_SIZE]),
|
|
||||||
_ => Err(Error::InvalidPublicKey),
|
_ => Err(Error::InvalidPublicKey),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1161,12 +1207,25 @@ impl XOnlyPublicKey {
|
||||||
///
|
///
|
||||||
/// Returns [`Error::InvalidPublicKey`] if the length of the data slice is not 32 bytes or the
|
/// Returns [`Error::InvalidPublicKey`] if the length of the data slice is not 32 bytes or the
|
||||||
/// slice does not represent a valid Secp256k1 point x coordinate.
|
/// slice does not represent a valid Secp256k1 point x coordinate.
|
||||||
|
#[deprecated(since = "TBD", note = "Use `from_byte_array` instead.")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
|
pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
|
||||||
if data.is_empty() || data.len() != constants::SCHNORR_PUBLIC_KEY_SIZE {
|
match <[u8; constants::SCHNORR_PUBLIC_KEY_SIZE]>::try_from(data) {
|
||||||
return Err(Error::InvalidPublicKey);
|
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 {
|
unsafe {
|
||||||
let mut pk = ffi::XOnlyPublicKey::new();
|
let mut pk = ffi::XOnlyPublicKey::new();
|
||||||
if ffi::secp256k1_xonly_pubkey_parse(
|
if ffi::secp256k1_xonly_pubkey_parse(
|
||||||
|
|
|
@ -78,6 +78,7 @@ impl Signature {
|
||||||
pub fn from_byte_array(sig: [u8; constants::SCHNORR_SIGNATURE_SIZE]) -> Self { Self(sig) }
|
pub fn from_byte_array(sig: [u8; constants::SCHNORR_SIGNATURE_SIZE]) -> Self { Self(sig) }
|
||||||
|
|
||||||
/// Creates a `Signature` directly from a slice.
|
/// Creates a `Signature` directly from a slice.
|
||||||
|
#[deprecated(since = "TBD", note = "Use `from_byte_array` instead.")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(data: &[u8]) -> Result<Signature, Error> {
|
pub fn from_slice(data: &[u8]) -> Result<Signature, Error> {
|
||||||
match data.len() {
|
match data.len() {
|
||||||
|
|
Loading…
Reference in New Issue