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

@@ -1,17 +1,6 @@
use zeroize::Zeroize;
use group::GroupEncoding;
use sha2::{Digest, Sha256};
use group::{
ff::{Field, PrimeField},
GroupEncoding,
};
use elliptic_curve::{
generic_array::GenericArray,
bigint::{Encoding, U384},
hash2curve::{Expander, ExpandMsg, ExpandMsgXmd},
};
use ciphersuite::Ciphersuite;
use crate::{curve::Curve, algorithm::Hram};
@@ -19,87 +8,37 @@ macro_rules! kp_curve {
(
$feature: literal,
$lib: ident,
$Curve: ident,
$Hram: ident,
$ID: literal,
$CONTEXT: literal
) => {
#[cfg_attr(docsrs, doc(cfg(feature = $feature)))]
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
pub struct $Curve;
impl $Curve {
fn hash(dst: &[u8], data: &[u8]) -> Sha256 {
Sha256::new().chain_update(&[$CONTEXT.as_ref(), dst, data].concat())
}
}
pub use ciphersuite::$Curve;
impl Curve for $Curve {
type F = $lib::Scalar;
type G = $lib::ProjectivePoint;
const ID: &'static [u8] = $ID;
fn generator() -> Self::G {
$lib::ProjectivePoint::GENERATOR
}
fn hash_to_vec(dst: &[u8], data: &[u8]) -> Vec<u8> {
Self::hash(dst, data).finalize().to_vec()
}
fn hash_to_F(dst: &[u8], msg: &[u8]) -> Self::F {
let mut dst = &[$CONTEXT, dst].concat();
let oversize = Sha256::digest([b"H2C-OVERSIZE-DST-".as_ref(), dst].concat()).to_vec();
if dst.len() > 255 {
dst = &oversize;
}
// While one of these two libraries does support directly hashing to the Scalar field, the
// other doesn't. While that's probably an oversight, this is a universally working method
let mut modulus = vec![0; 16];
modulus.extend((Self::F::zero() - Self::F::one()).to_bytes());
let modulus = U384::from_be_slice(&modulus).wrapping_add(&U384::ONE);
let mut unreduced = U384::from_be_bytes({
let mut bytes = [0; 48];
ExpandMsgXmd::<Sha256>::expand_message(&[msg], dst, 48).unwrap().fill_bytes(&mut bytes);
bytes
})
.reduce(&modulus)
.unwrap()
.to_be_bytes();
let mut array = *GenericArray::from_slice(&unreduced[16 ..]);
let res = $lib::Scalar::from_repr(array).unwrap();
unreduced.zeroize();
array.zeroize();
res
}
const CONTEXT: &'static [u8] = $CONTEXT;
}
#[cfg_attr(docsrs, doc(cfg(feature = $feature)))]
#[derive(Clone)]
pub struct $Hram;
impl Hram<$Curve> for $Hram {
#[allow(non_snake_case)]
fn hram(R: &$lib::ProjectivePoint, A: &$lib::ProjectivePoint, m: &[u8]) -> $lib::Scalar {
$Curve::hash_to_F(b"chal", &[R.to_bytes().as_ref(), A.to_bytes().as_ref(), m].concat())
fn hram(
R: &<$Curve as Ciphersuite>::G,
A: &<$Curve as Ciphersuite>::G,
m: &[u8],
) -> <$Curve as Ciphersuite>::F {
<$Curve as Curve>::hash_to_F(
b"chal",
&[R.to_bytes().as_ref(), A.to_bytes().as_ref(), m].concat(),
)
}
}
};
}
#[cfg(feature = "p256")]
kp_curve!("p256", p256, P256, IetfP256Hram, b"P-256", b"FROST-P256-SHA256-v11");
kp_curve!("p256", P256, IetfP256Hram, b"FROST-P256-SHA256-v11");
#[cfg(feature = "secp256k1")]
kp_curve!(
"secp256k1",
k256,
Secp256k1,
IetfSecp256k1Hram,
b"secp256k1",
b"FROST-secp256k1-SHA256-v11"
);
kp_curve!("secp256k1", Secp256k1, IetfSecp256k1Hram, b"FROST-secp256k1-SHA256-v11");