Skip to content

Commit c4b5134

Browse files
authored
Merge pull request #224 from LLFourn/bip340-domain-separation
Implement BIP340 domain separation and simplify Message/Signature types
2 parents bc3ca5b + 1257da4 commit c4b5134

File tree

19 files changed

+238
-323
lines changed

19 files changed

+238
-323
lines changed

CHANGELOG.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
- `hash_to_curve` - Simple try-and-increment with uniform distribution (recommended)
1111
- `hash_to_curve_sswu` - RFC 9380 compliant constant-time hashing
1212
- `hash_to_curve_rfc9381_tai` - RFC 9381 VRF try-and-increment format
13+
- Add `Message::new` for BIP340-compliant domain separation using 33-byte padded prefix
14+
- Deprecate `Message::plain` which uses non-standard 64-byte prefix
15+
- Remove type parameters from `Message` and `Signature` types (always public now)
16+
- Remove unused `Slice` type from secp256kfun
1317

1418
## v0.11.0
1519

@@ -21,7 +25,6 @@
2125
- Add `Hash32` trait to collect all the useful hash traits we use all over the place
2226
- Add our own take on [chill-dkg](ttps://github.com/BlockstreamResearch/bip-frost-dkg/tree/master) WIP BIP
2327

24-
2528
## v0.10.0
2629

2730
- Change `Scalar::from_bytes` to work for `Scalar<_, NonZero>` as well.
@@ -67,7 +70,6 @@
6770
- Change the `from_bytes` type commands to not assume secrecy in `Scalar` and `Point`.
6871
- Update to rust-secp256k1 v0.25.0
6972

70-
7173
## 0.7.1
7274

7375
- Fix critical bug in MuSig2 implementation where multiple tweaks would break it
@@ -88,4 +90,3 @@
8890
## 0.6.1
8991

9092
- Fix serialization of `Point<EvenY>`
91-

schnorr_fun/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let schnorr = Schnorr::<Sha256, _>::new(nonce_gen.clone());
3939
// Generate your public/private key-pair
4040
let keypair = schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
4141
// Sign a variable length message
42-
let message = Message::<Public>::plain("the-times-of-london", b"Chancellor on brink of second bailout for banks");
42+
let message = Message::new("the-times-of-london", b"Chancellor on brink of second bailout for banks");
4343
// Sign the message with our keypair
4444
let signature = schnorr.sign(&keypair, message);
4545
// Get the verifier's key

schnorr_fun/benches/bench_schnorr.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn sign_schnorr(c: &mut Criterion) {
2020
{
2121
let keypair = schnorr.new_keypair(*SK);
2222
group.bench_function("fun::schnorr_sign", |b| {
23-
b.iter(|| schnorr.sign(&keypair, Message::<Public>::raw(MESSAGE)))
23+
b.iter(|| schnorr.sign(&keypair, Message::raw(MESSAGE)))
2424
});
2525
}
2626

@@ -40,19 +40,14 @@ fn verify_schnorr(c: &mut Criterion) {
4040
let mut group = c.benchmark_group("schnorr_verify");
4141
let keypair = schnorr.new_keypair(*SK);
4242
{
43-
let message = Message::<Public>::raw(MESSAGE);
43+
let message = Message::raw(MESSAGE);
4444
let sig = schnorr.sign(&keypair, message);
4545
let verification_key = &keypair.public_key();
4646
group.bench_function("fun::schnorr_verify", |b| {
4747
b.iter(|| schnorr.verify(verification_key, message, &sig))
4848
});
4949

50-
{
51-
let sig = sig.set_secrecy::<Secret>();
52-
group.bench_function("fun::schnorr_verify_ct", |b| {
53-
b.iter(|| schnorr.verify(verification_key, message, &sig))
54-
});
55-
}
50+
// Constant-time verification is no longer supported after removing type parameters
5651
}
5752

5853
{

schnorr_fun/src/adaptor/encrypted_signature.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,8 @@ mod test {
4747
let schnorr = crate::new_with_deterministic_nonces::<sha2::Sha256>();
4848
let kp = schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
4949
let encryption_key = Point::random(&mut rand::thread_rng());
50-
let encrypted_signature = schnorr.encrypted_sign(
51-
&kp,
52-
&encryption_key,
53-
Message::<Public>::plain("test", b"foo"),
54-
);
50+
let encrypted_signature =
51+
schnorr.encrypted_sign(&kp, &encryption_key, Message::new("test", b"foo"));
5552
let serialized = bincode::encode_to_vec(
5653
bincode::serde::Compat(&encrypted_signature),
5754
bincode::config::standard(),

schnorr_fun/src/adaptor/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
//! let verification_key = signing_keypair.public_key();
2424
//! let decryption_key = Scalar::random(&mut rand::thread_rng());
2525
//! let encryption_key = schnorr.encryption_key_for(&decryption_key);
26-
//! let message = Message::<Public>::plain("text-bitcoin", b"send 1 BTC to Bob");
26+
//! let message = Message::new("text-bitcoin", b"send 1 BTC to Bob");
2727
//!
2828
//! // Alice knows: signing_keypair, encryption_key
2929
//! // Bob knows: decryption_key, verification_key
@@ -68,7 +68,7 @@ pub trait EncryptedSign {
6868
&self,
6969
signing_keypair: &KeyPair<EvenY>,
7070
encryption_key: &Point<Normal, impl Secrecy>,
71-
message: Message<'_, impl Secrecy>,
71+
message: Message<'_>,
7272
) -> EncryptedSignature;
7373
}
7474

@@ -81,7 +81,7 @@ where
8181
&self,
8282
signing_key: &KeyPair<EvenY>,
8383
encryption_key: &Point<Normal, impl Secrecy>,
84-
message: Message<'_, impl Secrecy>,
84+
message: Message<'_>,
8585
) -> EncryptedSignature {
8686
let (x, X) = signing_key.as_tuple();
8787
let Y = encryption_key;
@@ -139,7 +139,7 @@ pub trait Adaptor {
139139
&self,
140140
verification_key: &Point<EvenY, impl Secrecy>,
141141
encryption_key: &Point<impl PointType, impl Secrecy>,
142-
message: Message<'_, impl Secrecy>,
142+
message: Message<'_>,
143143
encrypted_signature: &EncryptedSignature<impl Secrecy>,
144144
) -> bool;
145145

@@ -179,7 +179,7 @@ pub trait Adaptor {
179179
&self,
180180
encryption_key: &Point<impl Normalized, impl Secrecy>,
181181
encrypted_signature: &EncryptedSignature<impl Secrecy>,
182-
signature: &Signature<impl Secrecy>,
182+
signature: &Signature,
183183
) -> Option<Scalar>;
184184
}
185185

@@ -195,7 +195,7 @@ where
195195
&self,
196196
verification_key: &Point<EvenY, impl Secrecy>,
197197
encryption_key: &Point<impl PointType, impl Secrecy>,
198-
message: Message<'_, impl Secrecy>,
198+
message: Message<'_>,
199199
encrypted_signature: &EncryptedSignature<impl Secrecy>,
200200
) -> bool {
201201
let EncryptedSignature {
@@ -236,7 +236,7 @@ where
236236
&self,
237237
encryption_key: &Point<impl PointType, impl Secrecy>,
238238
encrypted_signature: &EncryptedSignature<impl Secrecy>,
239-
signature: &Signature<impl Secrecy>,
239+
signature: &Signature,
240240
) -> Option<Scalar> {
241241
if signature.R != encrypted_signature.R {
242242
return None;
@@ -298,7 +298,7 @@ mod test {
298298
let signing_keypair = schnorr.new_keypair(secret_key);
299299
let verification_key = signing_keypair.public_key();
300300
let encryption_key = schnorr.encryption_key_for(&decryption_key);
301-
let message = Message::<Public>::plain("test", b"give 100 coins to Bob".as_ref());
301+
let message = Message::new("test", b"give 100 coins to Bob".as_ref());
302302

303303
let encrypted_signature =
304304
schnorr.encrypted_sign(&signing_keypair, &encryption_key, message);

schnorr_fun/src/frost/chilldkg.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ pub mod simplepedpop {
101101
let secret_poly = poly::scalar::generate(threshold as usize, rng);
102102
let pop_keypair = KeyPair::new_xonly(secret_poly[0]);
103103
// XXX The thing that's singed differs from the spec
104-
let pop = schnorr.sign(&pop_keypair, Message::<Public>::empty());
104+
let pop = schnorr.sign(&pop_keypair, Message::empty());
105105
let com = poly::scalar::to_point_poly(&secret_poly);
106106

107107
let shares = share_receivers
@@ -201,7 +201,7 @@ pub mod simplepedpop {
201201
}
202202

203203
let (first_coeff_even_y, _) = input.com[0].into_point_with_even_y();
204-
if !schnorr.verify(&first_coeff_even_y, Message::<Public>::empty(), &input.pop) {
204+
if !schnorr.verify(&first_coeff_even_y, Message::empty(), &input.pop) {
205205
return Err("☠ pop didn't verify");
206206
}
207207
*entry = Some(input);
@@ -324,7 +324,7 @@ pub mod simplepedpop {
324324
{
325325
for (key_contrib, pop) in &agg_input.key_contrib {
326326
let (first_coeff_even_y, _) = key_contrib.into_point_with_even_y();
327-
if !schnorr.verify(&first_coeff_even_y, Message::<Public>::empty(), pop) {
327+
if !schnorr.verify(&first_coeff_even_y, Message::empty(), pop) {
328328
return Err(ReceiveShareError::InvalidPop);
329329
}
330330
}
@@ -606,7 +606,7 @@ pub mod encpedpop {
606606
{
607607
schnorr.sign(
608608
keypair,
609-
Message::<Public>::plain("BIP DKG/cert", self.cert_bytes().as_ref()),
609+
Message::new("BIP DKG/cert", self.cert_bytes().as_ref()),
610610
)
611611
}
612612

@@ -620,7 +620,7 @@ pub mod encpedpop {
620620
) -> bool {
621621
schnorr.verify(
622622
&cert_key,
623-
Message::<Public>::plain("BIP DKG/cert", self.cert_bytes().as_ref()),
623+
Message::new("BIP DKG/cert", self.cert_bytes().as_ref()),
624624
&signature,
625625
)
626626
}

schnorr_fun/src/frost/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//! let xonly_shared_key = shared_key.into_xonly(); // this is the key signatures will be valid under
3131
//! let xonly_my_secret_share = my_secret_share.into_xonly();
3232
//! # let xonly_secret_share3 = secret_share3.into_xonly();
33-
//! let message = Message::plain("my-app", b"chancellor on brink of second bailout for banks");
33+
//! let message = Message::new("my-app", b"chancellor on brink of second bailout for banks");
3434
//! // Generate nonces for this signing session (and send them to coordinator somehow)
3535
//! // ⚠ session_id MUST be different for every signing attempt to avoid nonce reuse (if using deterministic nonces).
3636
//! let session_id = b"signing-ominous-message-about-banks-attempt-1".as_slice();
@@ -446,7 +446,7 @@ mod test {
446446
let session = frost.coordinator_sign_session(
447447
&frost_poly.into_xonly(),
448448
BTreeMap::from_iter([(s!(1).public(), nonce), (s!(2).public(), malicious_nonce)]),
449-
Message::<Public>::plain("test", b"hello"),
449+
Message::new("test", b"hello"),
450450
);
451451

452452
assert_eq!(session.final_nonce(), *G);

schnorr_fun/src/frost/shared_key.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl<T: PointType, Z: ZeroChoice> SharedKey<T, Z> {
231231
}
232232

233233
impl SharedKey<Normal> {
234-
/// Convert the key into a BIP340 "x-only" SharedKey.
234+
/// Convert the key into a [BIP340] "x-only" SharedKey.
235235
///
236236
/// This is the [BIP340] compatible version of the key which you can put in a segwitv1 output.
237237
///

0 commit comments

Comments
 (0)