Skip to content
Closed
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
77 changes: 68 additions & 9 deletions frost-core/src/tests/ciphersuite_generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use rand_core::{CryptoRng, RngCore};

use crate as frost;
use crate::keys::dkg::{round1, round2};
use crate::keys::SigningShare;
use crate::keys::{SecretShare, SigningShare};
use crate::round1::SigningNonces;
use crate::round2::SignatureShare;
use crate::{
keys::PublicKeyPackage, Error, Field, Group, Identifier, Signature, SigningKey, SigningPackage,
Expand All @@ -26,6 +27,8 @@ pub fn check_zero_key_fails<C: Ciphersuite>() {
/// Test share generation with a Ciphersuite
pub fn check_share_generation<C: Ciphersuite, R: RngCore + CryptoRng>(mut rng: R) {
let secret = crate::SigningKey::<C>::new(&mut rng);
// Simulate serialization / deserialization to ensure it works
let secret = SigningKey::deserialize(&secret.serialize()).unwrap();

let max_signers = 5;
let min_signers = 3;
Expand Down Expand Up @@ -110,20 +113,30 @@ pub fn check_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(

let max_signers = 5;
let min_signers = 3;
let (shares, pubkeys) = frost::keys::generate_with_dealer(
let (shares, pub_key_package) = frost::keys::generate_with_dealer(
max_signers,
min_signers,
frost::keys::IdentifierList::Default,
&mut rng,
)
.unwrap();
// Simulate serialization / deserialization to ensure it works
let pub_key_package =
PublicKeyPackage::deserialize(&pub_key_package.serialize().unwrap()).unwrap();

// Verifies the secret shares from the dealer
let key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> = shares
.into_iter()
.map(|(k, v)| (k, frost::keys::KeyPackage::try_from(v).unwrap()))
.collect();
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
BTreeMap::new();

for (k, v) in shares {
// Simulate serialization / deserialization to ensure it works
let v = SecretShare::<C>::deserialize(&v.serialize().unwrap()).unwrap();
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
// Simulate serialization / deserialization to ensure it works
let key_package =
frost::keys::KeyPackage::deserialize(&key_package.serialize().unwrap()).unwrap();
key_packages.insert(k, key_package);
}
// Check if it fails with not enough signers. Usually this would return an
// error before even running the signing procedure, because `KeyPackage`
// contains the correct `min_signers` value and the signing procedure checks
Expand All @@ -144,11 +157,11 @@ pub fn check_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
})
.collect(),
&mut rng,
pubkeys.clone(),
pub_key_package.clone(),
);
assert_eq!(r, Err(Error::InvalidSignature));

check_sign(min_signers, key_packages, rng, pubkeys).unwrap()
check_sign(min_signers, key_packages, rng, pub_key_package).unwrap()
}

/// Test FROST signing with trusted dealer fails with invalid numbers of signers.
Expand Down Expand Up @@ -203,7 +216,10 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
// Round 1: generating nonces and signing commitments for each participant
////////////////////////////////////////////////////////////////////////////

for participant_identifier in key_packages.keys().take(min_signers as usize).cloned() {
for participant_identifier in key_packages.keys().take(min_signers as usize) {
// Simulate serialization / deserialization to ensure it works
let participant_identifier =
Identifier::deserialize(&participant_identifier.serialize()).unwrap();
// Generate one (1) nonce and one SigningCommitments instance for each
// participant, up to _min_signers_.
let (nonces, commitments) = frost::round1::commit(
Expand All @@ -213,6 +229,11 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
.signing_share(),
&mut rng,
);
// Simulate serialization / deserialization to ensure it works
let nonces = SigningNonces::deserialize(&nonces.serialize().unwrap()).unwrap();
let commitments =
frost::round1::SigningCommitments::deserialize(&commitments.serialize().unwrap())
.unwrap();
nonces_map.insert(participant_identifier, nonces);
commitments_map.insert(participant_identifier, commitments);
}
Expand All @@ -223,6 +244,9 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
let mut signature_shares = BTreeMap::new();
let message = "message to sign".as_bytes();
let signing_package = SigningPackage::new(commitments_map, message);
// Simulate serialization / deserialization to ensure it works
let signing_package =
SigningPackage::deserialize(&signing_package.serialize().unwrap()).unwrap();

////////////////////////////////////////////////////////////////////////////
// Round 2: each participant generates their signature share
Expand All @@ -241,6 +265,8 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(

// Each participant generates their signature share.
let signature_share = frost::round2::sign(&signing_package, nonces_to_use, key_package)?;
// Simulate serialization / deserialization to ensure it works
let signature_share = SignatureShare::deserialize(&signature_share.serialize()).unwrap();
signature_shares.insert(*participant_identifier, signature_share);
}

Expand All @@ -265,6 +291,8 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(

// Aggregate (also verifies the signature shares)
let group_signature = frost::aggregate(&signing_package, &signature_shares, &pubkey_package)?;
// Simulate serialization / deserialization to ensure it works
let group_signature = Signature::deserialize(&group_signature.serialize().unwrap()).unwrap();

// Check that the threshold signature can be verified by the group public
// key (the verification key).
Expand Down Expand Up @@ -451,6 +479,16 @@ where
frost::keys::dkg::part1(participant_identifier, max_signers, min_signers, &mut rng)
.unwrap();

// Simulate serialization / deserialization to ensure it works
let round1_secret_package = frost::keys::dkg::round1::SecretPackage::<C>::deserialize(
&round1_secret_package.serialize().unwrap(),
)
.unwrap();
let round1_package = frost::keys::dkg::round1::Package::<C>::deserialize(
&round1_package.serialize().unwrap(),
)
.unwrap();

// Store the participant's secret package for later use.
// In practice each participant will store it in their own environment.
round1_secret_packages.insert(
Expand Down Expand Up @@ -507,6 +545,12 @@ where
let (round2_secret_package, round2_packages) =
frost::keys::dkg::part2(round1_secret_package, round1_packages).expect("should work");

// Simulate serialization / deserialization to ensure it works
let round2_secret_package = frost::keys::dkg::round2::SecretPackage::<C>::deserialize(
&round2_secret_package.serialize().unwrap(),
)
.unwrap();

// Store the participant's secret package for later use.
// In practice each participant will store it in their own environment.
round2_secret_packages.insert(
Expand All @@ -522,6 +566,11 @@ where
// Note that, in contrast to the previous part, here each other participant
// gets its own specific package.
for (receiver_identifier, round2_package) in round2_packages {
// Simulate serialization / deserialization to ensure it works
let round2_package = frost::keys::dkg::round2::Package::<C>::deserialize(
&round2_package.serialize().unwrap(),
)
.unwrap();
received_round2_packages
.entry(receiver_identifier)
.or_insert_with(BTreeMap::new)
Expand Down Expand Up @@ -572,6 +621,13 @@ where
&received_round2_packages[&participant_identifier],
)
.unwrap();
// Simulate serialization / deserialization to ensure it works
let key_package =
frost::keys::KeyPackage::deserialize(&key_package.serialize().unwrap()).unwrap();
let pubkey_package_for_participant = frost::keys::PublicKeyPackage::deserialize(
&pubkey_package_for_participant.serialize().unwrap(),
)
.unwrap();
verifying_shares.insert(participant_identifier, key_package.verifying_share);
// Test if all verifying_key are equal
if let Some(previous_verifying_key) = verifying_key {
Expand All @@ -593,6 +649,9 @@ where
.unwrap()
.1
.clone();
// Simulate serialization / deserialization to ensure it works
let pubkeys =
frost::keys::PublicKeyPackage::deserialize(&pubkeys.serialize().unwrap()).unwrap();

// Proceed with the signing test.
check_sign(min_signers, key_packages, rng, pubkeys).unwrap()
Expand Down
40 changes: 38 additions & 2 deletions frost-core/src/tests/refresh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ pub fn check_refresh_shares_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
&mut rng,
)
.unwrap();
// Simulate serialization / deserialization to ensure it works
let new_pub_key_package =
frost::keys::PublicKeyPackage::deserialize(&new_pub_key_package.serialize().unwrap())
.unwrap();

// Each participant refreshes their share

Expand All @@ -79,14 +83,16 @@ pub fn check_refresh_shares_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
let current_share = &old_key_packages[&identifier];
// Do a serialization roundtrip to simulate real usage
let zero_share = SecretShare::deserialize(&zero_shares[i].serialize().unwrap()).unwrap();
let new_share = refresh_share(zero_share, current_share);
let new_share = refresh_share(zero_share, current_share).unwrap();
new_shares.insert(identifier, new_share);
}

let mut key_packages: BTreeMap<frost::Identifier<C>, KeyPackage<C>> = BTreeMap::new();

for (k, v) in new_shares {
key_packages.insert(k, v.unwrap());
// Simulate serialization / deserialization to ensure it works
let v = KeyPackage::<C>::deserialize(&v.serialize().unwrap()).unwrap();
key_packages.insert(k, v);
}
check_sign(MIN_SIGNERS, key_packages, rng, new_pub_key_package).unwrap();
}
Expand Down Expand Up @@ -371,6 +377,16 @@ where
let (round1_secret_package, round1_package) =
refresh_dkg_part1(participant_identifier, max_signers, min_signers, &mut rng).unwrap();

// Simulate serialization / deserialization to ensure it works
let round1_secret_package = frost::keys::dkg::round1::SecretPackage::<C>::deserialize(
&round1_secret_package.serialize().unwrap(),
)
.unwrap();
let round1_package = frost::keys::dkg::round1::Package::<C>::deserialize(
&round1_package.serialize().unwrap(),
)
.unwrap();

// Store the participant's secret package for later use.
// In practice each participant will store it in their own environment.
round1_secret_packages.insert(
Expand Down Expand Up @@ -421,6 +437,12 @@ where
let (round2_secret_package, round2_packages) =
refresh_dkg_part2(round1_secret_package, round1_packages).expect("should work");

// Simulate serialization / deserialization to ensure it works
let round2_secret_package = frost::keys::dkg::round2::SecretPackage::<C>::deserialize(
&round2_secret_package.serialize().unwrap(),
)
.unwrap();

// Store the participant's secret package for later use.
// In practice each participant will store it in their own environment.
round2_secret_packages.insert(
Expand All @@ -436,6 +458,11 @@ where
// Note that, in contrast to the previous part, here each other participant
// gets its own specific package.
for (receiver_identifier, round2_package) in round2_packages {
// Simulate serialization / deserialization to ensure it works
let round2_package = frost::keys::dkg::round2::Package::<C>::deserialize(
&round2_package.serialize().unwrap(),
)
.unwrap();
received_round2_packages
.entry(receiver_identifier)
.or_insert_with(BTreeMap::new)
Expand Down Expand Up @@ -488,6 +515,12 @@ where
old_key_packages[&participant_identifier].clone(),
)
.unwrap();
// Simulate serialization / deserialization to ensure it works
let key_package = KeyPackage::deserialize(&key_package.serialize().unwrap()).unwrap();
let pubkey_package_for_participant = frost::keys::PublicKeyPackage::deserialize(
&pubkey_package_for_participant.serialize().unwrap(),
)
.unwrap();
verifying_shares.insert(participant_identifier, key_package.verifying_share);
// Test if all verifying_key are equal
if let Some(previous_verifying_key) = verifying_key {
Expand All @@ -509,6 +542,9 @@ where
.unwrap()
.1
.clone();
// Simulate serialization / deserialization to ensure it works
let pubkeys =
frost::keys::PublicKeyPackage::deserialize(&pubkeys.serialize().unwrap()).unwrap();

// Proceed with the signing test.
check_sign(min_signers, key_packages, rng, pubkeys).unwrap()
Expand Down
Loading