Update FROST signing to match the IETF draft

Modernizes dependencies
This commit is contained in:
Luke Parker
2022-04-23 03:49:30 -04:00
parent 76a6ff46be
commit e22dcb1441
18 changed files with 226 additions and 724 deletions

View File

@@ -1,3 +1 @@
Cargo.lock
.build
c/.build

View File

@@ -12,16 +12,13 @@ thiserror = "1"
rand_core = "0.6"
hex = "0.4"
digest = "0.9"
tiny-keccak = { version = "2.0", features = ["keccak"] }
blake2 = "0.9"
blake2 = "0.10"
curve25519-dalek = { version = "3.2", features = ["std", "simd_backend"] }
ff = { version = "0.10", optional = true }
group = { version = "0.10", optional = true }
ff = { version = "0.11", optional = true }
group = { version = "0.11", optional = true }
dalek-ff-group = { path = "../dalek-ff-group", optional = true }
frost = { path = "../frost", optional = true }

View File

@@ -1,7 +1,6 @@
use rand_core::{RngCore, CryptoRng};
use digest::Digest;
use blake2::Blake2b;
use blake2::{Digest, Blake2b512};
use curve25519_dalek::{
constants::ED25519_BASEPOINT_TABLE,
@@ -82,10 +81,10 @@ pub(crate) fn sign_core(
let z;
let mut next_rand = rand_source;
next_rand = Blake2b::digest(&next_rand).as_slice().try_into().unwrap();
next_rand = Blake2b512::digest(&next_rand).as_slice().try_into().unwrap();
{
let a = Scalar::from_bytes_mod_order_wide(&next_rand);
next_rand = Blake2b::digest(&next_rand).as_slice().try_into().unwrap();
next_rand = Blake2b512::digest(&next_rand).as_slice().try_into().unwrap();
C_out = commitment(&a, ssr.amount);
for member in &ssr.ring {
@@ -149,7 +148,7 @@ pub(crate) fn sign_core(
s.resize(n, Scalar::zero());
while j != i {
s[j] = Scalar::from_bytes_mod_order_wide(&next_rand);
next_rand = Blake2b::digest(&next_rand).as_slice().try_into().unwrap();
next_rand = Blake2b512::digest(&next_rand).as_slice().try_into().unwrap();
let c_p = mu_P * c;
let c_c = mu_C * c;

View File

@@ -1,7 +1,6 @@
use rand_core::{RngCore, CryptoRng};
use digest::Digest;
use blake2::Blake2b;
use blake2::{Digest, Blake2b512};
use curve25519_dalek::{
constants::ED25519_BASEPOINT_TABLE,
@@ -11,7 +10,7 @@ use curve25519_dalek::{
use dalek_ff_group as dfg;
use group::Group;
use frost::{Curve, FrostError, algorithm::Algorithm};
use frost::{Curve, FrostError, algorithm::Algorithm, sign::ParamsView};
use monero::util::ringct::{Key, Clsag};
@@ -94,11 +93,11 @@ impl Algorithm<Ed25519> for Multisig {
fn preprocess_addendum<R: RngCore + CryptoRng>(
rng: &mut R,
group_key: &dfg::EdwardsPoint,
view: &ParamsView<Ed25519>,
nonces: &[dfg::Scalar; 2]
) -> Vec<u8> {
#[allow(non_snake_case)]
let H = hash_to_point(&group_key.0);
let H = hash_to_point(&view.group_key().0);
let h0 = nonces[0].0 * H;
let h1 = nonces[1].0 * H;
// 32 + 32 + 64 + 64
@@ -112,6 +111,7 @@ impl Algorithm<Ed25519> for Multisig {
fn process_addendum(
&mut self,
_: &ParamsView<Ed25519>,
l: usize,
commitments: &[dfg::EdwardsPoint; 2],
p: &dfg::Scalar,
@@ -147,19 +147,32 @@ impl Algorithm<Ed25519> for Multisig {
fn sign_share(
&mut self,
_: dfg::EdwardsPoint,
secret: dfg::Scalar,
nonce: dfg::Scalar,
view: &ParamsView<Ed25519>,
nonce_sum: dfg::EdwardsPoint,
_: &[u8],
nonce: dfg::Scalar,
_: &[u8]
) -> dfg::Scalar {
// Use everyone's commitments to derive a random source all signers can agree upon
// Cannot be manipulated to effect and all signers must, and will, know this
let rand_source = Blake2b::new().chain("Clsag_randomness").chain(&self.b).finalize().as_slice().try_into().unwrap();
#[allow(non_snake_case)]
let (clsag, c, mu_C, z, mu_P, C_out) = sign_core(rand_source, self.image, &self.msg, &self.ssr, nonce_sum.0, self.AH.0);
let rand_source = Keccak::v512()
.chain("Clsag_randomness")
.chain(&self.b)
.finalize()
.as_slice()
.try_into()
.unwrap();
let share = dfg::Scalar(nonce.0 - (c * (mu_P * secret.0)));
#[allow(non_snake_case)]
let (clsag, c, mu_C, z, mu_P, C_out) = sign_core(
rand_source,
self.image,
&self.msg,
&self.ssr,
nonce_sum.0,
self.AH.0
);
let share = dfg::Scalar(nonce.0 - (c * (mu_P * view.secret_share().0)));
self.interim = Some(ClsagSignInterim { c, mu_C, z, mu_P, clsag, C_out });
share

View File

@@ -2,8 +2,7 @@ use core::convert::TryInto;
use rand_core::{RngCore, CryptoRng};
use digest::Digest;
use blake2::Blake2b;
use blake2::{Digest, Blake2b512};
use curve25519_dalek::{
constants::ED25519_BASEPOINT_TABLE as DTable,
@@ -49,6 +48,14 @@ impl Curve for Ed25519 {
EdwardsPoint(DPoint::vartime_multiscalar_mul(scalars, points))
}
fn hash_msg(msg: &[u8]) -> Vec<u8> {
Blake2b512::digest(msg)
}
fn hash_to_F(data: &[u8]) -> Self::F {
dfg::Scalar::from_hash(Blake2b512::new().chain(data))
}
fn F_len() -> usize {
32
}
@@ -61,19 +68,13 @@ impl Curve for Ed25519 {
let scalar = Self::F::from_repr(
slice.try_into().map_err(|_| CurveError::InvalidLength(32, slice.len()))?
);
if scalar.is_some() {
if scalar.is_some().unwrap_u8() == 1 {
Ok(scalar.unwrap())
} else {
Err(CurveError::InvalidScalar(hex::encode(slice)))
Err(CurveError::InvalidScalar)
}
}
fn F_from_le_slice_unreduced(slice: &[u8]) -> Self::F {
let mut wide: [u8; 64] = [0; 64];
wide[..slice.len()].copy_from_slice(slice);
dfg::Scalar::from_bytes_mod_order_wide(&wide)
}
fn G_from_slice(slice: &[u8]) -> Result<Self::G, CurveError> {
let point = dfg::CompressedEdwardsY::new(
slice.try_into().map_err(|_| CurveError::InvalidLength(32, slice.len()))?
@@ -83,11 +84,11 @@ impl Curve for Ed25519 {
let point = point.unwrap();
// Ban torsioned points
if !point.is_torsion_free() {
Err(CurveError::InvalidPoint(hex::encode(slice)))?
Err(CurveError::InvalidPoint)?
}
Ok(point)
} else {
Err(CurveError::InvalidPoint(hex::encode(slice)))?
Err(CurveError::InvalidPoint)
}
}
@@ -98,10 +99,6 @@ impl Curve for Ed25519 {
fn G_to_bytes(g: &Self::G) -> Vec<u8> {
g.compress().to_bytes().to_vec()
}
fn F_from_bytes_wide(bytes: [u8; 64]) -> Self::F {
dfg::Scalar::from_bytes_mod_order_wide(&bytes)
}
}
// Used to prove legitimacy in several locations
@@ -124,7 +121,7 @@ impl DLEqProof {
let R2 = r * H;
let c = DScalar::from_hash(
Blake2b::new()
Blake2b512::new()
.chain(R1.compress().to_bytes())
.chain(R2.compress().to_bytes())
.chain((secret * &DTable).compress().to_bytes())
@@ -148,7 +145,7 @@ impl DLEqProof {
let R2 = (s * H) - (c * alt);
let expected_c = DScalar::from_hash(
Blake2b::new()
Blake2b512::new()
.chain(R1.compress().to_bytes())
.chain(R2.compress().to_bytes())
.chain(primary.compress().to_bytes())