Skip to content

Commit 35773fe

Browse files
authored
Merge pull request #203 from LLFourn/secret_binonce
[❄] Add binonce::SecretNonce
2 parents c825a36 + 5562e0f commit 35773fe

File tree

5 files changed

+93
-49
lines changed

5 files changed

+93
-49
lines changed

schnorr_fun/src/binonce.rs

Lines changed: 73 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct Nonce<Z = NonZero>(pub [Point<Normal, Public, Z>; 2]);
1717
impl<Z: ZeroChoice> Nonce<Z> {
1818
/// Reads the pair of nonces from 66 bytes (two 33-byte serialized points).
1919
///
20-
/// If either pair of 33 bytes is `[0u8;32]` that point is interpreted as `Zero`.
20+
/// If either pair of 33 bytes is `[0u8;33]` that point is interpreted as `Zero`.
2121
pub fn from_bytes(bytes: [u8; 66]) -> Option<Self> {
2222
let R1 = Point::from_slice(&bytes[..33])?;
2323
let R2 = Point::from_slice(&bytes[33..])?;
@@ -35,7 +35,7 @@ impl<Z: ZeroChoice> Nonce<Z> {
3535

3636
/// Serializes a public nonce as as 66 bytes (two 33-byte serialized points).
3737
///
38-
/// If either point is `Zero` it will be serialized as `[0u8;32]`.
38+
/// If either point is `Zero` it will be serialized as `[0u8;33]`.
3939
pub fn to_bytes(&self) -> [u8; 66] {
4040
let mut bytes = [0u8; 66];
4141
bytes[..33].copy_from_slice(self.0[0].to_bytes().as_ref());
@@ -72,7 +72,7 @@ impl Nonce<Zero> {
7272
}
7373

7474
secp256kfun::impl_fromstr_deserialize! {
75-
name => "public nonce pair",
75+
name => "public binonce",
7676
fn from_bytes<Z: ZeroChoice>(bytes: [u8;66]) -> Option<Nonce<Z>> {
7777
Nonce::from_bytes(bytes)
7878
}
@@ -86,51 +86,64 @@ secp256kfun::impl_display_serialize! {
8686

8787
/// A pair of secret nonces along with the public portion.
8888
///
89-
/// A nonce key pair can be created manually with [`from_secrets`]
89+
/// A nonce key pair can be created manually with [`from_secret`]
9090
///
91-
/// [`from_secrets`]: Self::from_secrets
91+
/// [`from_secret`]: Self::from_secret
9292
#[derive(Debug, Clone, PartialEq)]
9393
pub struct NonceKeyPair {
9494
/// The public nonce
9595
pub public: Nonce<NonZero>,
9696
/// The secret nonce
97-
pub secret: [Scalar; 2],
97+
pub secret: SecretNonce,
9898
}
9999

100-
impl NonceKeyPair {
101-
/// Load nonces from two secret scalars
102-
pub fn from_secrets(secret: [Scalar; 2]) -> Self {
103-
let [ref r1, ref r2] = secret;
104-
let R1 = g!(r1 * G).normalize();
105-
let R2 = g!(r2 * G).normalize();
106-
NonceKeyPair {
107-
public: Nonce([R1, R2]),
108-
secret,
109-
}
110-
}
111-
/// Deserializes a nonce key pair from 64-bytes (two 32-byte serialized scalars).
100+
/// A pair of secret nonces.
101+
///
102+
/// ⚠ An attacker getting this allows them to extract your secret share from a signature share.
103+
#[derive(Debug, Clone, PartialEq)]
104+
pub struct SecretNonce(pub [Scalar; 2]);
105+
106+
impl SecretNonce {
107+
/// Deserializes a secret binonce from 64-bytes (two 32-byte serialized scalars).
112108
pub fn from_bytes(bytes: [u8; 64]) -> Option<Self> {
113109
let r1 = Scalar::from_slice(&bytes[..32])?.non_zero()?;
114110
let r2 = Scalar::from_slice(&bytes[32..])?.non_zero()?;
115-
let R1 = g!(r1 * G).normalize();
116-
let R2 = g!(r2 * G).normalize();
117-
let pub_nonce = Nonce([R1, R2]);
118-
Some(NonceKeyPair {
119-
public: pub_nonce,
120-
secret: [r1, r2],
121-
})
111+
Some(Self([r1, r2]))
122112
}
123113

124-
/// Serializes a nonce key pair to 64-bytes (two 32-bytes serialized scalars).
114+
/// Serializes a secret binonce to 64-bytes (two 32-bytes serialized scalars).
125115
pub fn to_bytes(&self) -> [u8; 64] {
126116
let mut bytes = [0u8; 64];
127-
bytes[..32].copy_from_slice(self.secret[0].to_bytes().as_ref());
128-
bytes[32..].copy_from_slice(self.secret[1].to_bytes().as_ref());
117+
bytes[..32].copy_from_slice(self.0[0].to_bytes().as_ref());
118+
bytes[32..].copy_from_slice(self.0[1].to_bytes().as_ref());
129119
bytes
130120
}
131121

122+
/// Generate a nonce secret binonce from an rng
123+
pub fn random(rng: &mut impl RngCore) -> Self {
124+
Self([Scalar::random(rng), Scalar::random(rng)])
125+
}
126+
127+
/// Convert a secret nonce into a key pair by computing the public nonce
128+
pub fn into_keypair(self) -> NonceKeyPair {
129+
NonceKeyPair::from_secret(self)
130+
}
131+
}
132+
133+
impl NonceKeyPair {
134+
/// Load nonces from two secret scalars
135+
pub fn from_secret(secret: SecretNonce) -> Self {
136+
let [ref r1, ref r2] = secret.0;
137+
let R1 = g!(r1 * G).normalize();
138+
let R2 = g!(r2 * G).normalize();
139+
NonceKeyPair {
140+
public: Nonce([R1, R2]),
141+
secret,
142+
}
143+
}
144+
132145
/// Get the secret portion of the nonce key pair (don't share this!)
133-
pub fn secret(&self) -> &[Scalar; 2] {
146+
pub fn secret(&self) -> &SecretNonce {
134147
&self.secret
135148
}
136149

@@ -139,21 +152,46 @@ impl NonceKeyPair {
139152
self.public
140153
}
141154

142-
/// Generate a nonce keypair from an rng
155+
/// Generate a random secret nonce and conver to a keypair
143156
pub fn random(rng: &mut impl RngCore) -> Self {
144-
Self::from_secrets([Scalar::random(rng), Scalar::random(rng)])
157+
Self::from_secret(SecretNonce::random(rng))
158+
}
159+
}
160+
161+
impl AsRef<SecretNonce> for NonceKeyPair {
162+
fn as_ref(&self) -> &SecretNonce {
163+
self.secret()
164+
}
165+
}
166+
167+
impl AsRef<SecretNonce> for SecretNonce {
168+
fn as_ref(&self) -> &SecretNonce {
169+
self
170+
}
171+
}
172+
173+
secp256kfun::impl_fromstr_deserialize! {
174+
name => "secret binonce",
175+
fn from_bytes(bytes: [u8;64]) -> Option<SecretNonce> {
176+
SecretNonce::from_bytes(bytes)
177+
}
178+
}
179+
180+
secp256kfun::impl_display_serialize! {
181+
fn to_bytes(value: &SecretNonce) -> [u8;64] {
182+
value.to_bytes()
145183
}
146184
}
147185

148186
secp256kfun::impl_fromstr_deserialize! {
149-
name => "secret nonce pair",
187+
name => "secret binonce",
150188
fn from_bytes(bytes: [u8;64]) -> Option<NonceKeyPair> {
151-
NonceKeyPair::from_bytes(bytes)
189+
Some(NonceKeyPair::from_secret(SecretNonce::from_bytes(bytes)?))
152190
}
153191
}
154192

155193
secp256kfun::impl_display_serialize! {
156-
fn to_bytes(nkp: &NonceKeyPair) -> [u8;64] {
157-
nkp.to_bytes()
194+
fn to_bytes(value: &NonceKeyPair) -> [u8;64] {
195+
value.secret.to_bytes()
158196
}
159197
}

schnorr_fun/src/frost/session.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
use crate::{binonce, frost::PartyIndex, Signature};
1+
use crate::{
2+
binonce::{self, SecretNonce},
3+
frost::PartyIndex,
4+
Signature,
5+
};
26
use alloc::collections::{BTreeMap, BTreeSet};
37
use secp256kfun::{poly, prelude::*};
48

5-
use super::{NonceKeyPair, PairedSecretShare, SharedKey, SignatureShare, VerificationShare};
9+
use super::{PairedSecretShare, SharedKey, SignatureShare, VerificationShare};
610
/// A FROST signing session used to *verify* signatures.
711
///
812
/// Created using [`coordinator_sign_session`].
@@ -214,7 +218,7 @@ impl PartySignSession {
214218
pub fn sign(
215219
&self,
216220
secret_share: &PairedSecretShare<EvenY>,
217-
secret_nonce: NonceKeyPair,
221+
secret_nonce: impl AsRef<SecretNonce>,
218222
) -> SignatureShare {
219223
if self.public_key != secret_share.public_key() {
220224
panic!("the share's shared key is not the same as the shared key of the session");
@@ -224,7 +228,7 @@ impl PartySignSession {
224228
}
225229
let secret_share = secret_share.secret_share();
226230
let lambda = poly::eval_basis_poly_at_0(secret_share.index, self.parties.iter().cloned());
227-
let [mut r1, mut r2] = secret_nonce.secret;
231+
let [mut r1, mut r2] = secret_nonce.as_ref().0;
228232
r1.conditional_negate(self.binonce_needs_negation);
229233
r2.conditional_negate(self.binonce_needs_negation);
230234

schnorr_fun/src/musig.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@
7171
//!
7272
//! [the excellent paper]: https://eprint.iacr.org/2020/1261.pdf
7373
//! [secp256k1-zkp]: https://github.com/ElementsProject/secp256k1-zkp/pull/131
74-
use crate::{adaptor::EncryptedSignature, binonce, Message, Schnorr, Signature};
74+
use crate::{
75+
adaptor::EncryptedSignature,
76+
binonce::{self, SecretNonce},
77+
Message, Schnorr, Signature,
78+
};
7579
use alloc::vec::Vec;
7680
use secp256kfun::{
7781
hash::{Hash32, HashAdd, Tag},
@@ -556,7 +560,7 @@ impl<H: Hash32, NG> MuSig<H, NG> {
556560
session: &SignSession<T>,
557561
my_index: usize,
558562
keypair: &KeyPair,
559-
local_secret_nonce: binonce::NonceKeyPair,
563+
local_secret_nonce: impl AsRef<SecretNonce>,
560564
) -> Scalar<Public, Zero> {
561565
assert_eq!(
562566
keypair.public_key(),
@@ -569,7 +573,7 @@ impl<H: Hash32, NG> MuSig<H, NG> {
569573
let mut a = agg_key.coefs[my_index];
570574

571575
a.conditional_negate(agg_key.needs_negation);
572-
let [mut r1, mut r2] = local_secret_nonce.secret;
576+
let [mut r1, mut r2] = local_secret_nonce.as_ref().0;
573577
r1.conditional_negate(session.nonce_needs_negation);
574578
r2.conditional_negate(session.nonce_needs_negation);
575579
s!(c * a * x_i + r1 + b * r2).public()

schnorr_fun/tests/musig_sign_verify.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![cfg(feature = "serde")]
22
use schnorr_fun::{
33
binonce,
4-
binonce::NonceKeyPair,
54
fun::{marker::*, serde, Point, Scalar},
65
musig, Message,
76
};
@@ -26,15 +25,15 @@ impl<T> Maybe<T> {
2625

2726
#[derive(Clone, Debug)]
2827
struct SecNonce {
29-
nonce: NonceKeyPair,
28+
nonce: binonce::SecretNonce,
3029
pk: Point,
3130
}
3231

3332
impl SecNonce {
3433
pub fn from_bytes(bytes: [u8; 97]) -> Option<Self> {
3534
let mut nonce = [0u8; 64];
3635
nonce.copy_from_slice(&bytes[..64]);
37-
let nonce = binonce::NonceKeyPair::from_bytes(nonce)?;
36+
let nonce = binonce::SecretNonce::from_bytes(nonce)?;
3837
Some(SecNonce {
3938
nonce,
4039
pk: Point::from_slice(&bytes[64..])?,

schnorr_fun/tests/musig_tweak.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
use std::{rc::Rc, sync::Arc};
44

55
use schnorr_fun::{
6-
binonce,
7-
binonce::NonceKeyPair,
6+
binonce::{self, NonceKeyPair},
87
fun::{marker::*, serde, Point, Scalar},
98
musig, Message,
109
};
@@ -28,15 +27,15 @@ impl<T> Maybe<T> {
2827
}
2928

3029
struct SecNonce {
31-
nonce: NonceKeyPair,
30+
nonce: binonce::SecretNonce,
3231
_pk: Point,
3332
}
3433

3534
impl SecNonce {
3635
pub fn from_bytes(bytes: [u8; 97]) -> Option<Self> {
3736
let mut nonce = [0u8; 64];
3837
nonce.copy_from_slice(&bytes[..64]);
39-
let nonce = binonce::NonceKeyPair::from_bytes(nonce)?;
38+
let nonce = binonce::SecretNonce::from_bytes(nonce)?;
4039
Some(SecNonce {
4140
nonce,
4241
_pk: Point::from_slice(&bytes[64..])?,

0 commit comments

Comments
 (0)