3.6.3 Check commitment encoding

Also extends tests of 3.6.2 and so on.
This commit is contained in:
Luke Parker 2023-02-28 21:57:18 -05:00
parent 7a05466049
commit 39b3452da1
No known key found for this signature in database

View file

@ -16,9 +16,9 @@ use dkg::tests::key_gen;
use crate::{ use crate::{
curve::Curve, curve::Curve,
Participant, ThresholdCore, ThresholdKeys, FrostError, Participant, ThresholdCore, ThresholdKeys, FrostError,
algorithm::{Schnorr, Hram}, algorithm::{IetfTranscript, Schnorr, Hram},
sign::{ sign::{
Nonce, GeneratorCommitments, NonceCommitments, Commitments, Writable, Preprocess, Writable, Nonce, GeneratorCommitments, NonceCommitments, Commitments, Preprocess,
PreprocessMachine, SignMachine, SignatureMachine, AlgorithmMachine, PreprocessMachine, SignMachine, SignatureMachine, AlgorithmMachine,
}, },
tests::{clone_without, recover_key, algorithm_machines, commit_and_shares, sign}, tests::{clone_without, recover_key, algorithm_machines, commit_and_shares, sign},
@ -36,6 +36,7 @@ pub struct Vectors {
pub nonce_randomness: Vec<[String; 2]>, pub nonce_randomness: Vec<[String; 2]>,
pub nonces: Vec<[String; 2]>, pub nonces: Vec<[String; 2]>,
pub commitments: Vec<[String; 2]>,
pub sig_shares: Vec<String>, pub sig_shares: Vec<String>,
@ -82,6 +83,14 @@ impl From<serde_json::Value> for Vectors {
.values() .values()
.map(|value| [to_str(&value["hiding_nonce"]), to_str(&value["binding_nonce"])]) .map(|value| [to_str(&value["hiding_nonce"]), to_str(&value["binding_nonce"])])
.collect(), .collect(),
commitments: value["round_one_outputs"]["participants"]
.as_object()
.unwrap()
.values()
.map(|value| {
[to_str(&value["hiding_nonce_commitment"]), to_str(&value["binding_nonce_commitment"])]
})
.collect(),
sig_shares: value["round_two_outputs"]["participants"] sig_shares: value["round_two_outputs"]["participants"]
.as_object() .as_object()
@ -195,18 +204,33 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
let nonces = [nonce(0), nonce(1)]; let nonces = [nonce(0), nonce(1)];
let these_commitments = let these_commitments =
[C::generator() * nonces[0].deref(), C::generator() * nonces[1].deref()]; [C::generator() * nonces[0].deref(), C::generator() * nonces[1].deref()];
let machine = machine.unsafe_override_preprocess(
vec![Nonce(nonces)], assert_eq!(
Preprocess { these_commitments[0].to_bytes().as_ref(),
commitments: Commitments { hex::decode(&vectors.commitments[c][0]).unwrap()
nonces: vec![NonceCommitments {
generators: vec![GeneratorCommitments(these_commitments)],
}],
dleq: None,
},
addendum: (),
},
); );
assert_eq!(
these_commitments[1].to_bytes().as_ref(),
hex::decode(&vectors.commitments[c][1]).unwrap()
);
let preprocess = Preprocess {
commitments: Commitments {
nonces: vec![NonceCommitments {
generators: vec![GeneratorCommitments(these_commitments)],
}],
dleq: None,
},
addendum: (),
};
// FROST doesn't specify how to serialize these together, yet this is sane
// (and the simplest option)
assert_eq!(
preprocess.serialize(),
hex::decode(vectors.commitments[c][0].clone() + &vectors.commitments[c][1]).unwrap()
);
let machine = machine.unsafe_override_preprocess(vec![Nonce(nonces)], preprocess);
commitments.insert( commitments.insert(
*i, *i,
@ -258,7 +282,7 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
// the current codebase // the current codebase
// A transparent RNG which has a fixed output // A transparent RNG which has a fixed output
struct TransparentRng(Option<[u8; 32]>); struct TransparentRng(Vec<[u8; 32]>);
impl RngCore for TransparentRng { impl RngCore for TransparentRng {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
unimplemented!() unimplemented!()
@ -267,7 +291,7 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
unimplemented!() unimplemented!()
} }
fn fill_bytes(&mut self, dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
dest.copy_from_slice(&self.0.take().unwrap()) dest.copy_from_slice(&self.0.remove(0))
} }
fn try_fill_bytes(&mut self, _: &mut [u8]) -> Result<(), rand_core::Error> { fn try_fill_bytes(&mut self, _: &mut [u8]) -> Result<(), rand_core::Error> {
unimplemented!() unimplemented!()
@ -286,21 +310,41 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
let share = Zeroizing::new( let share = Zeroizing::new(
C::read_F::<&[u8]>(&mut hex::decode(&vectors.shares[l - 1]).unwrap().as_ref()).unwrap(), C::read_F::<&[u8]>(&mut hex::decode(&vectors.shares[l - 1]).unwrap().as_ref()).unwrap(),
); );
for nonce in 0 .. 2 {
let randomness = vectors.nonce_randomness[i]
.iter()
.map(|randomness| hex::decode(randomness).unwrap().try_into().unwrap())
.collect::<Vec<_>>();
let nonces = vectors.nonces[i]
.iter()
.map(|nonce| {
Zeroizing::new(C::read_F::<&[u8]>(&mut hex::decode(nonce).unwrap().as_ref()).unwrap())
})
.collect::<Vec<_>>();
for (randomness, nonce) in randomness.iter().zip(&nonces) {
// Nonces are only present for participating signers, hence i // Nonces are only present for participating signers, hence i
assert_eq!( assert_eq!(C::random_nonce(&share, &mut TransparentRng(vec![*randomness])), *nonce);
C::random_nonce(
&share,
&mut TransparentRng(Some(
hex::decode(&vectors.nonce_randomness[i][nonce]).unwrap().try_into().unwrap()
))
),
Zeroizing::new(
C::read_F::<&[u8]>(&mut hex::decode(&vectors.nonces[i][nonce]).unwrap().as_ref())
.unwrap()
)
);
} }
// Also test it at the Commitments level
let (generated_nonces, commitments) = Commitments::<C>::new::<_, IetfTranscript>(
&mut TransparentRng(randomness),
&share,
&[vec![C::generator()]],
&[],
);
assert_eq!(generated_nonces.len(), 1);
assert_eq!(generated_nonces[0].0, [nonces[0].clone(), nonces[1].clone()]);
let mut commitments_bytes = vec![];
commitments.write(&mut commitments_bytes).unwrap();
assert_eq!(
commitments_bytes,
hex::decode(vectors.commitments[i][0].clone() + &vectors.commitments[i][1]).unwrap()
);
} }
// This doesn't verify C::random_nonce is called correctly, where the code should call it with // This doesn't verify C::random_nonce is called correctly, where the code should call it with
@ -334,13 +378,13 @@ pub fn test_with_vectors<R: RngCore + CryptoRng, C: Curve, H: Hram<C>>(
// Calculate the expected nonces // Calculate the expected nonces
let mut expected = (C::generator() * let mut expected = (C::generator() *
C::random_nonce(keys[i].secret_share(), &mut TransparentRng(Some(randomness.0))).deref()) C::random_nonce(keys[i].secret_share(), &mut TransparentRng(vec![randomness.0])).deref())
.to_bytes() .to_bytes()
.as_ref() .as_ref()
.to_vec(); .to_vec();
expected.extend( expected.extend(
(C::generator() * (C::generator() *
C::random_nonce(keys[i].secret_share(), &mut TransparentRng(Some(randomness.1))) C::random_nonce(keys[i].secret_share(), &mut TransparentRng(vec![randomness.1]))
.deref()) .deref())
.to_bytes() .to_bytes()
.as_ref(), .as_ref(),