Merge rust-bitcoin/rust-bitcoin#4189: Private key from slice fix

ecc5791930 Add test checking `XOnlyPublicKey::deserialize` (Martin Habovstiak)
bbe87eccf2 Fix bug in PSBT `Deserialize` for `XOnlyPublicKey` (Martin Habovstiak)
8efacd4dda Deprecate `PrivateKey::from_slice` method (Martin Habovstiak)
0d5cd7af43 Add `from_byte_array` to `PrivateKey`. (Martin Habovstiak)
1778fea66e Add a test checking `PrivateKey::from_slice` (Martin Habovstiak)
b87ddc0043 Don't panic in `PrivateKey::from_slice` (Martin Habovstiak)

Pull request description:

  This fixes the bug introduced in #4154 and deprecates `from_slice` method in favor of `from_byte_array` (see commits).

  Closes #4191

ACKs for top commit:
  jamillambert:
    ACK ecc5791930
  apoelstra:
    ACK ecc5791930b88581fcbc8f2417b0221486bd1031; successfully ran local tests

Tree-SHA512: 05117c68db7b46605dba6104ee7696220416f4efaef1fff01843a910037e4c96bfebc45fcdd16f875e5e800bb33af17193c4aa9b0b1593807df5153e7e935c22
This commit is contained in:
merge-script 2025-03-05 23:07:23 +00:00
commit 5ea4eac442
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 27 additions and 7 deletions

View File

@ -459,17 +459,22 @@ impl PrivateKey {
/// Serializes the private key to bytes.
pub fn to_vec(self) -> Vec<u8> { self.inner[..].to_vec() }
/// Deserializes a private key from a byte array.
pub fn from_byte_array(
data: [u8; 32],
network: impl Into<NetworkKind>
) -> Result<PrivateKey, secp256k1::Error> {
Ok(PrivateKey::new(secp256k1::SecretKey::from_byte_array(&data)?, network))
}
/// Deserializes a private key from a slice.
#[deprecated(since = "TBD", note = "use from_byte_array instead")]
pub fn from_slice(
data: &[u8],
network: impl Into<NetworkKind>,
) -> Result<PrivateKey, secp256k1::Error> {
Ok(PrivateKey::new(
secp256k1::SecretKey::from_byte_array(
data[..32].try_into().expect("Slice should be exactly 32 bytes"),
)?,
network,
))
let array = data.try_into().map_err(|_| secp256k1::Error::InvalidSecretKey)?;
Self::from_byte_array(array, network)
}
/// Formats the private key to WIF format.
@ -1600,4 +1605,13 @@ mod tests {
panic!("Expected Invalid char error");
}
}
#[test]
#[allow(deprecated)] // tests the deprecated function
#[allow(deprecated_in_future)]
fn invalid_private_key_len() {
use crate::Network;
assert!(PrivateKey::from_slice(&[1u8; 31], Network::Regtest).is_err());
assert!(PrivateKey::from_slice(&[1u8; 33], Network::Regtest).is_err());
}
}

View File

@ -261,7 +261,7 @@ impl Serialize for XOnlyPublicKey {
impl Deserialize for XOnlyPublicKey {
fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
XOnlyPublicKey::from_byte_array(
bytes[..32].try_into().expect("statistically impossible to hit"),
bytes.try_into().map_err(|_| Error::InvalidXOnlyPublicKey)?,
)
.map_err(|_| Error::InvalidXOnlyPublicKey)
}
@ -461,6 +461,12 @@ mod tests {
assert!(sighash.is_ok())
}
#[test]
fn deserialize_xonly_public_key_len() {
assert!(XOnlyPublicKey::deserialize(&[1; 31]).is_err());
assert!(XOnlyPublicKey::deserialize(&[1; 33]).is_err());
}
#[test]
#[should_panic(expected = "InvalidMagic")]
fn invalid_vector_1() {