Skip to content

Commit

Permalink
refactor: Create keys from owned array values
Browse files Browse the repository at this point in the history
I updated the constructors to take owned array values of the form
[u8; LEN] instead of taking array references of the form &[u8; LEN].
This makes the constructors more canonical. Already in this commit,
I could remove a bunch of calls to `&` or `*`.

Because this is a breaking change, I added an entry to the changelog.
  • Loading branch information
uncomputable committed Feb 17, 2025
1 parent e7eea32 commit 8bd7f30
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 20 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Next

* Create keys from owned array values instead of from references [#781](https://github.com/rust-bitcoin/rust-secp256k1/pull/781)

# 0.30.0 - 2024-10-08

* Allow signing variable-length messages [#706](https://github.com/rust-bitcoin/rust-secp256k1/pull/706)
Expand Down
40 changes: 20 additions & 20 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl str::FromStr for SecretKey {
fn from_str(s: &str) -> Result<SecretKey, Error> {
let mut res = [0u8; constants::SECRET_KEY_SIZE];
match from_hex(s, &mut res) {
Ok(constants::SECRET_KEY_SIZE) => SecretKey::from_byte_array(&res),
Ok(constants::SECRET_KEY_SIZE) => SecretKey::from_byte_array(res),
_ => Err(Error::InvalidSecretKey),
}
}
Expand All @@ -138,7 +138,7 @@ impl str::FromStr for SecretKey {
/// use secp256k1::{SecretKey, Secp256k1, PublicKey};
///
/// let secp = Secp256k1::new();
/// let secret_key = SecretKey::from_byte_array(&[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);
/// # }
/// ```
Expand Down Expand Up @@ -175,10 +175,10 @@ impl str::FromStr for PublicKey {
Ok(constants::PUBLIC_KEY_SIZE) => {
let bytes: [u8; constants::PUBLIC_KEY_SIZE] =
res[0..constants::PUBLIC_KEY_SIZE].try_into().unwrap();
PublicKey::from_byte_array_compressed(&bytes)
PublicKey::from_byte_array_compressed(bytes)
}
Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) =>
PublicKey::from_byte_array_uncompressed(&res),
PublicKey::from_byte_array_uncompressed(res),
_ => Err(Error::InvalidPublicKey),
}
}
Expand Down Expand Up @@ -223,7 +223,7 @@ impl SecretKey {
#[inline]
pub fn from_slice(data: &[u8]) -> Result<SecretKey, Error> {
match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
Ok(data) => Self::from_byte_array(&data),
Ok(data) => Self::from_byte_array(data),
Err(_) => Err(InvalidSecretKey),
}
}
Expand All @@ -234,18 +234,18 @@ impl SecretKey {
///
/// ```
/// use secp256k1::SecretKey;
/// let sk = SecretKey::from_byte_array(&[0xcd; 32]).expect("32 bytes, within curve order");
/// 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> {
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))
Ok(SecretKey(data))
}

/// Creates a new secret key using data from BIP-340 [`Keypair`].
Expand Down Expand Up @@ -373,7 +373,7 @@ impl SecretKey {
impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
/// Converts a 32-byte hash directly to a secret key without error paths.
fn from(t: T) -> SecretKey {
SecretKey::from_byte_array(&t.into_32()).expect("failed to create secret key")
SecretKey::from_byte_array(t.into_32()).expect("failed to create secret key")
}
}

Expand Down Expand Up @@ -403,7 +403,7 @@ impl<'de> serde::Deserialize<'de> for SecretKey {
} else {
let visitor =
super::serde_util::Tuple32Visitor::new("raw 32 bytes SecretKey", |bytes| {
SecretKey::from_byte_array(&bytes)
SecretKey::from_byte_array(bytes)
});
d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor)
}
Expand Down Expand Up @@ -464,10 +464,10 @@ impl PublicKey {
pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> {
match data.len() {
constants::PUBLIC_KEY_SIZE => PublicKey::from_byte_array_compressed(
&<[u8; constants::PUBLIC_KEY_SIZE]>::try_from(data).unwrap(),
<[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(),
<[u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]>::try_from(data).unwrap(),
),
_ => Err(InvalidPublicKey),
}
Expand All @@ -476,7 +476,7 @@ impl PublicKey {
/// Creates a public key from a serialized array in compressed format.
#[inline]
pub fn from_byte_array_compressed(
data: &[u8; constants::PUBLIC_KEY_SIZE],
data: [u8; constants::PUBLIC_KEY_SIZE],
) -> Result<PublicKey, Error> {
unsafe {
let mut pk = ffi::PublicKey::new();
Expand All @@ -497,7 +497,7 @@ impl PublicKey {
/// 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],
data: [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE],
) -> Result<PublicKey, Error> {
unsafe {
let mut pk = ffi::PublicKey::new();
Expand Down Expand Up @@ -553,7 +553,7 @@ impl PublicKey {
};
buf[1..].clone_from_slice(&pk.serialize());

PublicKey::from_byte_array_compressed(&buf).expect("we know the buffer is valid")
PublicKey::from_byte_array_compressed(buf).expect("we know the buffer is valid")
}

#[inline]
Expand Down Expand Up @@ -792,7 +792,7 @@ impl<'de> serde::Deserialize<'de> for PublicKey {
} else {
let visitor =
super::serde_util::Tuple33Visitor::new("33 bytes compressed public key", |bytes| {
PublicKey::from_byte_array_compressed(&bytes)
PublicKey::from_byte_array_compressed(bytes)
});
d.deserialize_tuple(constants::PUBLIC_KEY_SIZE, visitor)
}
Expand Down Expand Up @@ -1193,7 +1193,7 @@ impl str::FromStr for XOnlyPublicKey {
fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
let mut res = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
match from_hex(s, &mut res) {
Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) => XOnlyPublicKey::from_byte_array(&res),
Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) => XOnlyPublicKey::from_byte_array(res),
_ => Err(Error::InvalidPublicKey),
}
}
Expand Down Expand Up @@ -1243,7 +1243,7 @@ impl XOnlyPublicKey {
#[inline]
pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
match <[u8; constants::SCHNORR_PUBLIC_KEY_SIZE]>::try_from(data) {
Ok(data) => Self::from_byte_array(&data),
Ok(data) => Self::from_byte_array(data),
Err(_) => Err(InvalidPublicKey),
}
}
Expand All @@ -1256,7 +1256,7 @@ impl XOnlyPublicKey {
/// x coordinate.
#[inline]
pub fn from_byte_array(
data: &[u8; constants::SCHNORR_PUBLIC_KEY_SIZE],
data: [u8; constants::SCHNORR_PUBLIC_KEY_SIZE],
) -> Result<XOnlyPublicKey, Error> {
unsafe {
let mut pk = ffi::XOnlyPublicKey::new();
Expand Down Expand Up @@ -1609,7 +1609,7 @@ impl<'de> serde::Deserialize<'de> for XOnlyPublicKey {
} else {
let visitor = super::serde_util::Tuple32Visitor::new(
"raw 32 bytes schnorr public key",
|bytes| XOnlyPublicKey::from_byte_array(&bytes),
|bytes| XOnlyPublicKey::from_byte_array(bytes),
);
d.deserialize_tuple(constants::SCHNORR_PUBLIC_KEY_SIZE, visitor)
}
Expand Down

0 comments on commit 8bd7f30

Please sign in to comment.