Skip to content

Commit

Permalink
Merge pull request #191 from LLFourn/clean_up_frost
Browse files Browse the repository at this point in the history
Clean up frost
  • Loading branch information
LLFourn authored Aug 14, 2024
2 parents 646b969 + 9dcb91c commit 2e748c4
Show file tree
Hide file tree
Showing 19 changed files with 163 additions and 125 deletions.
9 changes: 2 additions & 7 deletions ecdsa_fun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,7 @@ impl<NG: NonceGen> ECDSA<NG> {
///
/// ```
/// use ecdsa_fun::{
/// fun::{
/// digest::{Digest, Update},
/// g,
/// marker::*,
/// Scalar, G,
/// },
/// fun::{digest::Digest, prelude::*},
/// nonce, ECDSA,
/// };
/// use rand::rngs::ThreadRng;
Expand All @@ -149,7 +144,7 @@ impl<NG: NonceGen> ECDSA<NG> {
/// let message_hash = {
/// let message = b"Attack at dawn";
/// let mut message_hash = [0u8; 32];
/// let hash = Sha256::default().chain(message);
/// let hash = Sha256::default().chain_update(message);
/// message_hash.copy_from_slice(hash.finalize().as_ref());
/// message_hash
/// };
Expand Down
2 changes: 1 addition & 1 deletion schnorr_fun/src/adaptor/encrypted_signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ mod test {
fn encrypted_signature_serialization_roundtrip() {
use super::*;
use crate::{adaptor::*, fun::Scalar, Message};
let schnorr = crate::test_instance!();
let schnorr = crate::new_with_deterministic_nonces::<sha2::Sha256>();
let kp = schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
let encryption_key = Point::random(&mut rand::thread_rng());
let encrypted_signature = schnorr.encrypted_sign(
Expand Down
15 changes: 5 additions & 10 deletions schnorr_fun/src/adaptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,12 @@
//! }
//! ```
use crate::{
fun::{
derive_nonce,
digest::{generic_array::typenum::U32, Digest},
g,
marker::*,
nonce, s, KeyPair, Point, Scalar, G,
},
fun::{derive_nonce, nonce, prelude::*, KeyPair},
Message, Schnorr, Signature,
};
mod encrypted_signature;
pub use encrypted_signature::EncryptedSignature;
use secp256kfun::hash::Hash32;

/// Extension trait for [`Schnorr`] to add the encrypted signing algorithm.
///
Expand All @@ -79,7 +74,7 @@ pub trait EncryptedSign {

impl<NG, CH> EncryptedSign for Schnorr<CH, NG>
where
CH: Digest<OutputSize = U32> + Clone,
CH: Hash32,
NG: nonce::NonceGen,
{
fn encrypted_sign(
Expand Down Expand Up @@ -128,7 +123,7 @@ pub trait Adaptor {
/// # Example
/// ```
/// # use schnorr_fun::{adaptor::Adaptor, fun::Scalar, Schnorr};
/// # let schnorr = schnorr_fun::test_instance!();
/// let schnorr = schnorr_fun::new_with_deterministic_nonces::<sha2::Sha256>();
/// let decryption_key = Scalar::random(&mut rand::thread_rng());
/// let encryption_key = schnorr.encryption_key_for(&decryption_key);
fn encryption_key_for(&self, decryption_key: &Scalar) -> Point;
Expand Down Expand Up @@ -190,7 +185,7 @@ pub trait Adaptor {

impl<CH, NG> Adaptor for Schnorr<CH, NG>
where
CH: Digest<OutputSize = U32> + Clone,
CH: Hash32,
{
fn encryption_key_for(&self, decryption_key: &Scalar) -> Point {
g!(decryption_key * G).normalize()
Expand Down
2 changes: 1 addition & 1 deletion schnorr_fun/src/binonce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<Z: ZeroChoice> Nonce<Z> {
}

impl<Z> HashInto for Nonce<Z> {
fn hash_into(self, hash: &mut impl secp256kfun::digest::Digest) {
fn hash_into(self, hash: &mut impl secp256kfun::digest::Update) {
self.0.hash_into(hash)
}
}
Expand Down
30 changes: 14 additions & 16 deletions schnorr_fun/src/frost/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,8 @@ use alloc::{
};
use core::num::NonZeroU32;
use secp256kfun::{
derive_nonce_rng,
digest::{generic_array::typenum::U32, Digest},
g,
hash::{HashAdd, Tag},
derive_nonce_rng, g,
hash::{Hash32, HashAdd, Tag},
marker::*,
nonce::{self, NonceGen},
poly,
Expand Down Expand Up @@ -245,7 +243,7 @@ pub struct Frost<H, NG> {

impl<H, NG> Default for Frost<H, NG>
where
H: Default + Tag + Digest<OutputSize = U32>,
H: Hash32,
NG: Default + Tag + Clone,
{
fn default() -> Self {
Expand Down Expand Up @@ -384,8 +382,8 @@ impl core::fmt::Display for FinishKeyGenError {
#[cfg(feature = "std")]
impl std::error::Error for FinishKeyGenError {}

impl<H: Digest<OutputSize = U32> + Clone, NG: NonceGen> Frost<H, NG> {
/// Convenience method to generate secret shares and proof-of-possession to be shared with other
impl<H: Hash32, NG: NonceGen> Frost<H, NG> {
/// Convienence method to generate secret shares and proof-of-possession to be shared with other
/// participants. Each secret share needs to be securely communicated to the intended
/// participant but the proof of possession (schnorr signature) can be publically shared with
/// everyone.
Expand Down Expand Up @@ -535,19 +533,19 @@ impl<H: Digest<OutputSize = U32> + Clone, NG: NonceGen> Frost<H, NG> {
}
}

impl<H: Digest<OutputSize = U32> + Clone, NG> Frost<H, NG> {
/// Generate an id for the key generation by hashing the party indices and their point
impl<H: Hash32, NG> Frost<H, NG> {
/// Generate an id for the key generation by hashing the party indicies and their point
/// polynomials
pub fn keygen_id(&self, keygen: &KeyGen) -> [u8; 32] {
let mut keygen_hash = self.keygen_id_hash.clone();
keygen_hash.update((keygen.point_polys.len() as u32).to_be_bytes());
keygen_hash.update((keygen.point_polys.len() as u32).to_be_bytes().as_ref());
for (index, poly) in &keygen.point_polys {
keygen_hash.update(index.to_bytes());
keygen_hash.update(index.to_bytes().as_ref());
for point in poly {
keygen_hash.update(point.to_bytes());
keygen_hash.update(point.to_bytes().as_ref());
}
}
keygen_hash.finalize().into()
keygen_hash.finalize_fixed().into()
}

/// Collect all the public polynomials commitments into a [`KeyGen`] to produce a [`SharedKey`].
Expand Down Expand Up @@ -803,7 +801,7 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> Frost<H, NG> {
/// ```
pub fn new_with_deterministic_nonces<H>() -> Frost<H, nonce::Deterministic<H>>
where
H: Tag + Digest<OutputSize = U32> + Default + Clone,
H: Hash32,
{
Frost::default()
}
Expand All @@ -821,7 +819,7 @@ where
/// ```
pub fn new_with_synthetic_nonces<H, R>() -> Frost<H, nonce::Synthetic<H, nonce::GlobalRng<R>>>
where
H: Tag + Digest<OutputSize = U32> + Default + Clone,
H: Hash32,
R: RngCore + Default + Clone,
{
Frost::default()
Expand All @@ -832,7 +830,7 @@ where
/// You can still sign with this instance but you you will have to generate nonces in your own way.
pub fn new_without_nonce_generation<H>() -> Frost<H, nonce::NoNonces>
where
H: Tag + Digest<OutputSize = U32> + Default + Clone,
H: Hash32,
{
Frost::default()
}
Expand Down
10 changes: 8 additions & 2 deletions schnorr_fun/src/frost/share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ secp256kfun::impl_display_debug_serialize! {
}
}

#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
feature = "bincode",
derive(crate::fun::bincode::Encode, crate::fun::bincode::Decode),
Expand All @@ -131,11 +131,17 @@ secp256kfun::impl_display_debug_serialize! {
///
/// This is useful so you can keep track of tweaks to the secret value and tweaks to the shared key
/// in tandem.
pub struct PairedSecretShare<T: PointType, Z = NonZero> {
pub struct PairedSecretShare<T = Normal, Z = NonZero> {
secret_share: SecretShare,
public_key: Point<T, Public, Z>,
}

impl<T: PointType, Z> PartialEq for PairedSecretShare<T, Z> {
fn eq(&self, other: &Self) -> bool {
self.secret_share == other.secret_share && self.public_key == other.public_key
}
}

impl<T: Normalized, Z: ZeroChoice> PairedSecretShare<T, Z> {
/// The index of the secret share
pub fn index(&self) -> PartyIndex {
Expand Down
11 changes: 8 additions & 3 deletions schnorr_fun/src/frost/shared_key.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use core::{marker::PhantomData, ops::Deref};

use super::{PairedSecretShare, PartyIndex, SecretShare, VerificationShare};
use alloc::vec::Vec;
use core::{marker::PhantomData, ops::Deref};
use secp256kfun::{poly, prelude::*};

/// A polynomial where the first coefficient (constant term) is the image of a secret `Scalar` that
/// has been shared in a [Shamir's secret sharing] structure.
///
/// [Shamir's secret sharing]: https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, Eq)]
#[cfg_attr(
feature = "serde",
derive(crate::fun::serde::Serialize),
Expand Down Expand Up @@ -244,6 +243,12 @@ impl SharedKey<EvenY> {
}
}

impl<T1, Z1, T2, Z2> PartialEq<SharedKey<T2, Z2>> for SharedKey<T1, Z1> {
fn eq(&self, other: &SharedKey<T2, Z2>) -> bool {
other.point_polynomial == self.point_polynomial
}
}

#[cfg(feature = "bincode")]
impl<T: PointType, Z: ZeroChoice> crate::fun::bincode::Decode for SharedKey<T, Z> {
fn decode<D: secp256kfun::bincode::de::Decoder>(
Expand Down
8 changes: 0 additions & 8 deletions schnorr_fun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,3 @@ mod message;
pub use message::*;

mod libsecp_compat;

#[macro_export]
#[doc(hidden)]
macro_rules! test_instance {
() => {
$crate::Schnorr::<sha2::Sha256, secp256kfun::nonce::Deterministic<sha2::Sha256>>::default()
};
}
13 changes: 9 additions & 4 deletions schnorr_fun/src/message.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use secp256kfun::{digest::Digest, hash::HashInto, marker::*, Slice};
use secp256kfun::{
digest::{self},
hash::HashInto,
marker::*,
Slice,
};

/// A message to be signed.
///
Expand Down Expand Up @@ -57,11 +62,11 @@ impl<'a, S: Secrecy> Message<'a, S> {
}

impl<S> HashInto for Message<'_, S> {
fn hash_into(self, hash: &mut impl Digest) {
fn hash_into(self, hash: &mut impl digest::Update) {
if let Some(prefix) = self.app_tag {
let mut padded_prefix = [0u8; 64];
padded_prefix[..prefix.len()].copy_from_slice(prefix.as_bytes());
hash.update(padded_prefix);
hash.update(&padded_prefix);
}
hash.update(<&[u8]>::from(self.bytes));
}
Expand All @@ -70,7 +75,7 @@ impl<S> HashInto for Message<'_, S> {
#[cfg(test)]
mod test {
use super::*;
use sha2::Sha256;
use sha2::{Digest, Sha256};

#[test]
fn message_hash_into() {
Expand Down
22 changes: 10 additions & 12 deletions schnorr_fun/src/musig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,11 @@
use crate::{adaptor::EncryptedSignature, binonce, Message, Schnorr, Signature};
use alloc::vec::Vec;
use secp256kfun::{
digest::{generic_array::typenum::U32, Digest},
g,
hash::{HashAdd, Tag},
marker::*,
hash::{Hash32, HashAdd, Tag},
nonce::{self, NoNonces, NonceGen},
prelude::*,
rand_core::{RngCore, SeedableRng},
s, KeyPair, Point, Scalar, G,
KeyPair,
};

/// The MuSig context.
Expand Down Expand Up @@ -265,7 +263,7 @@ impl AggKey<EvenY> {
}
}

impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, NG> {
impl<H: Hash32, NG> MuSig<H, NG> {
/// Generates a new aggregated key from a list of individual keys.
///
/// Each party can be local (you know the secret key) or remote (you only know the public key).
Expand All @@ -290,7 +288,7 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, NG> {
/// ```
pub fn new_agg_key(&self, keys: Vec<Point>) -> AggKey<Normal> {
let coeff_hash = {
let L = self.pk_hash.clone().add(&keys[..]).finalize();
let L = self.pk_hash.clone().add(&keys[..]).finalize_fixed();
self.coeff_hash.clone().add(L.as_slice())
};

Expand Down Expand Up @@ -326,7 +324,7 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, NG> {

impl<H, NG> MuSig<H, NG>
where
H: Digest<OutputSize = U32> + Clone,
H: Hash32,
NG: NonceGen,
{
/// Seed a random number generator to be used for MuSig nonces.
Expand Down Expand Up @@ -437,7 +435,7 @@ pub struct SignSession<T = Ordinary> {
signing_type: T,
}

impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, NG> {
impl<H: Hash32, NG> MuSig<H, NG> {
/// Start a signing session.
///
/// You must provide the public nonces for this signing session in the correct order.
Expand Down Expand Up @@ -674,7 +672,7 @@ impl<H: Digest<OutputSize = U32> + Clone, NG> MuSig<H, NG> {
/// ```
pub fn new_with_deterministic_nonces<H>() -> MuSig<H, nonce::Deterministic<H>>
where
H: Tag + Digest<OutputSize = U32> + Default + Clone,
H: Hash32,
{
MuSig::default()
}
Expand All @@ -692,7 +690,7 @@ where
/// ```
pub fn new_with_synthetic_nonces<H, R>() -> MuSig<H, nonce::Synthetic<H, nonce::GlobalRng<R>>>
where
H: Tag + Digest<OutputSize = U32> + Default + Clone,
H: Hash32,
R: RngCore + Default + Clone,
{
MuSig::default()
Expand All @@ -703,7 +701,7 @@ where
/// You can still sign with this instance but you you will have to generate nonces in your own way.
pub fn new_without_nonce_generation<H>() -> MuSig<H, NoNonces>
where
H: Tag + Digest<OutputSize = U32> + Default,
H: Hash32,
{
MuSig::default()
}
Expand Down
Loading

0 comments on commit 2e748c4

Please sign in to comment.