allow specifying identifiers in generate_with_dealer (#419)
This commit is contained in:
parent
78b5c44de0
commit
4e134f50d6
|
@ -92,14 +92,24 @@ pub fn bench_sign<C: Ciphersuite, R: RngCore + CryptoRng + Clone>(
|
|||
|b, (max_signers, min_signers)| {
|
||||
let mut rng = rng.clone();
|
||||
b.iter(|| {
|
||||
frost::keys::generate_with_dealer::<C, R>(*max_signers, *min_signers, &mut rng)
|
||||
.unwrap();
|
||||
frost::keys::generate_with_dealer::<C, R>(
|
||||
*max_signers,
|
||||
*min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)
|
||||
.unwrap();
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let (shares, pubkeys) =
|
||||
frost::keys::generate_with_dealer::<C, R>(max_signers, min_signers, rng).unwrap();
|
||||
let (shares, pubkeys) = frost::keys::generate_with_dealer::<C, R>(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
|
|
|
@ -23,6 +23,9 @@ pub enum Error<C: Ciphersuite> {
|
|||
/// This identifier is unserializable.
|
||||
#[error("Malformed identifier is unserializable.")]
|
||||
MalformedIdentifier,
|
||||
/// This identifier is duplicated.
|
||||
#[error("Duplicated identifier.")]
|
||||
DuplicatedIdentifier,
|
||||
/// The encoding of a signing key was malformed.
|
||||
#[error("Malformed signing key encoding.")]
|
||||
MalformedSigningKey,
|
||||
|
@ -122,6 +125,7 @@ where
|
|||
| Error::DKGNotSupported
|
||||
| Error::FieldError(_)
|
||||
| Error::GroupError(_)
|
||||
| Error::DuplicatedIdentifier
|
||||
| Error::InvalidCoefficient
|
||||
| Error::IdentifierDerivationNotSupported => None,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#![allow(clippy::type_complexity)]
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
collections::{HashMap, HashSet},
|
||||
convert::TryFrom,
|
||||
default::Default,
|
||||
fmt::{self, Debug},
|
||||
|
@ -36,6 +36,13 @@ pub(crate) fn generate_coefficients<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// Return a list of default identifiers (1 to max_signers, inclusive).
|
||||
pub(crate) fn default_identifiers<C: Ciphersuite>(max_signers: u16) -> Vec<Identifier<C>> {
|
||||
(1..=max_signers)
|
||||
.map(|i| Identifier::<C>::try_from(i).expect("nonzero"))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
/// A secret scalar value representing a signer's share of the group secret.
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
|
@ -377,6 +384,14 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub enum IdentifierList<'a, C: Ciphersuite> {
|
||||
/// Use the default values (1 to max_signers, inclusive).
|
||||
Default,
|
||||
/// A user-provided list of identifiers.
|
||||
Custom(&'a [Identifier<C>]),
|
||||
}
|
||||
|
||||
/// Allows all participants' keys to be generated using a central, trusted
|
||||
/// dealer.
|
||||
///
|
||||
|
@ -392,6 +407,7 @@ where
|
|||
pub fn generate_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList<C>,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>), Error<C>> {
|
||||
let mut bytes = [0; 64];
|
||||
|
@ -399,7 +415,7 @@ pub fn generate_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
|
||||
let key = SigningKey::new(rng);
|
||||
|
||||
split(&key, max_signers, min_signers, rng)
|
||||
split(&key, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
/// Splits an existing key into FROST shares.
|
||||
|
@ -412,13 +428,21 @@ pub fn split<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
key: &SigningKey<C>,
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList<C>,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>), Error<C>> {
|
||||
let group_public = VerifyingKey::from(key);
|
||||
|
||||
let coefficients = generate_coefficients::<C, R>(min_signers as usize - 1, rng);
|
||||
|
||||
let secret_shares = generate_secret_shares(key, max_signers, min_signers, coefficients)?;
|
||||
let default_identifiers = default_identifiers(max_signers);
|
||||
let identifiers = match identifiers {
|
||||
IdentifierList::Custom(identifiers) => identifiers,
|
||||
IdentifierList::Default => &default_identifiers,
|
||||
};
|
||||
|
||||
let secret_shares =
|
||||
generate_secret_shares(key, max_signers, min_signers, coefficients, identifiers)?;
|
||||
let mut signer_pubkeys: HashMap<Identifier<C>, VerifyingShare<C>> =
|
||||
HashMap::with_capacity(max_signers as usize);
|
||||
|
||||
|
@ -671,18 +695,23 @@ pub(crate) fn generate_secret_shares<C: Ciphersuite>(
|
|||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
coefficients: Vec<Scalar<C>>,
|
||||
identifiers: &[Identifier<C>],
|
||||
) -> Result<Vec<SecretShare<C>>, Error<C>> {
|
||||
let mut secret_shares: Vec<SecretShare<C>> = Vec::with_capacity(max_signers as usize);
|
||||
|
||||
let (coefficients, commitment) =
|
||||
generate_secret_polynomial(secret, max_signers, min_signers, coefficients)?;
|
||||
|
||||
for idx in 1..=max_signers {
|
||||
let id = Identifier::<C>::try_from(idx)?;
|
||||
let value = evaluate_polynomial(id, &coefficients);
|
||||
let identifiers_set: HashSet<_> = identifiers.iter().collect();
|
||||
if identifiers_set.len() != identifiers.len() {
|
||||
return Err(Error::DuplicatedIdentifier);
|
||||
}
|
||||
|
||||
for id in identifiers {
|
||||
let value = evaluate_polynomial(*id, &coefficients);
|
||||
|
||||
secret_shares.push(SecretShare {
|
||||
identifier: id,
|
||||
identifier: *id,
|
||||
value: SigningShare(value),
|
||||
commitment: commitment.clone(),
|
||||
ciphersuite: (),
|
||||
|
|
|
@ -20,9 +20,14 @@ pub fn check_share_generation<C: Ciphersuite, R: RngCore + CryptoRng>(mut rng: R
|
|||
let coefficients =
|
||||
frost::keys::generate_coefficients::<C, _>(min_signers as usize - 1, &mut rng);
|
||||
|
||||
let secret_shares =
|
||||
frost::keys::generate_secret_shares(&secret, max_signers, min_signers, coefficients)
|
||||
.unwrap();
|
||||
let secret_shares = frost::keys::generate_secret_shares(
|
||||
&secret,
|
||||
max_signers,
|
||||
min_signers,
|
||||
coefficients,
|
||||
&frost::keys::default_identifiers(max_signers),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
for secret_share in secret_shares.iter() {
|
||||
assert!(secret_share.verify().is_ok());
|
||||
|
@ -62,8 +67,13 @@ pub fn check_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkeys) =
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng).unwrap();
|
||||
let (shares, pubkeys) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
|
@ -92,8 +102,7 @@ fn check_sign<C: Ciphersuite + PartialEq, R: RngCore + CryptoRng>(
|
|||
// Round 1: generating nonces and signing commitments for each participant
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
for participant_index in 1..(min_signers + 1) {
|
||||
let participant_identifier = participant_index.try_into().expect("should be nonzero");
|
||||
for participant_identifier in key_packages.keys().take(min_signers as usize).cloned() {
|
||||
// Generate one (1) nonce and one SigningCommitments instance for each
|
||||
// participant, up to _min_signers_.
|
||||
let (nonces, commitments) = frost::round1::commit(
|
||||
|
@ -346,6 +355,62 @@ where
|
|||
check_sign(min_signers, key_packages, rng, pubkeys)
|
||||
}
|
||||
|
||||
/// Test FROST signing with trusted dealer with a Ciphersuite, using specified
|
||||
/// Identifiers.
|
||||
pub fn check_sign_with_dealer_and_identifiers<C: Ciphersuite, R: RngCore + CryptoRng>(
|
||||
mut rng: R,
|
||||
) -> (Vec<u8>, Signature<C>, VerifyingKey<C>) {
|
||||
// Check error case first (repeated identifiers)
|
||||
|
||||
let identifiers: Vec<frost::Identifier<C>> = [1u16, 42, 100, 257, 42]
|
||||
.into_iter()
|
||||
.map(|i| i.try_into().unwrap())
|
||||
.collect();
|
||||
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let err = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Custom(&identifiers),
|
||||
&mut rng,
|
||||
)
|
||||
.debugless_unwrap_err();
|
||||
assert_eq!(err, Error::DuplicatedIdentifier);
|
||||
|
||||
// Check correct case
|
||||
|
||||
let identifiers: Vec<frost::Identifier<C>> = [1u16, 42, 100, 257, 65535]
|
||||
.into_iter()
|
||||
.map(|i| i.try_into().unwrap())
|
||||
.collect();
|
||||
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkeys) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Custom(&identifiers),
|
||||
&mut rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Check if the specified identifiers were used
|
||||
for id in identifiers {
|
||||
assert!(shares.contains_key(&id));
|
||||
}
|
||||
|
||||
// Do regular testing to make sure it works
|
||||
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
HashMap::new();
|
||||
for (k, v) in shares {
|
||||
let key_package = frost::keys::KeyPackage::try_from(v).unwrap();
|
||||
key_packages.insert(k, key_package);
|
||||
}
|
||||
check_sign(min_signers, key_packages, rng, pubkeys)
|
||||
}
|
||||
|
||||
fn check_part2_error<C: Ciphersuite>(
|
||||
round1_secret_package: frost::keys::dkg::round1::SecretPackage<C>,
|
||||
mut round1_packages: Vec<frost::keys::dkg::round1::Package<C>>,
|
||||
|
|
|
@ -32,7 +32,13 @@ 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>) =
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng).unwrap();
|
||||
frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Try to recover a share
|
||||
|
||||
|
@ -101,7 +107,13 @@ 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>) =
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng).unwrap();
|
||||
frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Signer 2 will lose their share
|
||||
// Signers (helpers) 1, 4 and 5 will help signer 2 (participant) to recover their share
|
||||
|
@ -161,7 +173,13 @@ pub fn check_repair_share_step_3<C: Ciphersuite, R: RngCore + CryptoRng>(
|
|||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, _pubkeys): (HashMap<Identifier<C>, SecretShare<C>>, PublicKeyPackage<C>) =
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng).unwrap();
|
||||
frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let sigmas: &Value = &repair_share_helpers["sigma_generation"];
|
||||
|
||||
|
|
|
@ -210,6 +210,7 @@ pub fn check_sign_with_test_vectors<C: Ciphersuite>(json_vectors: &Value) {
|
|||
max_signers as u16,
|
||||
min_signers as u16,
|
||||
share_polynomial_coefficients,
|
||||
&default_identifiers(max_signers as u16),
|
||||
)
|
||||
.unwrap();
|
||||
let secret_shares: HashMap<_, _> = secret_shares
|
||||
|
|
|
@ -17,7 +17,12 @@ use std::collections::HashMap;
|
|||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
|
|
|
@ -220,14 +220,18 @@ pub mod keys {
|
|||
|
||||
use super::*;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, E>;
|
||||
|
||||
/// Allows all participants' keys to be generated using a central, trusted
|
||||
/// dealer.
|
||||
pub fn generate_with_dealer<RNG: RngCore + CryptoRng>(
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
/// Splits an existing key into FROST shares.
|
||||
|
@ -240,9 +244,10 @@ pub mod keys {
|
|||
secret: &SigningKey,
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, rng)
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
/// Recompute the secret from t-of-n secret shares using Lagrange interpolation.
|
||||
|
|
|
@ -17,7 +17,12 @@ use std::collections::HashMap;
|
|||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
|
|
|
@ -214,14 +214,18 @@ pub mod keys {
|
|||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, E>;
|
||||
|
||||
/// Allows all participants' keys to be generated using a central, trusted
|
||||
/// dealer.
|
||||
pub fn generate_with_dealer<RNG: RngCore + CryptoRng>(
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
/// Splits an existing key into FROST shares.
|
||||
|
@ -234,9 +238,10 @@ pub mod keys {
|
|||
secret: &SigningKey,
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, rng)
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
/// Recompute the secret from t-of-n secret shares using Lagrange interpolation.
|
||||
|
|
|
@ -48,3 +48,13 @@ fn check_sign_with_test_vectors() {
|
|||
&VECTORS_BIG_IDENTIFIER,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
||||
frost_core::tests::ciphersuite_generic::check_sign_with_dealer_and_identifiers::<
|
||||
Ed448Shake256,
|
||||
_,
|
||||
>(rng);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,12 @@ use std::collections::HashMap;
|
|||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
|
|
|
@ -240,21 +240,24 @@ type P = P256Sha256;
|
|||
|
||||
/// A FROST(P-256, SHA-256) participant identifier.
|
||||
pub type Identifier = frost::Identifier<P>;
|
||||
|
||||
/// FROST(P-256, SHA-256) keys, key generation, key shares.
|
||||
pub mod keys {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::*;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, P>;
|
||||
|
||||
/// Allows all participants' keys to be generated using a central, trusted
|
||||
/// dealer.
|
||||
pub fn generate_with_dealer<RNG: RngCore + CryptoRng>(
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
/// Splits an existing key into FROST shares.
|
||||
|
@ -267,9 +270,10 @@ pub mod keys {
|
|||
secret: &SigningKey,
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, rng)
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
/// Recompute the secret from t-of-n secret shares using Lagrange interpolation.
|
||||
|
|
|
@ -46,3 +46,12 @@ fn check_sign_with_test_vectors() {
|
|||
frost_core::tests::vectors::check_sign_with_test_vectors::<P256Sha256>(&VECTORS);
|
||||
frost_core::tests::vectors::check_sign_with_test_vectors::<P256Sha256>(&VECTORS_BIG_IDENTIFIER);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
||||
frost_core::tests::ciphersuite_generic::check_sign_with_dealer_and_identifiers::<P256Sha256, _>(
|
||||
rng,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,13 @@ pub fn check_randomized_sign_with_dealer<C: Ciphersuite, R: RngCore + CryptoRng>
|
|||
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkeys) =
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng).unwrap();
|
||||
let (shares, pubkeys) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Verifies the secret shares from the dealer
|
||||
let mut key_packages: HashMap<frost::Identifier<C>, frost::keys::KeyPackage<C>> =
|
||||
|
|
|
@ -17,7 +17,12 @@ use std::collections::HashMap;
|
|||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
|
|
|
@ -208,14 +208,18 @@ pub mod keys {
|
|||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, R>;
|
||||
|
||||
/// Allows all participants' keys to be generated using a central, trusted
|
||||
/// dealer.
|
||||
pub fn generate_with_dealer<RNG: RngCore + CryptoRng>(
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
/// Splits an existing key into FROST shares.
|
||||
|
@ -228,9 +232,10 @@ pub mod keys {
|
|||
secret: &SigningKey,
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, rng)
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
/// Recompute the secret from t-of-n secret shares using Lagrange interpolation.
|
||||
|
|
|
@ -58,3 +58,13 @@ fn check_error_culprit() {
|
|||
fn check_identifier_derivation() {
|
||||
frost_core::tests::ciphersuite_generic::check_identifier_derivation::<Ristretto255Sha512>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
||||
frost_core::tests::ciphersuite_generic::check_sign_with_dealer_and_identifiers::<
|
||||
Ristretto255Sha512,
|
||||
_,
|
||||
>(rng);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,12 @@ use std::collections::HashMap;
|
|||
let mut rng = thread_rng();
|
||||
let max_signers = 5;
|
||||
let min_signers = 3;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?;
|
||||
let (shares, pubkey_package) = frost::keys::generate_with_dealer(
|
||||
max_signers,
|
||||
min_signers,
|
||||
frost::keys::IdentifierList::Default,
|
||||
&mut rng,
|
||||
)?;
|
||||
# // ANCHOR_END: tkg_gen
|
||||
|
||||
// Verifies the secret shares from the dealer and store them in a HashMap.
|
||||
|
|
|
@ -246,14 +246,18 @@ pub mod keys {
|
|||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// The identifier list to use when generating key shares.
|
||||
pub type IdentifierList<'a> = frost::keys::IdentifierList<'a, S>;
|
||||
|
||||
/// Allows all participants' keys to be generated using a central, trusted
|
||||
/// dealer.
|
||||
pub fn generate_with_dealer<RNG: RngCore + CryptoRng>(
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
mut rng: RNG,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)
|
||||
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
|
||||
}
|
||||
|
||||
/// Splits an existing key into FROST shares.
|
||||
|
@ -266,9 +270,10 @@ pub mod keys {
|
|||
secret: &SigningKey,
|
||||
max_signers: u16,
|
||||
min_signers: u16,
|
||||
identifiers: IdentifierList,
|
||||
rng: &mut R,
|
||||
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
|
||||
frost::keys::split(secret, max_signers, min_signers, rng)
|
||||
frost::keys::split(secret, max_signers, min_signers, identifiers, rng)
|
||||
}
|
||||
|
||||
/// Recompute the secret from t-of-n secret shares using Lagrange interpolation.
|
||||
|
|
|
@ -48,3 +48,13 @@ fn check_sign_with_test_vectors() {
|
|||
&VECTORS_BIG_IDENTIFIER,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
||||
frost_core::tests::ciphersuite_generic::check_sign_with_dealer_and_identifiers::<
|
||||
Secp256K1Sha256,
|
||||
_,
|
||||
>(rng);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue