mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 19:49:22 +00:00
3.6.3 Check commitment encoding
Also extends tests of 3.6.2 and so on.
This commit is contained in:
parent
7a05466049
commit
39b3452da1
1 changed files with 74 additions and 30 deletions
|
@ -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(),
|
||||||
|
|
Loading…
Reference in a new issue