Convert all HashMaps to BTreeMaps (#547)

Convert HashMaps to BTreeMaps (#476)
This commit is contained in:
natalie 2023-09-22 15:08:32 +01:00 committed by GitHub
parent a5dc479b4d
commit ba3ef7dbb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 252 additions and 256 deletions

View File

@ -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}}

View File

@ -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`).

View File

@ -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();

View File

@ -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

View File

@ -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 {

View File

@ -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}^{t1} φ_{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);

View File

@ -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())

View File

@ -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();

View File

@ -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,

View File

@ -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() {

View File

@ -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

View File

@ -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.

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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

View File

@ -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.

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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

View File

@ -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.

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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>>

View File

@ -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);

View File

@ -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

View File

@ -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.

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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

View File

@ -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.

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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