Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Message constructors #644

Merged
merged 1 commit into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/sign_verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn verify<C: Verification>(
pubkey: [u8; 33],
) -> Result<bool, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(msg.as_ref())?;
let msg = Message::from_digest_slice(msg.as_ref())?;
let sig = ecdsa::Signature::from_compact(&sig)?;
let pubkey = PublicKey::from_slice(&pubkey)?;

Expand All @@ -24,7 +24,7 @@ fn sign<C: Signing>(
seckey: [u8; 32],
) -> Result<ecdsa::Signature, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(msg.as_ref())?;
let msg = Message::from_digest_slice(msg.as_ref())?;
let seckey = SecretKey::from_slice(&seckey)?;
Ok(secp.sign_ecdsa(&msg, &seckey))
}
Expand Down
4 changes: 2 additions & 2 deletions examples/sign_verify_recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn recover<C: Verification>(
recovery_id: u8,
) -> Result<PublicKey, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(msg.as_ref())?;
let msg = Message::from_digest_slice(msg.as_ref())?;
let id = ecdsa::RecoveryId::from_i32(recovery_id as i32)?;
let sig = ecdsa::RecoverableSignature::from_compact(&sig, id)?;

Expand All @@ -24,7 +24,7 @@ fn sign_recovery<C: Signing>(
seckey: [u8; 32],
) -> Result<ecdsa::RecoverableSignature, Error> {
let msg = sha256::Hash::hash(msg);
let msg = Message::from_slice(msg.as_ref())?;
let msg = Message::from_digest_slice(msg.as_ref())?;
let seckey = SecretKey::from_slice(&seckey)?;
Ok(secp.sign_ecdsa_recoverable(&msg, &seckey))
}
Expand Down
4 changes: 2 additions & 2 deletions no_std_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
secp.randomize(&mut FakeRng);
let secret_key = SecretKey::new(&mut FakeRng);
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");

let sig = secp.sign_ecdsa(&message, &secret_key);
assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
Expand All @@ -119,7 +119,7 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
{
let secp_alloc = Secp256k1::new();
let public_key = PublicKey::from_secret_key(&secp_alloc, &secret_key);
let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");

let sig = secp_alloc.sign_ecdsa(&message, &secret_key);
assert!(secp_alloc.verify_ecdsa(&message, &sig, &public_key).is_ok());
Expand Down
4 changes: 2 additions & 2 deletions src/ecdsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,11 @@ impl<C: Verification> Secp256k1<C> {
/// # let secp = Secp256k1::new();
/// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
/// #
/// let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
/// let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
/// let sig = secp.sign_ecdsa(&message, &secret_key);
/// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
///
/// let message = Message::from_slice(&[0xcd; 32]).expect("32 bytes");
/// let message = Message::from_digest_slice(&[0xcd; 32]).expect("32 bytes");
/// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(Error::IncorrectSignature));
/// # }
/// ```
Expand Down
18 changes: 9 additions & 9 deletions src/ecdsa/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ mod tests {
let full = Secp256k1::new();

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

// Try key generation
let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
Expand Down Expand Up @@ -258,7 +258,7 @@ mod tests {
s.randomize(&mut rand::thread_rng());

let sk = SecretKey::from_slice(&ONE).unwrap();
let msg = Message::from_slice(&ONE).unwrap();
let msg = Message::from_digest_slice(&ONE).unwrap();

let sig = s.sign_ecdsa_recoverable(&msg, &sk);

Expand All @@ -283,7 +283,7 @@ mod tests {
s.randomize(&mut rand::thread_rng());

let sk = SecretKey::from_slice(&ONE).unwrap();
let msg = Message::from_slice(&ONE).unwrap();
let msg = Message::from_digest_slice(&ONE).unwrap();
let noncedata = [42u8; 32];

let sig = s.sign_ecdsa_recoverable_with_noncedata(&msg, &sk, &noncedata);
Expand All @@ -307,15 +307,15 @@ mod tests {
s.randomize(&mut rand::thread_rng());

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());

let sigr = s.sign_ecdsa_recoverable(&msg, &sk);
let sig = sigr.to_standard();

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));

let recovered_key = s.recover_ecdsa(&msg, &sigr).unwrap();
Expand All @@ -329,7 +329,7 @@ mod tests {
s.randomize(&mut rand::thread_rng());

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());

Expand All @@ -345,7 +345,7 @@ mod tests {
s.randomize(&mut rand::thread_rng());

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

let noncedata = [42u8; 32];

Expand All @@ -362,7 +362,7 @@ mod tests {
let mut s = Secp256k1::new();
s.randomize(&mut rand::thread_rng());

let msg = Message::from_slice(&[0x55; 32]).unwrap();
let msg = Message::from_digest_slice(&[0x55; 32]).unwrap();

// Zero is not a valid sig
let sig = RecoverableSignature::from_compact(&[0; 64], RecoveryId(0)).unwrap();
Expand Down Expand Up @@ -433,7 +433,7 @@ mod benches {
pub fn bench_recover(bh: &mut Bencher) {
let s = Secp256k1::new();
let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
let (sk, _) = s.generate_keypair(&mut rand::thread_rng());
let sig = s.sign_ecdsa_recoverable(&msg, &sk);

Expand Down
82 changes: 56 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
//! let public_key = PublicKey::from_secret_key(&secp, &secret_key);
//! // This is unsafe unless the supplied byte slice is the output of a cryptographic hash function.
//! // See the above example for how to use this library together with `bitcoin-hashes-std`.
//! let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
//! let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
//!
//! let sig = secp.sign_ecdsa(&message, &secret_key);
//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
Expand All @@ -93,7 +93,7 @@
//! 0x3a, 0x17, 0x10, 0xc9, 0x62, 0x67, 0x90, 0x63,
//! ]).expect("public keys must be 33 or 65 bytes, serialized according to SEC 2");
//!
//! let message = Message::from_slice(&[
//! let message = Message::from_digest_slice(&[
//! 0xaa, 0xdf, 0x7d, 0xe7, 0x82, 0x03, 0x4f, 0xbe,
//! 0x3d, 0x3d, 0xb2, 0xcb, 0x13, 0xc0, 0xcd, 0x91,
//! 0xbf, 0x41, 0xcb, 0x08, 0xfa, 0xc7, 0xbd, 0x61,
Expand Down Expand Up @@ -225,11 +225,41 @@ impl Message {
/// the result of signing isn't a
/// [secure signature](https://twitter.com/pwuille/status/1063582706288586752).
#[inline]
pub fn from_slice(data: &[u8]) -> Result<Message, Error> {
match data.len() {
#[deprecated(since = "0.28.0", note = "use from_digest_slice instead")]
pub fn from_slice(digest: &[u8]) -> Result<Message, Error> {
Message::from_digest_slice(digest)
}

/// Creates a [`Message`] from a `digest`.
///
/// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
///
/// The `digest` array has to be a cryptographically secure hash of the actual message that's
/// going to be signed. Otherwise the result of signing isn't a [secure signature].
///
/// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
#[inline]
pub fn from_digest(digest: [u8; 32]) -> Message { Message(digest) }

/// Creates a [`Message`] from a 32 byte slice `digest`.
///
/// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
///
/// The slice has to be 32 bytes long and be a cryptographically secure hash of the actual
/// message that's going to be signed. Otherwise the result of signing isn't a [secure
/// signature].
///
/// # Errors
///
/// If `digest` is not exactly 32 bytes long.
///
/// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
#[inline]
pub fn from_digest_slice(digest: &[u8]) -> Result<Message, Error> {
match digest.len() {
constants::MESSAGE_SIZE => {
let mut ret = [0u8; constants::MESSAGE_SIZE];
ret[..].copy_from_slice(data);
ret[..].copy_from_slice(digest);
Ok(Message(ret))
}
_ => Err(Error::InvalidMessage),
Expand Down Expand Up @@ -540,7 +570,7 @@ mod tests {
Secp256k1 { ctx: ctx_vrfy, phantom: PhantomData };

let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
let msg = Message::from_slice(&[2u8; 32]).unwrap();
let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
// Try signing
assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
let sig = full.sign_ecdsa(&msg, &sk);
Expand Down Expand Up @@ -572,7 +602,7 @@ mod tests {
let mut vrfy = unsafe { Secp256k1::from_raw_verification_only(ctx_vrfy.ctx) };

let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
let msg = Message::from_slice(&[2u8; 32]).unwrap();
let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
// Try signing
assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
let sig = full.sign_ecdsa(&msg, &sk);
Expand Down Expand Up @@ -618,7 +648,7 @@ mod tests {
// println!("{:?}", buf_ful[5]); // Can't even read the data thanks to the borrow checker.

let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
let msg = Message::from_slice(&[2u8; 32]).unwrap();
let msg = Message::from_digest_slice(&[2u8; 32]).unwrap();
// Try signing
assert_eq!(sign.sign_ecdsa(&msg, &sk), full.sign_ecdsa(&msg, &sk));
let sig = full.sign_ecdsa(&msg, &sk);
Expand All @@ -636,7 +666,7 @@ mod tests {
let full = Secp256k1::new();

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

// Try key generation
let (sk, pk) = full.generate_keypair(&mut rand::thread_rng());
Expand Down Expand Up @@ -665,7 +695,7 @@ mod tests {

for _ in 0..100 {
let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

let (sk, _) = s.generate_keypair(&mut rand::thread_rng());
let sig1 = s.sign_ecdsa(&msg, &sk);
Expand Down Expand Up @@ -756,7 +786,7 @@ mod tests {
let noncedata = [42u8; 32];
for _ in 0..100 {
let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
let sig = s.sign_ecdsa(&msg, &sk);
Expand Down Expand Up @@ -803,7 +833,7 @@ mod tests {
wild_msgs[1][0] -= 1;

for key in wild_keys.iter().map(|k| SecretKey::from_slice(&k[..]).unwrap()) {
for msg in wild_msgs.iter().map(|m| Message::from_slice(&m[..]).unwrap()) {
for msg in wild_msgs.iter().map(|m| Message::from_digest_slice(&m[..]).unwrap()) {
let sig = s.sign_ecdsa(&msg, &key);
let low_r_sig = s.sign_ecdsa_low_r(&msg, &key);
let grind_r_sig = s.sign_ecdsa_grind_r(&msg, &key, 1);
Expand All @@ -822,14 +852,14 @@ mod tests {
s.randomize(&mut rand::thread_rng());

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();

let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());

let sig = s.sign_ecdsa(&msg, &sk);

let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
}

Expand All @@ -845,15 +875,15 @@ mod tests {
);

assert_eq!(
Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]),
Message::from_digest_slice(&[0; constants::MESSAGE_SIZE - 1]),
Err(Error::InvalidMessage)
);
assert_eq!(
Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]),
Message::from_digest_slice(&[0; constants::MESSAGE_SIZE + 1]),
Err(Error::InvalidMessage)
);
assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
assert!(Message::from_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
assert!(Message::from_digest_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
assert!(Message::from_digest_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
}

#[test]
Expand Down Expand Up @@ -892,7 +922,7 @@ mod tests {
fn test_noncedata() {
let secp = Secp256k1::new();
let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
let noncedata = [42u8; 32];
let sk =
SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
Expand All @@ -919,7 +949,7 @@ mod tests {
let secp = Secp256k1::new();
let mut sig = ecdsa::Signature::from_der(&sig[..]).unwrap();
let pk = PublicKey::from_slice(&pk[..]).unwrap();
let msg = Message::from_slice(&msg[..]).unwrap();
let msg = Message::from_digest_slice(&msg[..]).unwrap();

// without normalization we expect this will fail
assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
Expand All @@ -934,7 +964,7 @@ mod tests {
fn test_low_r() {
let secp = Secp256k1::new();
let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
let sk =
SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
.unwrap();
Expand All @@ -952,7 +982,7 @@ mod tests {
fn test_grind_r() {
let secp = Secp256k1::new();
let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167");
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
let sk =
SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b")
.unwrap();
Expand All @@ -972,7 +1002,7 @@ mod tests {

let s = Secp256k1::new();

let msg = Message::from_slice(&[1; 32]).unwrap();
let msg = Message::from_digest_slice(&[1; 32]).unwrap();
let sk = SecretKey::from_slice(&[2; 32]).unwrap();
let sig = s.sign_ecdsa(&msg, &sk);
static SIG_BYTES: [u8; 71] = [
Expand Down Expand Up @@ -1002,7 +1032,7 @@ mod tests {
let sk_data = hex!("e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641");
let sk = SecretKey::from_slice(&sk_data).unwrap();
let msg_data = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
let msg = Message::from_slice(&msg_data).unwrap();
let msg = Message::from_digest_slice(&msg_data).unwrap();

// Check usage as explicit parameter
let pk = PublicKey::from_secret_key(SECP256K1, &sk);
Expand Down Expand Up @@ -1054,7 +1084,7 @@ mod benches {
pub fn bench_sign_ecdsa(bh: &mut Bencher) {
let s = Secp256k1::new();
let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
let (sk, _) = s.generate_keypair(&mut rand::thread_rng());

bh.iter(|| {
Expand All @@ -1067,7 +1097,7 @@ mod benches {
pub fn bench_verify_ecdsa(bh: &mut Bencher) {
let s = Secp256k1::new();
let msg = crate::random_32_bytes(&mut rand::thread_rng());
let msg = Message::from_slice(&msg).unwrap();
let msg = Message::from_digest_slice(&msg).unwrap();
let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
let sig = s.sign_ecdsa(&msg, &sk);

Expand Down
Loading
Loading