Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up frost #191

Merged
merged 5 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading