Skip to content

Commit 14e8218

Browse files
committed
Merge #644: Improve Message constructors
cd40ae7 Improve Message constructors (Tobin C. Harding) Pull request description: Observe: - The word "hash" can be a verb or a noun, its usage in function names is therefore at times ambiguous. - The function name `from_slice` gives no indication as to what the slice input is. Improve Message constructors by doing: - Add a constructor `Message::from_digest` that takes a 32 byte array as input. - Rename `Message::from_slice` to `Message::from_digest_slice` (deprecate `from_slice` and add `from_digest_slice`) - Improve the docs while we are at it. ### Note The original PR conflate 2 separate issues, the `Message` constructor naming clarity issue and the upgrade difficulty issue, PR is now only a solution to the first. The second will be done as a separate PR. ACKs for top commit: apoelstra: ACK cd40ae7 Tree-SHA512: 4e5aeccf15cca95073f4c3a518b9e1f54f0e33c92c45dfecd1daa31d052022cd28c71bb6df6cff8a6548993e3e22788f11cd2633214ab5a580c753e66d2ea749
2 parents 090f073 + cd40ae7 commit 14e8218

File tree

7 files changed

+77
-47
lines changed

7 files changed

+77
-47
lines changed

examples/sign_verify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn verify<C: Verification>(
1111
pubkey: [u8; 33],
1212
) -> Result<bool, Error> {
1313
let msg = sha256::Hash::hash(msg);
14-
let msg = Message::from_slice(msg.as_ref())?;
14+
let msg = Message::from_digest_slice(msg.as_ref())?;
1515
let sig = ecdsa::Signature::from_compact(&sig)?;
1616
let pubkey = PublicKey::from_slice(&pubkey)?;
1717

@@ -24,7 +24,7 @@ fn sign<C: Signing>(
2424
seckey: [u8; 32],
2525
) -> Result<ecdsa::Signature, Error> {
2626
let msg = sha256::Hash::hash(msg);
27-
let msg = Message::from_slice(msg.as_ref())?;
27+
let msg = Message::from_digest_slice(msg.as_ref())?;
2828
let seckey = SecretKey::from_slice(&seckey)?;
2929
Ok(secp.sign_ecdsa(&msg, &seckey))
3030
}

examples/sign_verify_recovery.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn recover<C: Verification>(
1111
recovery_id: u8,
1212
) -> Result<PublicKey, Error> {
1313
let msg = sha256::Hash::hash(msg);
14-
let msg = Message::from_slice(msg.as_ref())?;
14+
let msg = Message::from_digest_slice(msg.as_ref())?;
1515
let id = ecdsa::RecoveryId::from_i32(recovery_id as i32)?;
1616
let sig = ecdsa::RecoverableSignature::from_compact(&sig, id)?;
1717

@@ -24,7 +24,7 @@ fn sign_recovery<C: Signing>(
2424
seckey: [u8; 32],
2525
) -> Result<ecdsa::RecoverableSignature, Error> {
2626
let msg = sha256::Hash::hash(msg);
27-
let msg = Message::from_slice(msg.as_ref())?;
27+
let msg = Message::from_digest_slice(msg.as_ref())?;
2828
let seckey = SecretKey::from_slice(&seckey)?;
2929
Ok(secp.sign_ecdsa_recoverable(&msg, &seckey))
3030
}

no_std_test/src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
9191
secp.randomize(&mut FakeRng);
9292
let secret_key = SecretKey::new(&mut FakeRng);
9393
let public_key = PublicKey::from_secret_key(&secp, &secret_key);
94-
let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
94+
let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
9595

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

123123
let sig = secp_alloc.sign_ecdsa(&message, &secret_key);
124124
assert!(secp_alloc.verify_ecdsa(&message, &sig, &public_key).is_ok());

src/ecdsa/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -371,11 +371,11 @@ impl<C: Verification> Secp256k1<C> {
371371
/// # let secp = Secp256k1::new();
372372
/// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
373373
/// #
374-
/// let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
374+
/// let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
375375
/// let sig = secp.sign_ecdsa(&message, &secret_key);
376376
/// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Ok(()));
377377
///
378-
/// let message = Message::from_slice(&[0xcd; 32]).expect("32 bytes");
378+
/// let message = Message::from_digest_slice(&[0xcd; 32]).expect("32 bytes");
379379
/// assert_eq!(secp.verify_ecdsa(&message, &sig, &public_key), Err(Error::IncorrectSignature));
380380
/// # }
381381
/// ```

src/ecdsa/recovery.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ mod tests {
226226
let full = Secp256k1::new();
227227

228228
let msg = crate::random_32_bytes(&mut rand::thread_rng());
229-
let msg = Message::from_slice(&msg).unwrap();
229+
let msg = Message::from_digest_slice(&msg).unwrap();
230230

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

260260
let sk = SecretKey::from_slice(&ONE).unwrap();
261-
let msg = Message::from_slice(&ONE).unwrap();
261+
let msg = Message::from_digest_slice(&ONE).unwrap();
262262

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

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

285285
let sk = SecretKey::from_slice(&ONE).unwrap();
286-
let msg = Message::from_slice(&ONE).unwrap();
286+
let msg = Message::from_digest_slice(&ONE).unwrap();
287287
let noncedata = [42u8; 32];
288288

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

309309
let msg = crate::random_32_bytes(&mut rand::thread_rng());
310-
let msg = Message::from_slice(&msg).unwrap();
310+
let msg = Message::from_digest_slice(&msg).unwrap();
311311

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

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

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

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

331331
let msg = crate::random_32_bytes(&mut rand::thread_rng());
332-
let msg = Message::from_slice(&msg).unwrap();
332+
let msg = Message::from_digest_slice(&msg).unwrap();
333333

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

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

347347
let msg = crate::random_32_bytes(&mut rand::thread_rng());
348-
let msg = Message::from_slice(&msg).unwrap();
348+
let msg = Message::from_digest_slice(&msg).unwrap();
349349

350350
let noncedata = [42u8; 32];
351351

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

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

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

src/lib.rs

+56-26
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
//! let public_key = PublicKey::from_secret_key(&secp, &secret_key);
7171
//! // This is unsafe unless the supplied byte slice is the output of a cryptographic hash function.
7272
//! // See the above example for how to use this library together with `bitcoin-hashes-std`.
73-
//! let message = Message::from_slice(&[0xab; 32]).expect("32 bytes");
73+
//! let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
7474
//!
7575
//! let sig = secp.sign_ecdsa(&message, &secret_key);
7676
//! assert!(secp.verify_ecdsa(&message, &sig, &public_key).is_ok());
@@ -93,7 +93,7 @@
9393
//! 0x3a, 0x17, 0x10, 0xc9, 0x62, 0x67, 0x90, 0x63,
9494
//! ]).expect("public keys must be 33 or 65 bytes, serialized according to SEC 2");
9595
//!
96-
//! let message = Message::from_slice(&[
96+
//! let message = Message::from_digest_slice(&[
9797
//! 0xaa, 0xdf, 0x7d, 0xe7, 0x82, 0x03, 0x4f, 0xbe,
9898
//! 0x3d, 0x3d, 0xb2, 0xcb, 0x13, 0xc0, 0xcd, 0x91,
9999
//! 0xbf, 0x41, 0xcb, 0x08, 0xfa, 0xc7, 0xbd, 0x61,
@@ -225,11 +225,41 @@ impl Message {
225225
/// the result of signing isn't a
226226
/// [secure signature](https://twitter.com/pwuille/status/1063582706288586752).
227227
#[inline]
228-
pub fn from_slice(data: &[u8]) -> Result<Message, Error> {
229-
match data.len() {
228+
#[deprecated(since = "0.28.0", note = "use from_digest_slice instead")]
229+
pub fn from_slice(digest: &[u8]) -> Result<Message, Error> {
230+
Message::from_digest_slice(digest)
231+
}
232+
233+
/// Creates a [`Message`] from a `digest`.
234+
///
235+
/// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
236+
///
237+
/// The `digest` array has to be a cryptographically secure hash of the actual message that's
238+
/// going to be signed. Otherwise the result of signing isn't a [secure signature].
239+
///
240+
/// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
241+
#[inline]
242+
pub fn from_digest(digest: [u8; 32]) -> Message { Message(digest) }
243+
244+
/// Creates a [`Message`] from a 32 byte slice `digest`.
245+
///
246+
/// **If you just want to sign an arbitrary message use `Message::from_hashed_data` instead.**
247+
///
248+
/// The slice has to be 32 bytes long and be a cryptographically secure hash of the actual
249+
/// message that's going to be signed. Otherwise the result of signing isn't a [secure
250+
/// signature].
251+
///
252+
/// # Errors
253+
///
254+
/// If `digest` is not exactly 32 bytes long.
255+
///
256+
/// [secure signature]: https://twitter.com/pwuille/status/1063582706288586752
257+
#[inline]
258+
pub fn from_digest_slice(digest: &[u8]) -> Result<Message, Error> {
259+
match digest.len() {
230260
constants::MESSAGE_SIZE => {
231261
let mut ret = [0u8; constants::MESSAGE_SIZE];
232-
ret[..].copy_from_slice(data);
262+
ret[..].copy_from_slice(digest);
233263
Ok(Message(ret))
234264
}
235265
_ => Err(Error::InvalidMessage),
@@ -540,7 +570,7 @@ mod tests {
540570
Secp256k1 { ctx: ctx_vrfy, phantom: PhantomData };
541571

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

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

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

638668
let msg = crate::random_32_bytes(&mut rand::thread_rng());
639-
let msg = Message::from_slice(&msg).unwrap();
669+
let msg = Message::from_digest_slice(&msg).unwrap();
640670

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

666696
for _ in 0..100 {
667697
let msg = crate::random_32_bytes(&mut rand::thread_rng());
668-
let msg = Message::from_slice(&msg).unwrap();
698+
let msg = Message::from_digest_slice(&msg).unwrap();
669699

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

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

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

824854
let msg = crate::random_32_bytes(&mut rand::thread_rng());
825-
let msg = Message::from_slice(&msg).unwrap();
855+
let msg = Message::from_digest_slice(&msg).unwrap();
826856

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

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

831861
let msg = crate::random_32_bytes(&mut rand::thread_rng());
832-
let msg = Message::from_slice(&msg).unwrap();
862+
let msg = Message::from_digest_slice(&msg).unwrap();
833863
assert_eq!(s.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
834864
}
835865

@@ -845,15 +875,15 @@ mod tests {
845875
);
846876

847877
assert_eq!(
848-
Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]),
878+
Message::from_digest_slice(&[0; constants::MESSAGE_SIZE - 1]),
849879
Err(Error::InvalidMessage)
850880
);
851881
assert_eq!(
852-
Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]),
882+
Message::from_digest_slice(&[0; constants::MESSAGE_SIZE + 1]),
853883
Err(Error::InvalidMessage)
854884
);
855-
assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
856-
assert!(Message::from_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
885+
assert!(Message::from_digest_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
886+
assert!(Message::from_digest_slice(&[1; constants::MESSAGE_SIZE]).is_ok());
857887
}
858888

859889
#[test]
@@ -892,7 +922,7 @@ mod tests {
892922
fn test_noncedata() {
893923
let secp = Secp256k1::new();
894924
let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
895-
let msg = Message::from_slice(&msg).unwrap();
925+
let msg = Message::from_digest_slice(&msg).unwrap();
896926
let noncedata = [42u8; 32];
897927
let sk =
898928
SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
@@ -919,7 +949,7 @@ mod tests {
919949
let secp = Secp256k1::new();
920950
let mut sig = ecdsa::Signature::from_der(&sig[..]).unwrap();
921951
let pk = PublicKey::from_slice(&pk[..]).unwrap();
922-
let msg = Message::from_slice(&msg[..]).unwrap();
952+
let msg = Message::from_digest_slice(&msg[..]).unwrap();
923953

924954
// without normalization we expect this will fail
925955
assert_eq!(secp.verify_ecdsa(&msg, &sig, &pk), Err(Error::IncorrectSignature));
@@ -934,7 +964,7 @@ mod tests {
934964
fn test_low_r() {
935965
let secp = Secp256k1::new();
936966
let msg = hex!("887d04bb1cf1b1554f1b268dfe62d13064ca67ae45348d50d1392ce2d13418ac");
937-
let msg = Message::from_slice(&msg).unwrap();
967+
let msg = Message::from_digest_slice(&msg).unwrap();
938968
let sk =
939969
SecretKey::from_str("57f0148f94d13095cfda539d0da0d1541304b678d8b36e243980aab4e1b7cead")
940970
.unwrap();
@@ -952,7 +982,7 @@ mod tests {
952982
fn test_grind_r() {
953983
let secp = Secp256k1::new();
954984
let msg = hex!("ef2d5b9a7c61865a95941d0f04285420560df7e9d76890ac1b8867b12ce43167");
955-
let msg = Message::from_slice(&msg).unwrap();
985+
let msg = Message::from_digest_slice(&msg).unwrap();
956986
let sk =
957987
SecretKey::from_str("848355d75fe1c354cf05539bb29b2015f1863065bcb6766b44d399ab95c3fa0b")
958988
.unwrap();
@@ -972,7 +1002,7 @@ mod tests {
9721002

9731003
let s = Secp256k1::new();
9741004

975-
let msg = Message::from_slice(&[1; 32]).unwrap();
1005+
let msg = Message::from_digest_slice(&[1; 32]).unwrap();
9761006
let sk = SecretKey::from_slice(&[2; 32]).unwrap();
9771007
let sig = s.sign_ecdsa(&msg, &sk);
9781008
static SIG_BYTES: [u8; 71] = [
@@ -1002,7 +1032,7 @@ mod tests {
10021032
let sk_data = hex!("e6dd32f8761625f105c39a39f19370b3521d845a12456d60ce44debd0a362641");
10031033
let sk = SecretKey::from_slice(&sk_data).unwrap();
10041034
let msg_data = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
1005-
let msg = Message::from_slice(&msg_data).unwrap();
1035+
let msg = Message::from_digest_slice(&msg_data).unwrap();
10061036

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

10601090
bh.iter(|| {
@@ -1067,7 +1097,7 @@ mod benches {
10671097
pub fn bench_verify_ecdsa(bh: &mut Bencher) {
10681098
let s = Secp256k1::new();
10691099
let msg = crate::random_32_bytes(&mut rand::thread_rng());
1070-
let msg = Message::from_slice(&msg).unwrap();
1100+
let msg = Message::from_digest_slice(&msg).unwrap();
10711101
let (sk, pk) = s.generate_keypair(&mut rand::thread_rng());
10721102
let sig = s.sign_ecdsa(&msg, &sk);
10731103

0 commit comments

Comments
 (0)