Create a dedicated crate for the DKG (#141)

* Add dkg crate

* Remove F_len and G_len

They're generally no longer used.

* Replace hash_to_vec with a provided method around associated type H: Digest

Part of trying to minimize this trait so it can be moved elsewhere. Vec, 
which isn't std, may have been a blocker.

* Encrypt secret shares within the FROST library

Reduces requirements on callers in order to be correct.

* Update usage of Zeroize within FROST

* Inline functions in key_gen

There was no reason to have them separated as they were. sign probably 
has the same statement available, yet that isn't the focus right now.

* Add a ciphersuite package which provides hash_to_F

* Set the Ciphersuite version to something valid

* Have ed448 export Scalar/FieldElement/Point at the top level

* Move FROST over to Ciphersuite

* Correct usage of ff in ciphersuite

* Correct documentation handling

* Move Schnorr signatures to their own crate

* Remove unused feature from schnorr

* Fix Schnorr tests

* Split DKG into a separate crate

* Add serialize to Commitments and SecretShare

Helper for buf = vec![]; .write(buf).unwrap(); buf

* Move FROST over to the new dkg crate

* Update Monero lib to latest FROST

* Correct ethereum's usage of features

* Add serialize to GeneratorProof

* Add serialize helper function to FROST

* Rename AddendumSerialize to WriteAddendum

* Update processor

* Slight fix to processor
This commit is contained in:
Luke Parker
2022-10-29 03:54:42 -05:00
committed by GitHub
parent cbceaff678
commit 2379855b31
50 changed files with 2076 additions and 1601 deletions

View File

@@ -3,27 +3,25 @@ use std::io::{self, Read, Write};
use rand_core::{RngCore, CryptoRng};
use zeroize::Zeroize;
use transcript::Transcript;
use crate::{Curve, FrostError, FrostView, schnorr};
use crate::{Curve, FrostError, ThresholdView};
pub use schnorr::SchnorrSignature;
/// Serialize an addendum to a writer.
pub trait AddendumSerialize {
/// Write an addendum to a writer.
pub trait WriteAddendum {
fn write<W: Write>(&self, writer: &mut W) -> io::Result<()>;
}
impl AddendumSerialize for () {
impl WriteAddendum for () {
fn write<W: Write>(&self, _: &mut W) -> io::Result<()> {
Ok(())
}
}
/// Trait alias for the requirements to be used as an addendum.
pub trait Addendum: Clone + PartialEq + Debug + Zeroize + AddendumSerialize {}
impl<A: Clone + PartialEq + Debug + Zeroize + AddendumSerialize> Addendum for A {}
pub trait Addendum: Clone + PartialEq + Debug + WriteAddendum {}
impl<A: Clone + PartialEq + Debug + WriteAddendum> Addendum for A {}
/// Algorithm trait usable by the FROST signing machine to produce signatures..
pub trait Algorithm<C: Curve>: Clone {
@@ -46,7 +44,7 @@ pub trait Algorithm<C: Curve>: Clone {
fn preprocess_addendum<R: RngCore + CryptoRng>(
&mut self,
rng: &mut R,
params: &FrostView<C>,
params: &ThresholdView<C>,
) -> Self::Addendum;
/// Read an addendum from a reader.
@@ -55,7 +53,7 @@ pub trait Algorithm<C: Curve>: Clone {
/// Proccess the addendum for the specified participant. Guaranteed to be called in order.
fn process_addendum(
&mut self,
params: &FrostView<C>,
params: &ThresholdView<C>,
l: u16,
reader: Self::Addendum,
) -> Result<(), FrostError>;
@@ -66,7 +64,7 @@ pub trait Algorithm<C: Curve>: Clone {
/// The nonce will already have been processed into the combined form d + (e * p).
fn sign_share(
&mut self,
params: &FrostView<C>,
params: &ThresholdView<C>,
nonce_sums: &[Vec<C::G>],
nonces: &[C::F],
msg: &[u8],
@@ -149,44 +147,36 @@ impl<C: Curve, H: Hram<C>> Algorithm<C> for Schnorr<C, H> {
vec![vec![C::generator()]]
}
fn preprocess_addendum<R: RngCore + CryptoRng>(&mut self, _: &mut R, _: &FrostView<C>) {}
fn preprocess_addendum<R: RngCore + CryptoRng>(&mut self, _: &mut R, _: &ThresholdView<C>) {}
fn read_addendum<R: Read>(&self, _: &mut R) -> io::Result<Self::Addendum> {
Ok(())
}
fn process_addendum(&mut self, _: &FrostView<C>, _: u16, _: ()) -> Result<(), FrostError> {
fn process_addendum(&mut self, _: &ThresholdView<C>, _: u16, _: ()) -> Result<(), FrostError> {
Ok(())
}
fn sign_share(
&mut self,
params: &FrostView<C>,
params: &ThresholdView<C>,
nonce_sums: &[Vec<C::G>],
nonces: &[C::F],
msg: &[u8],
) -> C::F {
let c = H::hram(&nonce_sums[0][0], &params.group_key(), msg);
self.c = Some(c);
schnorr::sign::<C>(params.secret_share(), nonces[0], c).s
SchnorrSignature::<C>::sign(params.secret_share(), nonces[0], c).s
}
#[must_use]
fn verify(&self, group_key: C::G, nonces: &[Vec<C::G>], sum: C::F) -> Option<Self::Signature> {
let sig = SchnorrSignature { R: nonces[0][0], s: sum };
if schnorr::verify::<C>(group_key, self.c.unwrap(), &sig) {
Some(sig)
} else {
None
}
Some(sig).filter(|sig| sig.verify(group_key, self.c.unwrap()))
}
#[must_use]
fn verify_share(&self, verification_share: C::G, nonces: &[Vec<C::G>], share: C::F) -> bool {
schnorr::verify::<C>(
verification_share,
self.c.unwrap(),
&SchnorrSignature { R: nonces[0][0], s: share },
)
SchnorrSignature::<C> { R: nonces[0][0], s: share }.verify(verification_share, self.c.unwrap())
}
}