Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for all test vectors in DKG #875

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 113 additions & 98 deletions frost-core/src/tests/vectors_dkg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Helper function for testing with test vectors.
use alloc::{collections::BTreeMap, string::ToString, vec::Vec};

use debugless_unwrap::DebuglessUnwrap;
use hex::{self};
use serde_json::Value;
Expand Down Expand Up @@ -44,76 +43,92 @@ fn json_to_element<C: Ciphersuite>(vector: &Value) -> <C::Group as Group>::Seria

/// Parse test vectors for a given ciphersuite.
#[allow(clippy::type_complexity)]
pub fn parse_test_vectors_dkg<C: Ciphersuite>(json_vectors: &Value) -> DKGTestVectors<C> {
pub fn parse_test_vectors_dkg<C: Ciphersuite>(json_vectors: &Value) -> Vec<DKGTestVectors<C>> {
let mut vectors: Vec<DKGTestVectors<C>> = Vec::new();
let inputs = &json_vectors["inputs"];
let participant = &inputs["1"];

let participant_1_id: Identifier<C> = (participant["identifier"].as_u64().unwrap() as u16)
.try_into()
.unwrap();
let participant_2_id: Identifier<C> = (inputs["2"]["identifier"].as_u64().unwrap() as u16)
.try_into()
.unwrap();
let participant_3_id: Identifier<C> = (inputs["3"]["identifier"].as_u64().unwrap() as u16)
.try_into()
.unwrap();

let mut round1_packages = BTreeMap::new();
round1_packages.insert(participant_2_id, build_round_1_package(json_vectors, 2));
round1_packages.insert(participant_3_id, build_round_1_package(json_vectors, 3));

let mut round2_packages = BTreeMap::new();
round2_packages.insert(participant_2_id, build_round_2_package(json_vectors, 2));
round2_packages.insert(participant_3_id, build_round_2_package(json_vectors, 3));
let max_participants = json_vectors["config"]["MAX_PARTICIPANTS"].as_u64().unwrap() as u16;
let min_signers = json_vectors["config"]["MIN_PARTICIPANTS"].as_u64().unwrap() as u16;

let secret =
SigningKey::deserialize(json_to_scalar::<C>(&participant["signing_key"]).as_ref()).unwrap();
for i in 1..=max_participants {
let participant_id_str = &i.to_string();
let participant_data = &inputs[participant_id_str];
let participant_id: Identifier<C> = (participant_data["identifier"].as_u64().unwrap()
as u16)
.try_into()
.unwrap();

let coefficient = <<C::Group as Group>::Field as Field>::deserialize(&json_to_scalar::<C>(
&participant["coefficient"],
))
.unwrap();
let mut round1_packages = BTreeMap::new();
let mut round2_packages = BTreeMap::new();
for (other_participant_id_str, other_participant_data) in inputs.as_object().unwrap() {
if participant_id_str == other_participant_id_str {
continue;
}
match other_participant_id_str.parse::<u16>() {
Ok(id) => id,
Err(_) => continue,
};
let other_participant_id: Identifier<C> =
(other_participant_data["identifier"].as_u64().unwrap() as u16)
.try_into()
.unwrap();
round1_packages.insert(
other_participant_id,
build_round_1_package(other_participant_data),
);
round2_packages.insert(
other_participant_id,
build_round_2_package(participant_data, other_participant_id_str),
);
}

let secret =
SigningKey::deserialize(json_to_scalar::<C>(&participant_data["signing_key"]).as_ref())
.unwrap();

let coefficient = <<C::Group as Group>::Field as Field>::deserialize(&json_to_scalar::<C>(
&participant_data["coefficient"],
))
.unwrap();

let public_key_package = build_public_key_package(json_vectors);
let public_key_package = build_public_key_package(json_vectors);

let verifying_share =
VerifyingShare::deserialize(json_to_element::<C>(&participant["verifying_share"]).as_ref())
.unwrap();
let verifying_share = VerifyingShare::deserialize(
json_to_element::<C>(&participant_data["verifying_share"]).as_ref(),
)
.unwrap();

let verifying_key =
VerifyingKey::deserialize(json_to_element::<C>(&inputs["verifying_key"]).as_ref()).unwrap();
let verifying_key =
VerifyingKey::deserialize(json_to_element::<C>(&inputs["verifying_key"]).as_ref())
.unwrap();

let signing_share =
SigningShare::deserialize(json_to_scalar::<C>(&participant["signing_share"]).as_ref())
.unwrap();
let signing_share = SigningShare::deserialize(
json_to_scalar::<C>(&participant_data["signing_share"]).as_ref(),
)
.unwrap();

let key_package = KeyPackage {
header: Header::default(),
identifier: participant_1_id,
signing_share,
verifying_share,
verifying_key,
min_signers: 2,
};

DKGTestVectors {
secret,
coefficient,
round1_packages,
round2_packages,
public_key_package,
key_package,
participant_id: participant_1_id,
let key_package = KeyPackage {
header: Header::default(),
identifier: participant_id,
signing_share,
verifying_share,
verifying_key,
min_signers,
};
vectors.push(DKGTestVectors {
secret,
coefficient,
round1_packages,
round2_packages,
public_key_package,
key_package,
participant_id,
})
}
vectors
}

fn build_round_1_package<C: Ciphersuite>(
json_vectors: &Value,
participant_num: usize,
) -> Round1Package<C> {
let inputs = &json_vectors["inputs"];
let participant = &inputs[participant_num.to_string()];
let vss_commitment = participant["vss_commitments"]
fn build_round_1_package<C: Ciphersuite>(json_vectors: &Value) -> Round1Package<C> {
let vss_commitment = json_vectors["vss_commitments"]
.as_array()
.unwrap()
.iter()
Expand All @@ -123,7 +138,7 @@ fn build_round_1_package<C: Ciphersuite>(
let commitment = VerifiableSecretSharingCommitment::deserialize(vss_commitment).unwrap();

let proof_of_knowledge = Signature::deserialize(
&hex::decode(participant["proof_of_knowledge"].as_str().unwrap()).unwrap(),
&hex::decode(json_vectors["proof_of_knowledge"].as_str().unwrap()).unwrap(),
)
.debugless_unwrap();

Expand All @@ -136,12 +151,10 @@ fn build_round_1_package<C: Ciphersuite>(

fn build_round_2_package<C: Ciphersuite>(
json_vectors: &Value,
sender_num: usize,
sender_num: &String,
) -> Round2Package<C> {
let inputs = &json_vectors["inputs"];

let signing_share = SigningShare::deserialize(
json_to_scalar::<C>(&inputs["1"]["signing_shares"][sender_num.to_string()]).as_ref(),
json_to_scalar::<C>(&json_vectors["signing_shares"][sender_num]).as_ref(),
)
.unwrap();

Expand Down Expand Up @@ -182,41 +195,43 @@ fn build_public_key_package<C: Ciphersuite>(json_vectors: &Value) -> PublicKeyPa

/// Test DKG with the given test vectors for a ciphersuite
pub fn check_dkg_keygen<C: Ciphersuite>(json_vectors: &Value) {
let DKGTestVectors {
secret,
coefficient,
round1_packages,
round2_packages,
public_key_package,
key_package,
participant_id,
} = parse_test_vectors_dkg(json_vectors);

let min_signers = 2;
let max_signers = 3;

let (coefficients, commitment) = generate_secret_polynomial(
&secret as &SigningKey<C>,
max_signers,
min_signers,
vec![coefficient],
)
.unwrap();
for dkg_vectors in parse_test_vectors_dkg(json_vectors) {
let DKGTestVectors {
secret,
coefficient,
round1_packages,
round2_packages,
public_key_package,
key_package,
participant_id,
} = dkg_vectors;

let min_signers = 2;
let max_signers = 3;

let (coefficients, commitment) = generate_secret_polynomial(
&secret as &SigningKey<C>,
max_signers,
min_signers,
vec![coefficient],
)
.unwrap();

let round1_secret_package = SecretPackage::new(
participant_id,
coefficients,
commitment.clone(),
min_signers,
max_signers,
);
let round1_secret_package = SecretPackage::new(
participant_id,
coefficients,
commitment.clone(),
min_signers,
max_signers,
);

let (round2_secret_package, _round2_packages_1) =
part2(round1_secret_package, &round1_packages).unwrap();
let (round2_secret_package, _round2_packages_1) =
part2(round1_secret_package, &round1_packages).unwrap();

let (expected_key_package, expected_public_key_package) =
part3(&round2_secret_package, &round1_packages, &round2_packages).unwrap();
let (expected_key_package, expected_public_key_package) =
part3(&round2_secret_package, &round1_packages, &round2_packages).unwrap();

assert_eq!(public_key_package, expected_public_key_package);
assert_eq!(key_package, expected_key_package);
assert_eq!(public_key_package, expected_public_key_package);
assert_eq!(key_package, expected_key_package);
}
}
4 changes: 2 additions & 2 deletions frost-ed25519/tests/helpers/vectors_dkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"3": "7fde55b354d5d8dddc940fe932de5d1a6110b9bc4edeba2db7b32c34074d3a0a"
},
"verifying_share": "f326b756ed38b43a94bdac698e044d9e3f3a08a40e7c9d2e5346dd5bfaadf2f5",
"signing_share": "80a16ad6cf78be27995d5e312722ff2d42a5b08380b49dbc2e7e65c124220e0a"
"signing_share": "b9ed88cb30a9ddbc00dbdf7c40d6c76f791989cf9f3119bad899287c5f6c2303"
},
"3": {
"identifier": 3,
Expand All @@ -49,7 +49,7 @@
"2": "6b3e57fab1e74e61aacfd93d4926172a7e878a48540fe97367721e38485b3a00"
},
"verifying_share": "6bc91a2755902d955ce220ad0df6fbf57162260949d40bcf5a69cfffec9c085a",
"signing_share": "8bd411475cdc423c1ba94cf11b80e776592d5f675419398800d17173d673f40a"
"signing_share": "35b2b8fad8352f6e6a7c8fee082f45a339a37f0085c1f662c44c3f10903d970d"
}
}
}
2 changes: 1 addition & 1 deletion frost-ed448/tests/helpers/vectors_dkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"proof_of_knowledge": "eb47491f2461792114d357d02102c1a806451cfa88f1297f7a671a87a04de0ffde478ec1c2b91e743379254fe84eb2e0d170c69aec88bc1980bf8009ffc93d6ee0c3713681aa303cf85595bd975953318ab07be9e56dc6ba22465793ee337e383562fafc7525c05b36732b93f5f4fee22300",
"signing_shares": {
"1": "77c1831adb90cd94d0404ec2a8730af57d4e29e10ad02e26ee61328c95f1258a17bad98617632d92ee5aa8224793231db3a599d322b82d2300",
"2": "e29c8b642abfa741710945aedadf34ac73ef6863c3e56d599cc3c58039d45b7382674cbd2c8e064c8bae33851c9166536181b83fe34ce02200"
"2": "6aa7e48f3d7f4de3b1a0bb95a5085705e5618b8f67d89cf43dd8d649057d295ff0c837e4a918634a94a773606ed156c9db543c3bcd1e2a0e00"
},
"verifying_share": "3a1b5a9945fc64b088174c34e16dbced81f824fe8f9f12d1ec98afd4ea593a6ec75a74f70b77522c66681bd468080b525963dbcc2785d53a00",
"signing_share": "da7c3a1048da9e6b8e480a72d48479ab4724f9804e96a44c7f7e04691ffbfdd7a56c2a9644e1ad1075baeae746ce8317f63104e87363652900"
Expand Down
16 changes: 13 additions & 3 deletions frost-secp256k1-tr/tests/helpers/vectors_dkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"signing_key": "68e3f6904c6043973515a36bf7801a71597da35733f21305d75a5234f06e4529",
"coefficient": "25d2d840a3e2718a431ec69e14ee8a015b000d43c7a9868060f01d5aa52a19d1",
"vss_commitments": ["03e7ba4acb164d2bd5eba4f47b3a788109ddb3f88f1181792424fa332123a25ea8", "037495e920a1f032916193aa80ea97a4c3a611dec9ab47ccc969deb664f5f88bbe"],
"proof_of_knowledge": "6689a8d414eb4961308e21f8caa1045236efded4f3de9209dc07547e88be3b42e192de9bed27fb78a7a4d4e35a0422f11f52631b8e66d69e609398eaff2770b8",
"proof_of_knowledge": "191a4ef1851286e2fd6cebd483385452cbb12f43386241854939252c4ed8846b8631f9e69be37ccbd3a0b4593a8f63738747e165a22d0b5786eeb74e59a17837",
"signing_shares": {
"2": "1dd3cb3e2370e6af22917415f0ad584514807b58b3cc40d2230a26e115f02771",
"3": "dd25ee86acd01f996618aa0d1153f5e8fbc929a8e8a18b8f0a15f91d087217e2"
Expand All @@ -27,15 +27,25 @@
"coefficient": "f7ba0cbbffbea8aaceb3ade54bdbf35bafb1cda15b65ad490e0c63dd069a7c9f",
"vss_commitments": ["03ef10370a008cd95e179dc51e2cb7828f30b72d254e5166484f927c84ab326582", "022ce0dac0db217ba326fbbe3e6132d45e2a4bfa0a0c3790d91eacce9a1c2d6a10"],
"proof_of_knowledge": "a319dd51cf64b3896c22f54154812d4ae76cfa95f46f53ef69241fd702456fef32da76cc93d3a541ca495b723e793ee90c32440da5f314e2e58a2dc30550314a",
"verifying_share": "029ecb3a4db28a82e7b8d600d42711b02790dde3f063f0ecec6f812c1c5d7dcefc"
"signing_shares": {
"1": "b489a711942526abbb5330a8215d2e740f7dbddec3452006993a8cea3ac278cb",
"3": "20255dc07b1fb78bdf90bd85fd2389c988c8250faee11826656a09142fa9fc97"
},
"verifying_share": "029ecb3a4db28a82e7b8d600d42711b02790dde3f063f0ecec6f812c1c5d7dcefc",
"signing_share": "9131f1241cd8f95f6439b0f5edc2ecb969a2d3db9c85fe5added77116d41d0ce"
},
"3": {
"identifier": 3,
"signing_key": "9a267f4cde8087a6eca0969425846209b41b515b73195ebbeeef8a991103f1ec",
"coefficient": "42ff6f39ce4f97f279781378ebcf93df47add84d75882cd31b266e83f76e25f6",
"vss_commitments": ["02da186c3863c5600b471a2799cb6f15ae4d8315a2f225c177798880e75ac820a0", "03e6a36e7fa4b117c1aa428886672e3a35d926bb4c585a9b07d8ee9a3387420067"],
"proof_of_knowledge": "6e115d9e63fd15d432b380ccf1ec4ed03340fcf96caeae8985aedb5f905b1a65dc422ffe5878988fbbc55454857736c7755d9c8f5ee6822c8833ea21d54dba36",
"verifying_share": "02c98b3c2e9f4bde4cf90dc9c7be639e5adda6ea09fc605239880a22cb836f7145"
"signing_shares": {
"1": "da5c7f5238079835fe71f746364bb8756a7dcb228aeea686fa2aaa44dfec929c",
"2": "0d47e4b622ee3804bff8cfe088653efefe865cce0c065aecbf7e318182b89e2d"
},
"verifying_share": "02c98b3c2e9f4bde4cf90dc9c7be639e5adda6ea09fc605239880a22cb836f7145",
"signing_share": "30a59cedaae84737d8ef28f9a128db7bd1f1fd8fb3373dfa139ce5e29a4555a9"
}
}
}