Skip to content

Commit 1778bc3

Browse files
authored
Merge pull request #93 from nickfarrow/master-pr-prepared
Make musig nonces usable in FROST
2 parents 7ad620f + 1da416e commit 1778bc3

File tree

3 files changed

+120
-117
lines changed

3 files changed

+120
-117
lines changed

schnorr_fun/src/binonce.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//! Binonces for Musig and FROST Signature Schemes
2+
//!
3+
//! A binonce is a pair of public points used in the MuSig and FROST signature schemes.
4+
//! Your public nonces are derived from scalars which must be kept secret.
5+
//! Derived binonces should be unique and and must not be reused for signing under any circumstances
6+
//! as this can leak your secret key.
7+
use secp256kfun::{g, marker::*, Point, Scalar, G};
8+
9+
/// A nonce (pair of points) that each party must share with the others in the first stage of signing.
10+
#[derive(Clone, Copy, PartialEq, Debug)]
11+
pub struct Nonce(pub [Point; 2]);
12+
13+
impl Nonce {
14+
/// Reads the pair of nonces from 66 bytes (two 33-byte serialized points).
15+
pub fn from_bytes(bytes: [u8; 66]) -> Option<Self> {
16+
let R1 = Point::from_slice(&bytes[..33])?;
17+
let R2 = Point::from_slice(&bytes[33..])?;
18+
Some(Nonce([R1, R2]))
19+
}
20+
21+
/// Serializes a public nonce as as 66 bytes (two 33-byte serialized points).
22+
pub fn to_bytes(&self) -> [u8; 66] {
23+
let mut bytes = [0u8; 66];
24+
bytes[..33].copy_from_slice(self.0[0].to_bytes().as_ref());
25+
bytes[33..].copy_from_slice(self.0[1].to_bytes().as_ref());
26+
bytes
27+
}
28+
29+
/// Negate the two nonces
30+
pub fn conditional_negate(&mut self, needs_negation: bool) {
31+
self.0[0] = self.0[0].conditional_negate(needs_negation);
32+
self.0[1] = self.0[1].conditional_negate(needs_negation);
33+
}
34+
}
35+
36+
secp256kfun::impl_fromstr_deserialize! {
37+
name => "public nonce pair",
38+
fn from_bytes(bytes: [u8;66]) -> Option<Nonce> {
39+
Nonce::from_bytes(bytes)
40+
}
41+
}
42+
43+
secp256kfun::impl_display_serialize! {
44+
fn to_bytes(nonce: &Nonce) -> [u8;66] {
45+
nonce.to_bytes()
46+
}
47+
}
48+
49+
/// A pair of secret nonces along with the public portion.
50+
///
51+
/// A nonce key pair can be created manually with [`from_secrets`]
52+
///
53+
/// [`from_secrets`]: Self::from_secrets
54+
#[derive(Debug, Clone, PartialEq)]
55+
pub struct NonceKeyPair {
56+
/// The public nonce
57+
pub public: Nonce,
58+
/// The secret nonce
59+
pub secret: [Scalar; 2],
60+
}
61+
62+
impl NonceKeyPair {
63+
/// Load nonces from two secret scalars
64+
pub fn from_secrets(secret: [Scalar; 2]) -> Self {
65+
let [ref r1, ref r2] = secret;
66+
let R1 = g!(r1 * G).normalize();
67+
let R2 = g!(r2 * G).normalize();
68+
NonceKeyPair {
69+
public: Nonce([R1, R2]),
70+
secret,
71+
}
72+
}
73+
/// Deserializes a nonce key pair from 64-bytes (two 32-byte serialized scalars).
74+
pub fn from_bytes(bytes: [u8; 64]) -> Option<Self> {
75+
let r1 = Scalar::from_slice(&bytes[..32])?.mark::<NonZero>()?;
76+
let r2 = Scalar::from_slice(&bytes[32..])?.mark::<NonZero>()?;
77+
let R1 = g!(r1 * G).normalize();
78+
let R2 = g!(r2 * G).normalize();
79+
let pub_nonce = Nonce([R1, R2]);
80+
Some(NonceKeyPair {
81+
public: pub_nonce,
82+
secret: [r1, r2],
83+
})
84+
}
85+
86+
/// Serializes a nonce key pair to 64-bytes (two 32-bytes serialized scalars).
87+
pub fn to_bytes(&self) -> [u8; 64] {
88+
let mut bytes = [0u8; 64];
89+
bytes[..32].copy_from_slice(self.secret[0].to_bytes().as_ref());
90+
bytes[32..].copy_from_slice(self.secret[1].to_bytes().as_ref());
91+
bytes
92+
}
93+
94+
/// Get the secret portion of the nonce key pair (don't share this!)
95+
pub fn secret(&self) -> &[Scalar; 2] {
96+
&self.secret
97+
}
98+
99+
/// Get the public portion of the nonce key pair (share this!)
100+
pub fn public(&self) -> Nonce {
101+
self.public
102+
}
103+
}
104+
105+
secp256kfun::impl_fromstr_deserialize! {
106+
name => "secret nonce pair",
107+
fn from_bytes(bytes: [u8;64]) -> Option<NonceKeyPair> {
108+
NonceKeyPair::from_bytes(bytes)
109+
}
110+
}
111+
112+
secp256kfun::impl_display_serialize! {
113+
fn to_bytes(nkp: &NonceKeyPair) -> [u8;64] {
114+
nkp.to_bytes()
115+
}
116+
}

schnorr_fun/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ extern crate serde_crate as serde;
2222
pub use secp256kfun as fun;
2323
pub use secp256kfun::nonce;
2424

25+
/// binonces for Musig and FROST
26+
mod binonce;
2527
// musig needs vecs
2628
#[cfg(feature = "alloc")]
2729
pub mod musig;

schnorr_fun/src/musig.rs

Lines changed: 2 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
//!
6868
//! [the excellent paper]: https://eprint.iacr.org/2020/1261.pdf
6969
//! [secp256k1-zkp]: https://github.com/ElementsProject/secp256k1-zkp/pull/131
70+
pub use crate::binonce::{Nonce, NonceKeyPair};
7071
use crate::{adaptor::EncryptedSignature, KeyPair, Message, Schnorr, Signature, Vec};
7172
use secp256kfun::{
7273
derive_nonce,
@@ -300,123 +301,6 @@ impl<H: Digest<OutputSize = U32> + Clone, S> MuSig<H, S> {
300301
}
301302
}
302303

303-
/// A nonce (pair of points) that each party must share with the others in the first stage of signing.
304-
#[derive(Clone, Copy, PartialEq, Debug)]
305-
pub struct Nonce(pub [Point; 2]);
306-
307-
impl Nonce {
308-
/// Reads the pair of nonces from 66 bytes (two 33-byte serialized points).
309-
pub fn from_bytes(bytes: [u8; 66]) -> Option<Self> {
310-
let R1 = Point::from_slice(&bytes[..33])?;
311-
let R2 = Point::from_slice(&bytes[33..])?;
312-
Some(Nonce([R1, R2]))
313-
}
314-
315-
/// Serializes a public nonce as as 66 bytes (two 33-byte serialized points).
316-
pub fn to_bytes(&self) -> [u8; 66] {
317-
let mut bytes = [0u8; 66];
318-
bytes[..33].copy_from_slice(self.0[0].to_bytes().as_ref());
319-
bytes[33..].copy_from_slice(self.0[1].to_bytes().as_ref());
320-
bytes
321-
}
322-
}
323-
324-
secp256kfun::impl_fromstr_deserialize! {
325-
name => "MuSig2 public nonce pair",
326-
fn from_bytes(bytes: [u8;66]) -> Option<Nonce> {
327-
Nonce::from_bytes(bytes)
328-
}
329-
}
330-
331-
secp256kfun::impl_display_serialize! {
332-
fn to_bytes(nonce: &Nonce) -> [u8;66] {
333-
nonce.to_bytes()
334-
}
335-
}
336-
337-
/// A pair of secret nonces along with the public portion.
338-
///
339-
/// A nonce key pair can be created manually with [`from_secrets`] or with [`MuSig::gen_nonces`].
340-
///
341-
/// [`from_secrets`]: Self::from_secrets
342-
/// [`MuSig::gen_nonces`]: MuSig::gen_nonces
343-
#[derive(Debug, Clone, PartialEq)]
344-
pub struct NonceKeyPair {
345-
/// The public nonce
346-
public: Nonce,
347-
/// The secret nonce
348-
secret: [Scalar; 2],
349-
}
350-
351-
impl NonceKeyPair {
352-
/// Creates a keypair from two secret scalars.
353-
///
354-
/// ## Security
355-
///
356-
/// You must never use the same `NonceKeyPair` into two signing sessions.
357-
///
358-
/// ## Example
359-
/// ```
360-
/// use schnorr_fun::{fun::Scalar, musig::NonceKeyPair};
361-
/// let nkp = NonceKeyPair::from_secrets([
362-
/// Scalar::random(&mut rand::thread_rng()),
363-
/// Scalar::random(&mut rand::thread_rng()),
364-
/// ]);
365-
/// ```
366-
pub fn from_secrets(secret: [Scalar; 2]) -> Self {
367-
let [ref r1, ref r2] = secret;
368-
let R1 = g!(r1 * G).normalize();
369-
let R2 = g!(r2 * G).normalize();
370-
NonceKeyPair {
371-
public: Nonce([R1, R2]),
372-
secret,
373-
}
374-
}
375-
/// Deserializes a nonce key pair from 64-bytes (two 32-byte serialized scalars).
376-
pub fn from_bytes(bytes: [u8; 64]) -> Option<Self> {
377-
let r1 = Scalar::from_slice(&bytes[..32])?.mark::<NonZero>()?;
378-
let r2 = Scalar::from_slice(&bytes[32..])?.mark::<NonZero>()?;
379-
let R1 = g!(r1 * G).normalize();
380-
let R2 = g!(r2 * G).normalize();
381-
let pub_nonce = Nonce([R1, R2]);
382-
Some(NonceKeyPair {
383-
public: pub_nonce,
384-
secret: [r1, r2],
385-
})
386-
}
387-
388-
/// Serializes a nonce key pair to 64-bytes (two 32-bytes serialized scalars).
389-
pub fn to_bytes(&self) -> [u8; 64] {
390-
let mut bytes = [0u8; 64];
391-
bytes[..32].copy_from_slice(self.secret[0].to_bytes().as_ref());
392-
bytes[32..].copy_from_slice(self.secret[1].to_bytes().as_ref());
393-
bytes
394-
}
395-
396-
/// Get the secret portion of the nonce key pair (don't share this!)
397-
pub fn secret(&self) -> &[Scalar; 2] {
398-
&self.secret
399-
}
400-
401-
/// Get the public portion of the nonce key pair (share this!)
402-
pub fn public(&self) -> Nonce {
403-
self.public
404-
}
405-
}
406-
407-
secp256kfun::impl_fromstr_deserialize! {
408-
name => "MuSig secret nonce pair",
409-
fn from_bytes(bytes: [u8;64]) -> Option<NonceKeyPair> {
410-
NonceKeyPair::from_bytes(bytes)
411-
}
412-
}
413-
414-
secp256kfun::impl_display_serialize! {
415-
fn to_bytes(nkp: &NonceKeyPair) -> [u8;64] {
416-
nkp.to_bytes()
417-
}
418-
}
419-
420304
impl<H: Digest<OutputSize = U32> + Clone, NG: NonceGen> MuSig<H, Schnorr<H, NG>> {
421305
/// Generate nonces for your local keys in keylist.
422306
///
@@ -441,6 +325,7 @@ impl<H: Digest<OutputSize = U32> + Clone, NG: NonceGen> MuSig<H, Schnorr<H, NG>>
441325
/// [`Deterministic`]: secp256kfun::nonce::Deterministic
442326
/// [`start_sign_session`]: Self::start_sign_session
443327
/// [`start_sign_session_deterministic`]: Self::start_sign_session_deterministic
328+
/// [`NonceKeyPair`]: schnorr_fun::binonce::NonceKeyPair
444329
pub fn gen_nonces(&self, keylist: &KeyList, sid: &[u8]) -> Vec<NonceKeyPair> {
445330
keylist
446331
.parties

0 commit comments

Comments
 (0)