Convert all HashMaps to BTreeMaps (#547)
Convert HashMaps to BTreeMaps (#476)
This commit is contained in:
parent
a5dc479b4d
commit
ba3ef7dbb8
|
@ -58,7 +58,7 @@ calls
|
|||
[`dkg::part2()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/keys/dkg/fn.part2.html)
|
||||
passing their own previously created `round1::SecretPackage` and the list of
|
||||
received `round1::Packages`. It returns a `round2::SecretPackage` and a
|
||||
`HashMap` mapping other participants's `Identifier`s to `round2::Package`s:
|
||||
`BTreeMap` mapping other participants's `Identifier`s to `round2::Package`s:
|
||||
|
||||
```rust,no_run,noplayground
|
||||
{{#include ../../../frost-ristretto255/dkg.md:dkg_part2}}
|
||||
|
|
|
@ -8,7 +8,7 @@ channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel).
|
|||
|
||||
To generate the key shares, the dealer calls
|
||||
[`generate_with_dealer()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/keys/fn.generate_with_dealer.html).
|
||||
It returns a `HashMap` mapping the (automatically generated) `Identifier`s to
|
||||
It returns a `BTreeMap` mapping the (automatically generated) `Identifier`s to
|
||||
their respective `SecretShare`s, and a `PublicKeyPackage` which contains the
|
||||
`VerifyingShare` for each participant and the group public key (`VerifyingKey`).
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Ciphersuite-generic benchmark functions.
|
||||
#![allow(clippy::unwrap_used)]
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use criterion::{BenchmarkId, Criterion, Throughput};
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
@ -113,8 +113,8 @@ pub fn bench_sign<C: Ciphersuite, R: RngCore + CryptoRng + Clone>(
|
|||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
HashMap::new();
|
||||
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
for (k, v) in shares {
|
||||
key_packages.insert(k, frost::keys::KeyPackage::try_from(v).unwrap());
|
||||
|
@ -137,7 +137,7 @@ pub fn bench_sign<C: Ciphersuite, R: RngCore + CryptoRng + Clone>(
|
|||
},
|
||||
);
|
||||
|
||||
let mut nonces: HashMap<_, _> = HashMap::new();
|
||||
let mut nonces: BTreeMap<_, _> = BTreeMap::new();
|
||||
let mut commitments: BTreeMap<_, _> = BTreeMap::new();
|
||||
|
||||
for participant_index in 1..=min_signers {
|
||||
|
@ -173,7 +173,7 @@ pub fn bench_sign<C: Ciphersuite, R: RngCore + CryptoRng + Clone>(
|
|||
},
|
||||
);
|
||||
|
||||
let mut signature_shares = HashMap::new();
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
for participant_identifier in nonces.keys() {
|
||||
let key_package = key_packages.get(participant_identifier).unwrap();
|
||||
let nonces_to_use = &nonces.get(participant_identifier).unwrap();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//! generation and the FROST rounds.
|
||||
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet, HashMap},
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
fmt::{self, Debug},
|
||||
};
|
||||
|
||||
|
@ -408,7 +408,7 @@ where
|
|||
/// service attack due to publishing an invalid signature.
|
||||
pub fn aggregate<C>(
|
||||
signing_package: &SigningPackage<C>,
|
||||
signature_shares: &HashMap<Identifier<C>, round2::SignatureShare<C>>,
|
||||
signature_shares: &BTreeMap<Identifier<C>, round2::SignatureShare<C>>,
|
||||
pubkeys: &keys::PublicKeyPackage<C>,
|
||||
) -> Result<Signature<C>, Error<C>>
|
||||
where
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#![allow(clippy::type_complexity)]
|
||||
|
||||
use std::{
|
||||
collections::{BTreeSet, HashMap, HashSet},
|
||||
collections::{BTreeMap, BTreeSet, HashSet},
|
||||
convert::TryFrom,
|
||||
default::Default,
|
||||
fmt::{self, Debug},
|
||||
|
@ -458,7 +458,7 @@ pub fn generate_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList<C>,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>), Error<C>> {
|
||||
) -> Result<(BTreeMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>), Error<C>> {
|
||||
let mut bytes = [0; 64];
|
||||
rng.fill_bytes(&mut bytes);
|
||||
|
||||
|
@ -479,7 +479,7 @@ pub fn split<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList<C>,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>), Error<C>> {
|
||||
) -> Result<(BTreeMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>), Error<C>> {
|
||||
validate_num_of_signers(min_signers, max_signers)?;
|
||||
|
||||
if let IdentifierList::Custom(identifiers) = &identifiers {
|
||||
|
@ -501,11 +501,9 @@ pub fn split<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
generate_secret_shares(key, max_signers, min_signers, coefficients, identifiers)?
|
||||
}
|
||||
};
|
||||
let mut verifying_shares: HashMap<Identifier<C>, VerifyingShare<C>> =
|
||||
HashMap::with_capacity(max_signers as usize);
|
||||
let mut verifying_shares: BTreeMap<Identifier<C>, VerifyingShare<C>> = BTreeMap::new();
|
||||
|
||||
let mut secret_shares_by_id: HashMap<Identifier<C>, SecretShare<C>> =
|
||||
HashMap::with_capacity(max_signers as usize);
|
||||
let mut secret_shares_by_id: BTreeMap<Identifier<C>, SecretShare<C>> = BTreeMap::new();
|
||||
|
||||
for secret_share in secret_shares {
|
||||
let signer_public = secret_share.signing_share.into();
|
||||
|
@ -673,7 +671,7 @@ pub struct PublicKeyPackage<C: Ciphersuite> {
|
|||
pub(crate) header: Header<C>,
|
||||
/// The verifying shares for all participants. Used to validate signature
|
||||
/// shares they generate.
|
||||
pub(crate) verifying_shares: HashMap<Identifier<C>, VerifyingShare<C>>,
|
||||
pub(crate) verifying_shares: BTreeMap<Identifier<C>, VerifyingShare<C>>,
|
||||
/// The joint public key for the entire group.
|
||||
pub(crate) verifying_key: VerifyingKey<C>,
|
||||
}
|
||||
|
@ -684,7 +682,7 @@ where
|
|||
{
|
||||
/// Create a new [`PublicKeyPackage`] instance.
|
||||
pub fn new(
|
||||
verifying_shares: HashMap<Identifier<C>, VerifyingShare<C>>,
|
||||
verifying_shares: BTreeMap<Identifier<C>, VerifyingShare<C>>,
|
||||
verifying_key: VerifyingKey<C>,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
//! [Feldman's VSS]: https://www.cs.umd.edu/~gasarch/TOPICS/secretsharing/feldmanVSS.pdf
|
||||
//! [secure broadcast channel]: https://frost.zfnd.org/terminology.html#broadcast-channel
|
||||
|
||||
use std::{collections::HashMap, iter};
|
||||
use std::{collections::BTreeMap, iter};
|
||||
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
||||
|
@ -346,11 +346,11 @@ where
|
|||
/// must be sent to each participant who has the given identifier in the map key.
|
||||
pub fn part2<C: Ciphersuite>(
|
||||
secret_package: round1::SecretPackage<C>,
|
||||
round1_packages: &HashMap<Identifier<C>, round1::Package<C>>,
|
||||
round1_packages: &BTreeMap<Identifier<C>, round1::Package<C>>,
|
||||
) -> Result<
|
||||
(
|
||||
round2::SecretPackage<C>,
|
||||
HashMap<Identifier<C>, round2::Package<C>>,
|
||||
BTreeMap<Identifier<C>, round2::Package<C>>,
|
||||
),
|
||||
Error<C>,
|
||||
> {
|
||||
|
@ -358,7 +358,7 @@ pub fn part2<C: Ciphersuite>(
|
|||
return Err(Error::IncorrectNumberOfPackages);
|
||||
}
|
||||
|
||||
let mut round2_packages = HashMap::new();
|
||||
let mut round2_packages = BTreeMap::new();
|
||||
|
||||
for (sender_identifier, round1_package) in round1_packages {
|
||||
let ell = *sender_identifier;
|
||||
|
@ -407,14 +407,14 @@ pub fn part2<C: Ciphersuite>(
|
|||
/// Computes the verifying shares of the other participants for the third step
|
||||
/// of the DKG protocol.
|
||||
fn compute_verifying_shares<C: Ciphersuite>(
|
||||
round1_packages: &HashMap<Identifier<C>, round1::Package<C>>,
|
||||
round1_packages: &BTreeMap<Identifier<C>, round1::Package<C>>,
|
||||
round2_secret_package: &round2::SecretPackage<C>,
|
||||
) -> Result<HashMap<Identifier<C>, VerifyingShare<C>>, Error<C>> {
|
||||
) -> Result<BTreeMap<Identifier<C>, VerifyingShare<C>>, Error<C>> {
|
||||
// Round 2, Step 4
|
||||
//
|
||||
// > Any participant can compute the public verification share of any other participant
|
||||
// > by calculating Y_i = ∏_{j=1}^n ∏_{k=0}^{t−1} φ_{jk}^{i^k mod q}.
|
||||
let mut others_verifying_shares = HashMap::new();
|
||||
let mut others_verifying_shares = BTreeMap::new();
|
||||
|
||||
// Note that in this loop, "i" refers to the other participant whose public verification share
|
||||
// we are computing, and not the current participant.
|
||||
|
@ -464,8 +464,8 @@ fn compute_verifying_shares<C: Ciphersuite>(
|
|||
/// signatures.
|
||||
pub fn part3<C: Ciphersuite>(
|
||||
round2_secret_package: &round2::SecretPackage<C>,
|
||||
round1_packages: &HashMap<Identifier<C>, round1::Package<C>>,
|
||||
round2_packages: &HashMap<Identifier<C>, round2::Package<C>>,
|
||||
round1_packages: &BTreeMap<Identifier<C>, round1::Package<C>>,
|
||||
round2_packages: &BTreeMap<Identifier<C>, round2::Package<C>>,
|
||||
) -> Result<(KeyPackage<C>, PublicKeyPackage<C>), Error<C>> {
|
||||
if round1_packages.len() != (round2_secret_package.max_signers - 1) as usize {
|
||||
return Err(Error::IncorrectNumberOfPackages);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
|
||||
//! using a subset of the other signers know here as `helpers`.
|
||||
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use crate::{
|
||||
frost::{compute_lagrange_coefficient, Identifier},
|
||||
|
@ -19,13 +19,13 @@ use super::{generate_coefficients, SecretShare, SigningShare, VerifiableSecretSh
|
|||
/// where `helpers` contains the identifiers of all the helpers (including `helper_i`), and `share_i`
|
||||
/// is the share of `helper_i`.
|
||||
///
|
||||
/// Returns a HashMap mapping which value should be sent to which participant.
|
||||
/// Returns a BTreeMap mapping which value should be sent to which participant.
|
||||
pub fn repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
helpers: &[Identifier<C>],
|
||||
share_i: &SecretShare<C>,
|
||||
rng: &mut R,
|
||||
participant: Identifier<C>,
|
||||
) -> Result<HashMap<Identifier<C>, Scalar<C>>, Error<C>> {
|
||||
) -> Result<BTreeMap<Identifier<C>, Scalar<C>>, Error<C>> {
|
||||
if helpers.len() < 2 {
|
||||
return Err(Error::InvalidMinSigners);
|
||||
}
|
||||
|
@ -46,19 +46,19 @@ pub fn repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
/// Compute the last delta value given the (generated uniformly at random) remaining ones
|
||||
/// since they all must add up to `zeta_i * share_i`.
|
||||
///
|
||||
/// Returns a HashMap mapping which value should be sent to which participant.
|
||||
/// Returns a BTreeMap mapping which value should be sent to which participant.
|
||||
fn compute_last_random_value<C: Ciphersuite>(
|
||||
helpers: &BTreeSet<Identifier<C>>,
|
||||
share_i: &SecretShare<C>,
|
||||
random_values: &Vec<Scalar<C>>,
|
||||
participant: Identifier<C>,
|
||||
) -> Result<HashMap<Identifier<C>, Scalar<C>>, Error<C>> {
|
||||
) -> Result<BTreeMap<Identifier<C>, Scalar<C>>, Error<C>> {
|
||||
// Calculate Lagrange Coefficient for helper_i
|
||||
let zeta_i = compute_lagrange_coefficient(helpers, Some(participant), share_i.identifier)?;
|
||||
|
||||
let lhs = zeta_i * share_i.signing_share.0;
|
||||
|
||||
let mut out: HashMap<Identifier<C>, Scalar<C>> = helpers
|
||||
let mut out: BTreeMap<Identifier<C>, Scalar<C>> = helpers
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(random_values.iter().copied())
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
//! Ciphersuite-generic test functions.
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
convert::TryFrom,
|
||||
};
|
||||
use std::{collections::BTreeMap, convert::TryFrom};
|
||||
|
||||
use crate::{
|
||||
frost::{self, Identifier},
|
||||
|
@ -119,8 +116,8 @@ pub fn check_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
HashMap::new();
|
||||
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
for (k, v) in shares {
|
||||
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
|
||||
|
@ -192,12 +189,12 @@ pub fn check_dkg_part1_fails_with_invalid_signers<C: Ciphersuite, R: RngCore + C
|
|||
/// Test FROST signing with the given shares.
|
||||
pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
|
||||
min_signers: u16,
|
||||
key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>>,
|
||||
key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>>,
|
||||
mut rng: R,
|
||||
pubkey_package: frost::keys::PublicKeyPackage<C>,
|
||||
) -> Result<(Vec<u8>, Signature<C>, VerifyingKey<C>), Error<C>> {
|
||||
let mut nonces_map: HashMap<frost::Identifier<C>, frost::round1::SigningNonces<C>> =
|
||||
HashMap::new();
|
||||
let mut nonces_map: BTreeMap<frost::Identifier<C>, frost::round1::SigningNonces<C>> =
|
||||
BTreeMap::new();
|
||||
let mut commitments_map: BTreeMap<frost::Identifier<C>, frost::round1::SigningCommitments<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
|
@ -222,7 +219,7 @@ pub fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
|
|||
// This is what the signature aggregator / coordinator needs to do:
|
||||
// - decide what message to sign
|
||||
// - take one (unused) commitment per signing participant
|
||||
let mut signature_shares = HashMap::new();
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
let message = "message to sign".as_bytes();
|
||||
let signing_package = frost::SigningPackage::new(commitments_map, message);
|
||||
|
||||
|
@ -305,7 +302,7 @@ fn check_sign_errors<C: Ciphersuite + PartialEq>(
|
|||
|
||||
fn check_aggregate_errors<C: Ciphersuite + PartialEq>(
|
||||
signing_package: frost::SigningPackage<C>,
|
||||
signature_shares: HashMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
signature_shares: BTreeMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
pubkey_package: frost::keys::PublicKeyPackage<C>,
|
||||
) {
|
||||
check_aggregate_corrupted_share(
|
||||
|
@ -322,7 +319,7 @@ fn check_aggregate_errors<C: Ciphersuite + PartialEq>(
|
|||
|
||||
fn check_aggregate_corrupted_share<C: Ciphersuite + PartialEq>(
|
||||
signing_package: frost::SigningPackage<C>,
|
||||
mut signature_shares: HashMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
mut signature_shares: BTreeMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
pubkey_package: frost::keys::PublicKeyPackage<C>,
|
||||
) {
|
||||
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
|
||||
|
@ -340,7 +337,7 @@ fn check_aggregate_corrupted_share<C: Ciphersuite + PartialEq>(
|
|||
/// part can't either since it's caught before by the PublicKeyPackage part.
|
||||
fn check_aggregate_invalid_share_identifier_for_verifying_shares<C: Ciphersuite + PartialEq>(
|
||||
signing_package: frost::SigningPackage<C>,
|
||||
mut signature_shares: HashMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
mut signature_shares: BTreeMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
pubkey_package: frost::keys::PublicKeyPackage<C>,
|
||||
) {
|
||||
let invalid_identifier = Identifier::derive("invalid identifier".as_bytes()).unwrap();
|
||||
|
@ -371,18 +368,18 @@ where
|
|||
// Keep track of each participant's round 1 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round1_secret_packages: HashMap<
|
||||
let mut round1_secret_packages: BTreeMap<
|
||||
frost::Identifier<C>,
|
||||
frost::keys::dkg::round1::SecretPackage<C>,
|
||||
> = HashMap::new();
|
||||
> = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 1 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round1_packages: HashMap<
|
||||
let mut received_round1_packages: BTreeMap<
|
||||
frost::Identifier<C>,
|
||||
HashMap<frost::Identifier<C>, frost::keys::dkg::round1::Package<C>>,
|
||||
> = HashMap::new();
|
||||
BTreeMap<frost::Identifier<C>, frost::keys::dkg::round1::Package<C>>,
|
||||
> = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the first part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -397,7 +394,7 @@ where
|
|||
round1_secret_packages.insert(participant_identifier, round1_secret_package);
|
||||
|
||||
// "Send" the round 1 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
for receiver_participant_index in 1..=max_signers {
|
||||
if receiver_participant_index == participant_index {
|
||||
|
@ -408,7 +405,7 @@ where
|
|||
.expect("should be nonzero");
|
||||
received_round1_packages
|
||||
.entry(receiver_participant_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round1_package.clone());
|
||||
}
|
||||
}
|
||||
|
@ -420,12 +417,12 @@ where
|
|||
// Keep track of each participant's round 2 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round2_secret_packages = HashMap::new();
|
||||
let mut round2_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 2 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round2_packages = HashMap::new();
|
||||
let mut received_round2_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the second part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -444,14 +441,14 @@ where
|
|||
round2_secret_packages.insert(participant_identifier, round2_secret_package);
|
||||
|
||||
// "Send" the round 2 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
// 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 {
|
||||
received_round2_packages
|
||||
.entry(receiver_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round2_package);
|
||||
}
|
||||
}
|
||||
|
@ -463,11 +460,11 @@ where
|
|||
// Keep track of each participant's long-lived key package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut key_packages = HashMap::new();
|
||||
let mut key_packages = BTreeMap::new();
|
||||
|
||||
// Map of the verifying key of each participant.
|
||||
// Used by the signing test that follows.
|
||||
let mut verifying_keys = HashMap::new();
|
||||
let mut verifying_keys = BTreeMap::new();
|
||||
// The group public key, used by the signing test that follows.
|
||||
let mut verifying_key = None;
|
||||
// For each participant, store the set of verifying keys they have computed.
|
||||
|
@ -476,7 +473,7 @@ where
|
|||
// If there is not, then all candidates must store their own sets.
|
||||
// The verifying keys are used to verify the signature shares produced
|
||||
// for each signature before being aggregated.
|
||||
let mut pubkey_packages_by_participant = HashMap::new();
|
||||
let mut pubkey_packages_by_participant = BTreeMap::new();
|
||||
|
||||
check_part3_different_participants(
|
||||
max_signers,
|
||||
|
@ -520,14 +517,14 @@ where
|
|||
/// Check that calling dkg::part3() with distinct sets of participants fail.
|
||||
fn check_part3_different_participants<C: Ciphersuite>(
|
||||
max_signers: u16,
|
||||
round2_secret_packages: HashMap<Identifier<C>, frost::keys::dkg::round2::SecretPackage<C>>,
|
||||
received_round1_packages: HashMap<
|
||||
round2_secret_packages: BTreeMap<Identifier<C>, frost::keys::dkg::round2::SecretPackage<C>>,
|
||||
received_round1_packages: BTreeMap<
|
||||
Identifier<C>,
|
||||
HashMap<Identifier<C>, frost::keys::dkg::round1::Package<C>>,
|
||||
BTreeMap<Identifier<C>, frost::keys::dkg::round1::Package<C>>,
|
||||
>,
|
||||
received_round2_packages: HashMap<
|
||||
received_round2_packages: BTreeMap<
|
||||
Identifier<C>,
|
||||
HashMap<Identifier<C>, frost::keys::dkg::round2::Package<C>>,
|
||||
BTreeMap<Identifier<C>, frost::keys::dkg::round2::Package<C>>,
|
||||
>,
|
||||
) {
|
||||
// For each participant, perform the third part of the DKG protocol.
|
||||
|
@ -618,8 +615,8 @@ pub fn check_sign_with_dealer_and_identifiers<C: Ciphersuite, R: RngCore + Crypt
|
|||
|
||||
// Do regular testing to make sure it works
|
||||
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
HashMap::new();
|
||||
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
BTreeMap::new();
|
||||
for (k, v) in shares {
|
||||
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
|
||||
key_packages.insert(k, key_package);
|
||||
|
@ -629,7 +626,7 @@ pub fn check_sign_with_dealer_and_identifiers<C: Ciphersuite, R: RngCore + Crypt
|
|||
|
||||
fn check_part2_error<C: Ciphersuite>(
|
||||
round1_secret_package: frost::keys::dkg::round1::SecretPackage<C>,
|
||||
mut round1_packages: HashMap<frost::Identifier<C>, frost::keys::dkg::round1::Package<C>>,
|
||||
mut round1_packages: BTreeMap<frost::Identifier<C>, frost::keys::dkg::round1::Package<C>>,
|
||||
) {
|
||||
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
|
||||
// Corrupt a PoK
|
||||
|
@ -686,16 +683,16 @@ pub fn check_sign_with_missing_identifier<C: Ciphersuite, R: RngCore + CryptoRng
|
|||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
HashMap::new();
|
||||
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
for (k, v) in shares {
|
||||
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
|
||||
key_packages.insert(k, key_package);
|
||||
}
|
||||
|
||||
let mut nonces_map: HashMap<frost::Identifier<C>, frost::round1::SigningNonces<C>> =
|
||||
HashMap::new();
|
||||
let mut nonces_map: BTreeMap<frost::Identifier<C>, frost::round1::SigningNonces<C>> =
|
||||
BTreeMap::new();
|
||||
let mut commitments_map: BTreeMap<frost::Identifier<C>, frost::round1::SigningCommitments<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
|
@ -767,8 +764,8 @@ pub fn check_sign_with_incorrect_commitments<C: Ciphersuite, R: RngCore + Crypto
|
|||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
HashMap::new();
|
||||
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
for (k, v) in shares {
|
||||
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Test for Repairable Threshold Scheme
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use debugless_unwrap::DebuglessUnwrap;
|
||||
use rand_core::{CryptoRng, RngCore};
|
||||
|
@ -28,7 +28,7 @@ pub fn check_rts<C: Ciphersuite, R: RngCore + CryptoRng>(mut rng: R) {
|
|||
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, _pubkeys): (HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
let (shares, _pubkeys): (BTreeMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
|
@ -106,7 +106,7 @@ pub fn check_repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(mut rng
|
|||
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, _pubkeys): (HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
let (shares, _pubkeys): (BTreeMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
|
@ -176,7 +176,7 @@ pub fn check_repair_share_step_3<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
// Generate shares
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, _pubkeys): (HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
let (shares, _pubkeys): (BTreeMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
|
@ -221,7 +221,7 @@ pub fn check_repair_share_step_1_fails_with_invalid_min_signers<
|
|||
// Generate shares
|
||||
let max_signers = 3;
|
||||
let min_signers = 2; // This is to make sure this test fails at the right point
|
||||
let (shares, _pubkeys): (HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
let (shares, _pubkeys): (BTreeMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//! Helper function for testing with test vectors.
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use debugless_unwrap::DebuglessUnwrap;
|
||||
use hex::{self, FromHex};
|
||||
|
@ -14,16 +14,16 @@ use crate::{
|
|||
pub struct TestVectors<C: Ciphersuite> {
|
||||
secret_key: SigningKey<C>,
|
||||
verifying_key: VerifyingKey<C>,
|
||||
key_packages: HashMap<Identifier<C>, KeyPackage<C>>,
|
||||
key_packages: BTreeMap<Identifier<C>, KeyPackage<C>>,
|
||||
message_bytes: Vec<u8>,
|
||||
share_polynomial_coefficients: Vec<Scalar<C>>,
|
||||
hiding_nonces_randomness: HashMap<Identifier<C>, Vec<u8>>,
|
||||
binding_nonces_randomness: HashMap<Identifier<C>, Vec<u8>>,
|
||||
signer_nonces: HashMap<Identifier<C>, SigningNonces<C>>,
|
||||
hiding_nonces_randomness: BTreeMap<Identifier<C>, Vec<u8>>,
|
||||
binding_nonces_randomness: BTreeMap<Identifier<C>, Vec<u8>>,
|
||||
signer_nonces: BTreeMap<Identifier<C>, SigningNonces<C>>,
|
||||
signer_commitments: BTreeMap<Identifier<C>, SigningCommitments<C>>,
|
||||
binding_factor_inputs: HashMap<Identifier<C>, Vec<u8>>,
|
||||
binding_factors: HashMap<Identifier<C>, BindingFactor<C>>,
|
||||
signature_shares: HashMap<Identifier<C>, SignatureShare<C>>,
|
||||
binding_factor_inputs: BTreeMap<Identifier<C>, Vec<u8>>,
|
||||
binding_factors: BTreeMap<Identifier<C>, BindingFactor<C>>,
|
||||
signature_shares: BTreeMap<Identifier<C>, SignatureShare<C>>,
|
||||
signature_bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ pub fn parse_test_vectors<C: Ciphersuite>(json_vectors: &Value) -> TestVectors<C
|
|||
})
|
||||
.collect();
|
||||
|
||||
let mut key_packages: HashMap<Identifier<C>, KeyPackage<C>> = HashMap::new();
|
||||
let mut key_packages: BTreeMap<Identifier<C>, KeyPackage<C>> = BTreeMap::new();
|
||||
|
||||
let possible_participants = json_vectors["inputs"].as_object().unwrap()["participant_shares"]
|
||||
.as_array()
|
||||
|
@ -83,12 +83,12 @@ pub fn parse_test_vectors<C: Ciphersuite>(json_vectors: &Value) -> TestVectors<C
|
|||
|
||||
let round_one_outputs = &json_vectors["round_one_outputs"];
|
||||
|
||||
let mut hiding_nonces_randomness: HashMap<Identifier<C>, Vec<u8>> = HashMap::new();
|
||||
let mut binding_nonces_randomness: HashMap<Identifier<C>, Vec<u8>> = HashMap::new();
|
||||
let mut signer_nonces: HashMap<Identifier<C>, SigningNonces<C>> = HashMap::new();
|
||||
let mut hiding_nonces_randomness: BTreeMap<Identifier<C>, Vec<u8>> = BTreeMap::new();
|
||||
let mut binding_nonces_randomness: BTreeMap<Identifier<C>, Vec<u8>> = BTreeMap::new();
|
||||
let mut signer_nonces: BTreeMap<Identifier<C>, SigningNonces<C>> = BTreeMap::new();
|
||||
let mut signer_commitments: BTreeMap<Identifier<C>, SigningCommitments<C>> = BTreeMap::new();
|
||||
let mut binding_factor_inputs: HashMap<Identifier<C>, Vec<u8>> = HashMap::new();
|
||||
let mut binding_factors: HashMap<Identifier<C>, BindingFactor<C>> = HashMap::new();
|
||||
let mut binding_factor_inputs: BTreeMap<Identifier<C>, Vec<u8>> = BTreeMap::new();
|
||||
let mut binding_factors: BTreeMap<Identifier<C>, BindingFactor<C>> = BTreeMap::new();
|
||||
|
||||
for signer in round_one_outputs["outputs"].as_array().unwrap().iter() {
|
||||
let i = signer["identifier"].as_u64().unwrap() as u16;
|
||||
|
@ -132,7 +132,7 @@ pub fn parse_test_vectors<C: Ciphersuite>(json_vectors: &Value) -> TestVectors<C
|
|||
|
||||
let round_two_outputs = &json_vectors["round_two_outputs"];
|
||||
|
||||
let mut signature_shares: HashMap<Identifier<C>, SignatureShare<C>> = HashMap::new();
|
||||
let mut signature_shares: BTreeMap<Identifier<C>, SignatureShare<C>> = BTreeMap::new();
|
||||
|
||||
for signer in round_two_outputs["outputs"].as_array().unwrap().iter() {
|
||||
let i = signer["identifier"].as_u64().unwrap() as u16;
|
||||
|
@ -201,7 +201,7 @@ pub fn check_sign_with_test_vectors<C: Ciphersuite>(json_vectors: &Value) {
|
|||
&default_identifiers(max_signers as u16),
|
||||
)
|
||||
.unwrap();
|
||||
let secret_shares: HashMap<_, _> = secret_shares
|
||||
let secret_shares: BTreeMap<_, _> = secret_shares
|
||||
.iter()
|
||||
.map(|share| (share.identifier, share))
|
||||
.collect();
|
||||
|
@ -275,7 +275,7 @@ pub fn check_sign_with_test_vectors<C: Ciphersuite>(json_vectors: &Value) {
|
|||
assert_eq!(*binding_factor, binding_factors[identifier]);
|
||||
}
|
||||
|
||||
let mut our_signature_shares = HashMap::new();
|
||||
let mut our_signature_shares = BTreeMap::new();
|
||||
|
||||
// Each participant generates their signature share
|
||||
for identifier in signer_nonces.keys() {
|
||||
|
|
|
@ -12,7 +12,7 @@ scenario in a single thread and it abstracts away any communication between peer
|
|||
# // ANCHOR: tkg_gen
|
||||
use frost_ed25519 as frost;
|
||||
use rand::thread_rng;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
|
@ -25,10 +25,10 @@ let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
|||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
// Verifies the secret shares from the dealer and store them in a BTreeMap.
|
||||
// In practice, the KeyPackages must be sent to its respective participants
|
||||
// through a confidential and authenticated channel.
|
||||
let mut key_packages: HashMap<_, _> = HashMap::new();
|
||||
let mut key_packages: BTreeMap<_, _> = BTreeMap::new();
|
||||
|
||||
for (identifier, secret_share) in shares {
|
||||
# // ANCHOR: tkg_verify
|
||||
|
@ -37,7 +37,7 @@ for (identifier, secret_share) in shares {
|
|||
key_packages.insert(identifier, key_package);
|
||||
}
|
||||
|
||||
let mut nonces_map = HashMap::new();
|
||||
let mut nonces_map = BTreeMap::new();
|
||||
let mut commitments_map = BTreeMap::new();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,7 @@ for participant_index in 1..(min_signers as u16 + 1) {
|
|||
// This is what the signature aggregator / coordinator needs to do:
|
||||
// - decide what message to sign
|
||||
// - take one (unused) commitment per signing participant
|
||||
let mut signature_shares = HashMap::new();
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
# // ANCHOR: round2_package
|
||||
let message = "message to sign".as_bytes();
|
||||
# // In practice, the SigningPackage must be sent to all participants
|
||||
|
|
|
@ -27,7 +27,7 @@ they can proceed to sign messages with FROST.
|
|||
```rust
|
||||
# // ANCHOR: dkg_import
|
||||
use rand::thread_rng;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_ed25519 as frost;
|
||||
|
||||
|
@ -44,12 +44,12 @@ let min_signers = 3;
|
|||
// Keep track of each participant's round 1 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round1_secret_packages = HashMap::new();
|
||||
let mut round1_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 1 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round1_packages = HashMap::new();
|
||||
let mut received_round1_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the first part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -69,7 +69,7 @@ for participant_index in 1..=max_signers {
|
|||
round1_secret_packages.insert(participant_identifier, round1_secret_package);
|
||||
|
||||
// "Send" the round 1 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
for receiver_participant_index in 1..=max_signers {
|
||||
if receiver_participant_index == participant_index {
|
||||
|
@ -80,7 +80,7 @@ for participant_index in 1..=max_signers {
|
|||
.expect("should be nonzero");
|
||||
received_round1_packages
|
||||
.entry(receiver_participant_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round1_package.clone());
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's round 2 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round2_secret_packages = HashMap::new();
|
||||
let mut round2_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 2 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round2_packages = HashMap::new();
|
||||
let mut received_round2_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the second part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -117,14 +117,14 @@ for participant_index in 1..=max_signers {
|
|||
round2_secret_packages.insert(participant_identifier, round2_secret_package);
|
||||
|
||||
// "Send" the round 2 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
// 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 {
|
||||
received_round2_packages
|
||||
.entry(receiver_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round2_package);
|
||||
}
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's long-lived key package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut key_packages = HashMap::new();
|
||||
let mut key_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of each participant's public key package.
|
||||
// In practice, if there is a Coordinator, only they need to store the set.
|
||||
// If there is not, then all candidates must store their own sets.
|
||||
// All participants will have the same exact public key package.
|
||||
let mut pubkey_packages = HashMap::new();
|
||||
let mut pubkey_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the third part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
|
|
@ -64,8 +64,8 @@ pub fn part1<R: RngCore + CryptoRng>(
|
|||
/// must be sent to other participants.
|
||||
pub fn part2(
|
||||
secret_package: round1::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, HashMap<Identifier, round2::Package>), Error> {
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, BTreeMap<Identifier, round2::Package>), Error> {
|
||||
frost::keys::dkg::part2(secret_package, round1_packages)
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,8 @@ pub fn part2(
|
|||
/// signatures.
|
||||
pub fn part3(
|
||||
round2_secret_package: &round2::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
round2_packages: &HashMap<Identifier, round2::Package>,
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
round2_packages: &BTreeMap<Identifier, round2::Package>,
|
||||
) -> Result<(KeyPackage, PublicKeyPackage), Error> {
|
||||
frost::keys::dkg::part3(round2_secret_package, round1_packages, round2_packages)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
|
||||
//! using a subset of the other signers know here as `helpers`.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// This is imported separately to make `gencode` work.
|
||||
// (if it were below, the position of the import would vary between ciphersuites
|
||||
|
@ -20,13 +20,13 @@ use super::{SecretShare, VerifiableSecretSharingCommitment};
|
|||
/// where `helpers` contains the identifiers of all the helpers (including `helper_i`), and `share_i`
|
||||
/// is the share of `helper_i`.
|
||||
///
|
||||
/// Returns a HashMap mapping which value should be sent to which participant.
|
||||
/// Returns a BTreeMap mapping which value should be sent to which participant.
|
||||
pub fn repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
helpers: &[Identifier],
|
||||
share_i: &SecretShare,
|
||||
rng: &mut R,
|
||||
participant: Identifier,
|
||||
) -> Result<HashMap<Identifier, Scalar>, Error> {
|
||||
) -> Result<BTreeMap<Identifier, Scalar>, Error> {
|
||||
frost::keys::repairable::repair_share_step_1(helpers, share_i, rng, participant)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![doc = document_features::document_features!()]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use curve25519_dalek::{
|
||||
constants::ED25519_BASEPOINT_POINT,
|
||||
|
@ -216,7 +216,7 @@ pub type Identifier = frost::Identifier<E>;
|
|||
|
||||
/// FROST(Ed25519, SHA-512) keys, key generation, key shares.
|
||||
pub mod keys {
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -230,7 +230,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
|
@ -395,7 +395,7 @@ pub type Signature = frost_core::Signature<E>;
|
|||
/// service attack due to publishing an invalid signature.
|
||||
pub fn aggregate(
|
||||
signing_package: &SigningPackage,
|
||||
signature_shares: &HashMap<Identifier, round2::SignatureShare>,
|
||||
signature_shares: &BTreeMap<Identifier, round2::SignatureShare>,
|
||||
pubkeys: &keys::PublicKeyPackage,
|
||||
) -> Result<Signature, Error> {
|
||||
frost::aggregate(signing_package, signature_shares, pubkeys)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Generate sample, fixed instances of structs for testing.
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_core::{Ciphersuite, Element, Group, Scalar};
|
||||
use frost_ed25519::{
|
||||
|
@ -90,7 +90,7 @@ pub fn public_key_package() -> PublicKeyPackage {
|
|||
let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap();
|
||||
let serialized_element = <C as Ciphersuite>::Group::serialize(&element1());
|
||||
let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap();
|
||||
let verifying_shares = HashMap::from([(identifier, verifying_share)]);
|
||||
let verifying_shares = BTreeMap::from([(identifier, verifying_share)]);
|
||||
|
||||
PublicKeyPackage::new(verifying_shares, verifying_key)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ scenario in a single thread and it abstracts away any communication between peer
|
|||
# // ANCHOR: tkg_gen
|
||||
use frost_ed448 as frost;
|
||||
use rand::thread_rng;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
|
@ -25,10 +25,10 @@ let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
|||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
// Verifies the secret shares from the dealer and store them in a BTreeMap.
|
||||
// In practice, the KeyPackages must be sent to its respective participants
|
||||
// through a confidential and authenticated channel.
|
||||
let mut key_packages: HashMap<_, _> = HashMap::new();
|
||||
let mut key_packages: BTreeMap<_, _> = BTreeMap::new();
|
||||
|
||||
for (identifier, secret_share) in shares {
|
||||
# // ANCHOR: tkg_verify
|
||||
|
@ -37,7 +37,7 @@ for (identifier, secret_share) in shares {
|
|||
key_packages.insert(identifier, key_package);
|
||||
}
|
||||
|
||||
let mut nonces_map = HashMap::new();
|
||||
let mut nonces_map = BTreeMap::new();
|
||||
let mut commitments_map = BTreeMap::new();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,7 @@ for participant_index in 1..(min_signers as u16 + 1) {
|
|||
// This is what the signature aggregator / coordinator needs to do:
|
||||
// - decide what message to sign
|
||||
// - take one (unused) commitment per signing participant
|
||||
let mut signature_shares = HashMap::new();
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
# // ANCHOR: round2_package
|
||||
let message = "message to sign".as_bytes();
|
||||
# // In practice, the SigningPackage must be sent to all participants
|
||||
|
|
|
@ -27,7 +27,7 @@ they can proceed to sign messages with FROST.
|
|||
```rust
|
||||
# // ANCHOR: dkg_import
|
||||
use rand::thread_rng;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_ed448 as frost;
|
||||
|
||||
|
@ -44,12 +44,12 @@ let min_signers = 3;
|
|||
// Keep track of each participant's round 1 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round1_secret_packages = HashMap::new();
|
||||
let mut round1_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 1 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round1_packages = HashMap::new();
|
||||
let mut received_round1_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the first part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -69,7 +69,7 @@ for participant_index in 1..=max_signers {
|
|||
round1_secret_packages.insert(participant_identifier, round1_secret_package);
|
||||
|
||||
// "Send" the round 1 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
for receiver_participant_index in 1..=max_signers {
|
||||
if receiver_participant_index == participant_index {
|
||||
|
@ -80,7 +80,7 @@ for participant_index in 1..=max_signers {
|
|||
.expect("should be nonzero");
|
||||
received_round1_packages
|
||||
.entry(receiver_participant_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round1_package.clone());
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's round 2 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round2_secret_packages = HashMap::new();
|
||||
let mut round2_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 2 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round2_packages = HashMap::new();
|
||||
let mut received_round2_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the second part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -117,14 +117,14 @@ for participant_index in 1..=max_signers {
|
|||
round2_secret_packages.insert(participant_identifier, round2_secret_package);
|
||||
|
||||
// "Send" the round 2 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
// 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 {
|
||||
received_round2_packages
|
||||
.entry(receiver_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round2_package);
|
||||
}
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's long-lived key package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut key_packages = HashMap::new();
|
||||
let mut key_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of each participant's public key package.
|
||||
// In practice, if there is a Coordinator, only they need to store the set.
|
||||
// If there is not, then all candidates must store their own sets.
|
||||
// All participants will have the same exact public key package.
|
||||
let mut pubkey_packages = HashMap::new();
|
||||
let mut pubkey_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the third part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
|
|
@ -64,8 +64,8 @@ pub fn part1<R: RngCore + CryptoRng>(
|
|||
/// must be sent to other participants.
|
||||
pub fn part2(
|
||||
secret_package: round1::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, HashMap<Identifier, round2::Package>), Error> {
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, BTreeMap<Identifier, round2::Package>), Error> {
|
||||
frost::keys::dkg::part2(secret_package, round1_packages)
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,8 @@ pub fn part2(
|
|||
/// signatures.
|
||||
pub fn part3(
|
||||
round2_secret_package: &round2::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
round2_packages: &HashMap<Identifier, round2::Package>,
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
round2_packages: &BTreeMap<Identifier, round2::Package>,
|
||||
) -> Result<(KeyPackage, PublicKeyPackage), Error> {
|
||||
frost::keys::dkg::part3(round2_secret_package, round1_packages, round2_packages)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
|
||||
//! using a subset of the other signers know here as `helpers`.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// This is imported separately to make `gencode` work.
|
||||
// (if it were below, the position of the import would vary between ciphersuites
|
||||
|
@ -20,13 +20,13 @@ use super::{SecretShare, VerifiableSecretSharingCommitment};
|
|||
/// where `helpers` contains the identifiers of all the helpers (including `helper_i`), and `share_i`
|
||||
/// is the share of `helper_i`.
|
||||
///
|
||||
/// Returns a HashMap mapping which value should be sent to which participant.
|
||||
/// Returns a BTreeMap mapping which value should be sent to which participant.
|
||||
pub fn repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
helpers: &[Identifier],
|
||||
share_i: &SecretShare,
|
||||
rng: &mut R,
|
||||
participant: Identifier,
|
||||
) -> Result<HashMap<Identifier, Scalar>, Error> {
|
||||
) -> Result<BTreeMap<Identifier, Scalar>, Error> {
|
||||
frost::keys::repairable::repair_share_step_1(helpers, share_i, rng, participant)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![doc = document_features::document_features!()]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ed448_goldilocks::{
|
||||
curve::{edwards::CompressedEdwardsY, ExtendedPoint},
|
||||
|
@ -212,7 +212,7 @@ pub type Identifier = frost::Identifier<E>;
|
|||
/// FROST(Ed448, SHAKE256) keys, key generation, key shares.
|
||||
pub mod keys {
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, E>;
|
||||
|
@ -224,7 +224,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
|
@ -389,7 +389,7 @@ pub type Signature = frost_core::Signature<E>;
|
|||
/// service attack due to publishing an invalid signature.
|
||||
pub fn aggregate(
|
||||
signing_package: &SigningPackage,
|
||||
signature_shares: &HashMap<Identifier, round2::SignatureShare>,
|
||||
signature_shares: &BTreeMap<Identifier, round2::SignatureShare>,
|
||||
pubkeys: &keys::PublicKeyPackage,
|
||||
) -> Result<Signature, Error> {
|
||||
frost::aggregate(signing_package, signature_shares, pubkeys)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Generate sample, fixed instances of structs for testing.
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_core::{Ciphersuite, Element, Group, Scalar};
|
||||
use frost_ed448::{
|
||||
|
@ -90,7 +90,7 @@ pub fn public_key_package() -> PublicKeyPackage {
|
|||
let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap();
|
||||
let serialized_element = <C as Ciphersuite>::Group::serialize(&element1());
|
||||
let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap();
|
||||
let verifying_shares = HashMap::from([(identifier, verifying_share)]);
|
||||
let verifying_shares = BTreeMap::from([(identifier, verifying_share)]);
|
||||
|
||||
PublicKeyPackage::new(verifying_shares, verifying_key)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ scenario in a single thread and it abstracts away any communication between peer
|
|||
# // ANCHOR: tkg_gen
|
||||
use frost_p256 as frost;
|
||||
use rand::thread_rng;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
|
@ -25,10 +25,10 @@ let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
|||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
// Verifies the secret shares from the dealer and store them in a BTreeMap.
|
||||
// In practice, the KeyPackages must be sent to its respective participants
|
||||
// through a confidential and authenticated channel.
|
||||
let mut key_packages: HashMap<_, _> = HashMap::new();
|
||||
let mut key_packages: BTreeMap<_, _> = BTreeMap::new();
|
||||
|
||||
for (identifier, secret_share) in shares {
|
||||
# // ANCHOR: tkg_verify
|
||||
|
@ -37,7 +37,7 @@ for (identifier, secret_share) in shares {
|
|||
key_packages.insert(identifier, key_package);
|
||||
}
|
||||
|
||||
let mut nonces_map = HashMap::new();
|
||||
let mut nonces_map = BTreeMap::new();
|
||||
let mut commitments_map = BTreeMap::new();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,7 @@ for participant_index in 1..(min_signers as u16 + 1) {
|
|||
// This is what the signature aggregator / coordinator needs to do:
|
||||
// - decide what message to sign
|
||||
// - take one (unused) commitment per signing participant
|
||||
let mut signature_shares = HashMap::new();
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
# // ANCHOR: round2_package
|
||||
let message = "message to sign".as_bytes();
|
||||
# // In practice, the SigningPackage must be sent to all participants
|
||||
|
|
|
@ -27,7 +27,7 @@ they can proceed to sign messages with FROST.
|
|||
```rust
|
||||
# // ANCHOR: dkg_import
|
||||
use rand::thread_rng;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_p256 as frost;
|
||||
|
||||
|
@ -44,12 +44,12 @@ let min_signers = 3;
|
|||
// Keep track of each participant's round 1 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round1_secret_packages = HashMap::new();
|
||||
let mut round1_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 1 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round1_packages = HashMap::new();
|
||||
let mut received_round1_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the first part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -69,7 +69,7 @@ for participant_index in 1..=max_signers {
|
|||
round1_secret_packages.insert(participant_identifier, round1_secret_package);
|
||||
|
||||
// "Send" the round 1 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
for receiver_participant_index in 1..=max_signers {
|
||||
if receiver_participant_index == participant_index {
|
||||
|
@ -80,7 +80,7 @@ for participant_index in 1..=max_signers {
|
|||
.expect("should be nonzero");
|
||||
received_round1_packages
|
||||
.entry(receiver_participant_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round1_package.clone());
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's round 2 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round2_secret_packages = HashMap::new();
|
||||
let mut round2_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 2 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round2_packages = HashMap::new();
|
||||
let mut received_round2_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the second part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -117,14 +117,14 @@ for participant_index in 1..=max_signers {
|
|||
round2_secret_packages.insert(participant_identifier, round2_secret_package);
|
||||
|
||||
// "Send" the round 2 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
// 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 {
|
||||
received_round2_packages
|
||||
.entry(receiver_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round2_package);
|
||||
}
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's long-lived key package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut key_packages = HashMap::new();
|
||||
let mut key_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of each participant's public key package.
|
||||
// In practice, if there is a Coordinator, only they need to store the set.
|
||||
// If there is not, then all candidates must store their own sets.
|
||||
// All participants will have the same exact public key package.
|
||||
let mut pubkey_packages = HashMap::new();
|
||||
let mut pubkey_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the third part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
|
|
@ -64,8 +64,8 @@ pub fn part1<R: RngCore + CryptoRng>(
|
|||
/// must be sent to other participants.
|
||||
pub fn part2(
|
||||
secret_package: round1::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, HashMap<Identifier, round2::Package>), Error> {
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, BTreeMap<Identifier, round2::Package>), Error> {
|
||||
frost::keys::dkg::part2(secret_package, round1_packages)
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,8 @@ pub fn part2(
|
|||
/// signatures.
|
||||
pub fn part3(
|
||||
round2_secret_package: &round2::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
round2_packages: &HashMap<Identifier, round2::Package>,
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
round2_packages: &BTreeMap<Identifier, round2::Package>,
|
||||
) -> Result<(KeyPackage, PublicKeyPackage), Error> {
|
||||
frost::keys::dkg::part3(round2_secret_package, round1_packages, round2_packages)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
|
||||
//! using a subset of the other signers know here as `helpers`.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// This is imported separately to make `gencode` work.
|
||||
// (if it were below, the position of the import would vary between ciphersuites
|
||||
|
@ -20,13 +20,13 @@ use super::{SecretShare, VerifiableSecretSharingCommitment};
|
|||
/// where `helpers` contains the identifiers of all the helpers (including `helper_i`), and `share_i`
|
||||
/// is the share of `helper_i`.
|
||||
///
|
||||
/// Returns a HashMap mapping which value should be sent to which participant.
|
||||
/// Returns a BTreeMap mapping which value should be sent to which participant.
|
||||
pub fn repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
helpers: &[Identifier],
|
||||
share_i: &SecretShare,
|
||||
rng: &mut R,
|
||||
participant: Identifier,
|
||||
) -> Result<HashMap<Identifier, Scalar>, Error> {
|
||||
) -> Result<BTreeMap<Identifier, Scalar>, Error> {
|
||||
frost::keys::repairable::repair_share_step_1(helpers, share_i, rng, participant)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![doc = document_features::document_features!()]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use p256::{
|
||||
elliptic_curve::{
|
||||
|
@ -242,7 +242,7 @@ type P = P256Sha256;
|
|||
pub type Identifier = frost::Identifier<P>;
|
||||
/// FROST(P-256, SHA-256) keys, key generation, key shares.
|
||||
pub mod keys {
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -256,7 +256,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
|
@ -421,7 +421,7 @@ pub type Signature = frost_core::Signature<P>;
|
|||
/// service attack due to publishing an invalid signature.
|
||||
pub fn aggregate(
|
||||
signing_package: &SigningPackage,
|
||||
signature_shares: &HashMap<Identifier, round2::SignatureShare>,
|
||||
signature_shares: &BTreeMap<Identifier, round2::SignatureShare>,
|
||||
pubkeys: &keys::PublicKeyPackage,
|
||||
) -> Result<Signature, Error> {
|
||||
frost::aggregate(signing_package, signature_shares, pubkeys)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Generate sample, fixed instances of structs for testing.
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_core::{Ciphersuite, Element, Group, Scalar};
|
||||
use frost_p256::{
|
||||
|
@ -90,7 +90,7 @@ pub fn public_key_package() -> PublicKeyPackage {
|
|||
let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap();
|
||||
let serialized_element = <C as Ciphersuite>::Group::serialize(&element1());
|
||||
let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap();
|
||||
let verifying_shares = HashMap::from([(identifier, verifying_share)]);
|
||||
let verifying_shares = BTreeMap::from([(identifier, verifying_share)]);
|
||||
|
||||
PublicKeyPackage::new(verifying_shares, verifying_key)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#[cfg(any(test, feature = "test-impl"))]
|
||||
pub mod tests;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use derive_getters::Getters;
|
||||
pub use frost_core;
|
||||
|
@ -132,7 +132,7 @@ pub fn sign<C: Ciphersuite>(
|
|||
/// See [`frost::aggregate`] for documentation on the other parameters.
|
||||
pub fn aggregate<C>(
|
||||
signing_package: &frost::SigningPackage<C>,
|
||||
signature_shares: &HashMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
signature_shares: &BTreeMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
|
||||
pubkeys: &frost::keys::PublicKeyPackage<C>,
|
||||
randomized_params: &RandomizedParams<C>,
|
||||
) -> Result<frost_core::Signature<C>, Error<C>>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Ciphersuite-generic test functions for re-randomized FROST.
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::{frost_core::frost, frost_core::Ciphersuite, RandomizedParams, Randomizer};
|
||||
use frost_core::{Signature, VerifyingKey};
|
||||
|
@ -27,14 +27,15 @@ pub fn check_randomized_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>
|
|||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
HashMap::new();
|
||||
let mut key_packages: BTreeMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
for (k, v) in shares {
|
||||
key_packages.insert(k, frost::keys::KeyPackage::try_from(v).unwrap());
|
||||
}
|
||||
|
||||
let mut nonces: HashMap<frost::Identifier<C>, frost::round1::SigningNonces<C>> = HashMap::new();
|
||||
let mut nonces: BTreeMap<frost::Identifier<C>, frost::round1::SigningNonces<C>> =
|
||||
BTreeMap::new();
|
||||
let mut commitments: BTreeMap<frost::Identifier<C>, frost::round1::SigningCommitments<C>> =
|
||||
BTreeMap::new();
|
||||
|
||||
|
@ -64,8 +65,8 @@ pub fn check_randomized_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>
|
|||
// This is what the signature aggregator / coordinator needs to do:
|
||||
// - decide what message to sign
|
||||
// - take one (unused) commitment per signing participant
|
||||
let mut signature_shares: HashMap<frost::Identifier<_>, frost::round2::SignatureShare<_>> =
|
||||
HashMap::new();
|
||||
let mut signature_shares: BTreeMap<frost::Identifier<_>, frost::round2::SignatureShare<_>> =
|
||||
BTreeMap::new();
|
||||
let message = "message to sign".as_bytes();
|
||||
let signing_package = frost::SigningPackage::new(commitments, message);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ scenario in a single thread and it abstracts away any communication between peer
|
|||
# // ANCHOR: tkg_gen
|
||||
use frost_ristretto255 as frost;
|
||||
use rand::thread_rng;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
|
@ -25,10 +25,10 @@ let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
|||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
// Verifies the secret shares from the dealer and store them in a BTreeMap.
|
||||
// In practice, the KeyPackages must be sent to its respective participants
|
||||
// through a confidential and authenticated channel.
|
||||
let mut key_packages: HashMap<_, _> = HashMap::new();
|
||||
let mut key_packages: BTreeMap<_, _> = BTreeMap::new();
|
||||
|
||||
for (identifier, secret_share) in shares {
|
||||
# // ANCHOR: tkg_verify
|
||||
|
@ -37,7 +37,7 @@ for (identifier, secret_share) in shares {
|
|||
key_packages.insert(identifier, key_package);
|
||||
}
|
||||
|
||||
let mut nonces_map = HashMap::new();
|
||||
let mut nonces_map = BTreeMap::new();
|
||||
let mut commitments_map = BTreeMap::new();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,7 @@ for participant_index in 1..(min_signers as u16 + 1) {
|
|||
// This is what the signature aggregator / coordinator needs to do:
|
||||
// - decide what message to sign
|
||||
// - take one (unused) commitment per signing participant
|
||||
let mut signature_shares = HashMap::new();
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
# // ANCHOR: round2_package
|
||||
let message = "message to sign".as_bytes();
|
||||
# // In practice, the SigningPackage must be sent to all participants
|
||||
|
|
|
@ -27,7 +27,7 @@ they can proceed to sign messages with FROST.
|
|||
```rust
|
||||
# // ANCHOR: dkg_import
|
||||
use rand::thread_rng;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_ristretto255 as frost;
|
||||
|
||||
|
@ -44,12 +44,12 @@ let min_signers = 3;
|
|||
// Keep track of each participant's round 1 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round1_secret_packages = HashMap::new();
|
||||
let mut round1_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 1 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round1_packages = HashMap::new();
|
||||
let mut received_round1_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the first part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -69,7 +69,7 @@ for participant_index in 1..=max_signers {
|
|||
round1_secret_packages.insert(participant_identifier, round1_secret_package);
|
||||
|
||||
// "Send" the round 1 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
for receiver_participant_index in 1..=max_signers {
|
||||
if receiver_participant_index == participant_index {
|
||||
|
@ -80,7 +80,7 @@ for participant_index in 1..=max_signers {
|
|||
.expect("should be nonzero");
|
||||
received_round1_packages
|
||||
.entry(receiver_participant_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round1_package.clone());
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's round 2 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round2_secret_packages = HashMap::new();
|
||||
let mut round2_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 2 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round2_packages = HashMap::new();
|
||||
let mut received_round2_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the second part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -117,14 +117,14 @@ for participant_index in 1..=max_signers {
|
|||
round2_secret_packages.insert(participant_identifier, round2_secret_package);
|
||||
|
||||
// "Send" the round 2 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
// 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 {
|
||||
received_round2_packages
|
||||
.entry(receiver_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round2_package);
|
||||
}
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's long-lived key package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut key_packages = HashMap::new();
|
||||
let mut key_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of each participant's public key package.
|
||||
// In practice, if there is a Coordinator, only they need to store the set.
|
||||
// If there is not, then all candidates must store their own sets.
|
||||
// All participants will have the same exact public key package.
|
||||
let mut pubkey_packages = HashMap::new();
|
||||
let mut pubkey_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the third part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
|
|
@ -64,8 +64,8 @@ pub fn part1<R: RngCore + CryptoRng>(
|
|||
/// must be sent to other participants.
|
||||
pub fn part2(
|
||||
secret_package: round1::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, HashMap<Identifier, round2::Package>), Error> {
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, BTreeMap<Identifier, round2::Package>), Error> {
|
||||
frost::keys::dkg::part2(secret_package, round1_packages)
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,8 @@ pub fn part2(
|
|||
/// signatures.
|
||||
pub fn part3(
|
||||
round2_secret_package: &round2::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
round2_packages: &HashMap<Identifier, round2::Package>,
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
round2_packages: &BTreeMap<Identifier, round2::Package>,
|
||||
) -> Result<(KeyPackage, PublicKeyPackage), Error> {
|
||||
frost::keys::dkg::part3(round2_secret_package, round1_packages, round2_packages)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
|
||||
//! using a subset of the other signers know here as `helpers`.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// This is imported separately to make `gencode` work.
|
||||
// (if it were below, the position of the import would vary between ciphersuites
|
||||
|
@ -20,13 +20,13 @@ use super::{SecretShare, VerifiableSecretSharingCommitment};
|
|||
/// where `helpers` contains the identifiers of all the helpers (including `helper_i`), and `share_i`
|
||||
/// is the share of `helper_i`.
|
||||
///
|
||||
/// Returns a HashMap mapping which value should be sent to which participant.
|
||||
/// Returns a BTreeMap mapping which value should be sent to which participant.
|
||||
pub fn repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
helpers: &[Identifier],
|
||||
share_i: &SecretShare,
|
||||
rng: &mut R,
|
||||
participant: Identifier,
|
||||
) -> Result<HashMap<Identifier, Scalar>, Error> {
|
||||
) -> Result<BTreeMap<Identifier, Scalar>, Error> {
|
||||
frost::keys::repairable::repair_share_step_1(helpers, share_i, rng, participant)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#![deny(missing_docs)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use curve25519_dalek::{
|
||||
constants::RISTRETTO_BASEPOINT_POINT,
|
||||
|
@ -203,7 +203,7 @@ pub type Identifier = frost::Identifier<R>;
|
|||
/// FROST(ristretto255, SHA-512) keys, key generation, key shares.
|
||||
pub mod keys {
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, R>;
|
||||
|
@ -215,7 +215,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
|
@ -380,7 +380,7 @@ pub type Signature = frost_core::Signature<R>;
|
|||
/// service attack due to publishing an invalid signature.
|
||||
pub fn aggregate(
|
||||
signing_package: &SigningPackage,
|
||||
signature_shares: &HashMap<Identifier, round2::SignatureShare>,
|
||||
signature_shares: &BTreeMap<Identifier, round2::SignatureShare>,
|
||||
pubkeys: &keys::PublicKeyPackage,
|
||||
) -> Result<Signature, Error> {
|
||||
frost::aggregate(signing_package, signature_shares, pubkeys)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Generate sample, fixed instances of structs for testing.
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_core::{Ciphersuite, Element, Group, Scalar};
|
||||
use frost_ristretto255::{
|
||||
|
@ -90,7 +90,7 @@ pub fn public_key_package() -> PublicKeyPackage {
|
|||
let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap();
|
||||
let serialized_element = <C as Ciphersuite>::Group::serialize(&element1());
|
||||
let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap();
|
||||
let verifying_shares = HashMap::from([(identifier, verifying_share)]);
|
||||
let verifying_shares = BTreeMap::from([(identifier, verifying_share)]);
|
||||
|
||||
PublicKeyPackage::new(verifying_shares, verifying_key)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ scenario in a single thread and it abstracts away any communication between peer
|
|||
# // ANCHOR: tkg_gen
|
||||
use frost_secp256k1 as frost;
|
||||
use rand::thread_rng;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
|
@ -25,10 +25,10 @@ let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
|||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
// Verifies the secret shares from the dealer and store them in a BTreeMap.
|
||||
// In practice, the KeyPackages must be sent to its respective participants
|
||||
// through a confidential and authenticated channel.
|
||||
let mut key_packages: HashMap<_, _> = HashMap::new();
|
||||
let mut key_packages: BTreeMap<_, _> = BTreeMap::new();
|
||||
|
||||
for (identifier, secret_share) in shares {
|
||||
# // ANCHOR: tkg_verify
|
||||
|
@ -37,7 +37,7 @@ for (identifier, secret_share) in shares {
|
|||
key_packages.insert(identifier, key_package);
|
||||
}
|
||||
|
||||
let mut nonces_map = HashMap::new();
|
||||
let mut nonces_map = BTreeMap::new();
|
||||
let mut commitments_map = BTreeMap::new();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,7 @@ for participant_index in 1..(min_signers as u16 + 1) {
|
|||
// This is what the signature aggregator / coordinator needs to do:
|
||||
// - decide what message to sign
|
||||
// - take one (unused) commitment per signing participant
|
||||
let mut signature_shares = HashMap::new();
|
||||
let mut signature_shares = BTreeMap::new();
|
||||
# // ANCHOR: round2_package
|
||||
let message = "message to sign".as_bytes();
|
||||
# // In practice, the SigningPackage must be sent to all participants
|
||||
|
|
|
@ -27,7 +27,7 @@ they can proceed to sign messages with FROST.
|
|||
```rust
|
||||
# // ANCHOR: dkg_import
|
||||
use rand::thread_rng;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_secp256k1 as frost;
|
||||
|
||||
|
@ -44,12 +44,12 @@ let min_signers = 3;
|
|||
// Keep track of each participant's round 1 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round1_secret_packages = HashMap::new();
|
||||
let mut round1_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 1 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round1_packages = HashMap::new();
|
||||
let mut received_round1_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the first part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -69,7 +69,7 @@ for participant_index in 1..=max_signers {
|
|||
round1_secret_packages.insert(participant_identifier, round1_secret_package);
|
||||
|
||||
// "Send" the round 1 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
for receiver_participant_index in 1..=max_signers {
|
||||
if receiver_participant_index == participant_index {
|
||||
|
@ -80,7 +80,7 @@ for participant_index in 1..=max_signers {
|
|||
.expect("should be nonzero");
|
||||
received_round1_packages
|
||||
.entry(receiver_participant_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round1_package.clone());
|
||||
}
|
||||
}
|
||||
|
@ -92,12 +92,12 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's round 2 secret package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut round2_secret_packages = HashMap::new();
|
||||
let mut round2_secret_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of all round 2 packages sent to the given participant.
|
||||
// This is used to simulate the broadcast; in practice the packages
|
||||
// will be sent through some communication channel.
|
||||
let mut received_round2_packages = HashMap::new();
|
||||
let mut received_round2_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the second part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
@ -117,14 +117,14 @@ for participant_index in 1..=max_signers {
|
|||
round2_secret_packages.insert(participant_identifier, round2_secret_package);
|
||||
|
||||
// "Send" the round 2 package to all other participants. In this
|
||||
// test this is simulated using a HashMap; in practice this will be
|
||||
// test this is simulated using a BTreeMap; in practice this will be
|
||||
// sent through some communication channel.
|
||||
// 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 {
|
||||
received_round2_packages
|
||||
.entry(receiver_identifier)
|
||||
.or_insert_with(HashMap::new)
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(participant_identifier, round2_package);
|
||||
}
|
||||
}
|
||||
|
@ -136,13 +136,13 @@ for participant_index in 1..=max_signers {
|
|||
// Keep track of each participant's long-lived key package.
|
||||
// In practice each participant will keep its copy; no one
|
||||
// will have all the participant's packages.
|
||||
let mut key_packages = HashMap::new();
|
||||
let mut key_packages = BTreeMap::new();
|
||||
|
||||
// Keep track of each participant's public key package.
|
||||
// In practice, if there is a Coordinator, only they need to store the set.
|
||||
// If there is not, then all candidates must store their own sets.
|
||||
// All participants will have the same exact public key package.
|
||||
let mut pubkey_packages = HashMap::new();
|
||||
let mut pubkey_packages = BTreeMap::new();
|
||||
|
||||
// For each participant, perform the third part of the DKG protocol.
|
||||
// In practice, each participant will perform this on their own environments.
|
||||
|
|
|
@ -64,8 +64,8 @@ pub fn part1<R: RngCore + CryptoRng>(
|
|||
/// must be sent to other participants.
|
||||
pub fn part2(
|
||||
secret_package: round1::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, HashMap<Identifier, round2::Package>), Error> {
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
) -> Result<(round2::SecretPackage, BTreeMap<Identifier, round2::Package>), Error> {
|
||||
frost::keys::dkg::part2(secret_package, round1_packages)
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,8 @@ pub fn part2(
|
|||
/// signatures.
|
||||
pub fn part3(
|
||||
round2_secret_package: &round2::SecretPackage,
|
||||
round1_packages: &HashMap<Identifier, round1::Package>,
|
||||
round2_packages: &HashMap<Identifier, round2::Package>,
|
||||
round1_packages: &BTreeMap<Identifier, round1::Package>,
|
||||
round2_packages: &BTreeMap<Identifier, round2::Package>,
|
||||
) -> Result<(KeyPackage, PublicKeyPackage), Error> {
|
||||
frost::keys::dkg::part3(round2_secret_package, round1_packages, round2_packages)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! The RTS is used to help a signer (participant) repair their lost share. This is achieved
|
||||
//! using a subset of the other signers know here as `helpers`.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
// This is imported separately to make `gencode` work.
|
||||
// (if it were below, the position of the import would vary between ciphersuites
|
||||
|
@ -20,13 +20,13 @@ use super::{SecretShare, VerifiableSecretSharingCommitment};
|
|||
/// where `helpers` contains the identifiers of all the helpers (including `helper_i`), and `share_i`
|
||||
/// is the share of `helper_i`.
|
||||
///
|
||||
/// Returns a HashMap mapping which value should be sent to which participant.
|
||||
/// Returns a BTreeMap mapping which value should be sent to which participant.
|
||||
pub fn repair_share_step_1<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
helpers: &[Identifier],
|
||||
share_i: &SecretShare,
|
||||
rng: &mut R,
|
||||
participant: Identifier,
|
||||
) -> Result<HashMap<Identifier, Scalar>, Error> {
|
||||
) -> Result<BTreeMap<Identifier, Scalar>, Error> {
|
||||
frost::keys::repairable::repair_share_step_1(helpers, share_i, rng, participant)
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#![doc = include_str!("../README.md")]
|
||||
#![doc = document_features::document_features!()]
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use k256::{
|
||||
elliptic_curve::{
|
||||
|
@ -243,7 +243,7 @@ pub type Identifier = frost::Identifier<S>;
|
|||
/// FROST(secp256k1, SHA-256) keys, key generation, key shares.
|
||||
pub mod keys {
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, S>;
|
||||
|
@ -255,7 +255,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
|
@ -271,7 +271,7 @@ pub mod keys {
|
|||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
) -> Result<(BTreeMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
|
@ -420,7 +420,7 @@ pub type Signature = frost_core::Signature<S>;
|
|||
/// service attack due to publishing an invalid signature.
|
||||
pub fn aggregate(
|
||||
signing_package: &SigningPackage,
|
||||
signature_shares: &HashMap<Identifier, round2::SignatureShare>,
|
||||
signature_shares: &BTreeMap<Identifier, round2::SignatureShare>,
|
||||
pubkeys: &keys::PublicKeyPackage,
|
||||
) -> Result<Signature, Error> {
|
||||
frost::aggregate(signing_package, signature_shares, pubkeys)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Generate sample, fixed instances of structs for testing.
|
||||
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use frost_core::{Ciphersuite, Element, Group, Scalar};
|
||||
use frost_secp256k1::{
|
||||
|
@ -90,7 +90,7 @@ pub fn public_key_package() -> PublicKeyPackage {
|
|||
let verifying_share = VerifyingShare::deserialize(serialized_element).unwrap();
|
||||
let serialized_element = <C as Ciphersuite>::Group::serialize(&element1());
|
||||
let verifying_key = VerifyingKey::deserialize(serialized_element).unwrap();
|
||||
let verifying_shares = HashMap::from([(identifier, verifying_share)]);
|
||||
let verifying_shares = BTreeMap::from([(identifier, verifying_share)]);
|
||||
|
||||
PublicKeyPackage::new(verifying_shares, verifying_key)
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
//! - The repairable.rs module (it uses the frost-core docs as canonical)
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
collections::BTreeMap,
|
||||
env, fs,
|
||||
io::Write,
|
||||
iter::zip,
|
||||
|
@ -115,7 +115,7 @@ fn write_docs(
|
|||
let original_code = code.clone();
|
||||
|
||||
// Map documentations by their identifiers
|
||||
let docs: HashMap<String, (String, String, usize, usize)> =
|
||||
let docs: BTreeMap<String, (String, String, usize, usize)> =
|
||||
docs.iter().map(|x| (x.0.clone(), x.clone())).collect();
|
||||
|
||||
// To be able to replace the documentation properly, start from the end, which
|
||||
|
|
Loading…
Reference in New Issue