From e2940a465d62012581b89800fef23ec6dc241d40 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Fri, 28 May 2021 09:06:51 -0300 Subject: [PATCH] Change the type of the identifiers from u8 to u64 (#110) * Change the type of the identifiers from u8 to u64 * add a TODO Co-authored-by: Marek --- src/frost.rs | 43 ++++++++++++++++++++++++------------------- tests/frost.rs | 6 +++--- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/frost.rs b/src/frost.rs index ba22653..f45f622 100644 --- a/src/frost.rs +++ b/src/frost.rs @@ -62,7 +62,7 @@ impl From for Public { /// reconstruct the secret; in this case we use Shamir's secret sharing. #[derive(Clone)] pub struct Share { - receiver_index: u8, + receiver_index: u64, value: Secret, commitment: ShareCommitment, } @@ -102,9 +102,8 @@ pub struct GroupCommitment(jubjub::AffinePoint); pub struct SharePackage { /// The public signing key that represents the entire group. pub(crate) group_public: VerificationKey, - /// Denotes the participant index each share is owned by. We implicitly - /// restrict the number of participants to 255. - pub index: u8, + /// Denotes the participant index each share is owned by. + pub index: u64, /// This participant's public key. pub(crate) public: Public, /// This participant's share. @@ -142,7 +141,7 @@ impl TryFrom for KeyPackage { /// [`KeyPackage`]s, which they store to later use during signing. #[allow(dead_code)] pub struct KeyPackage { - index: u8, + index: u64, secret_share: Secret, public: Public, group_public: VerificationKey, @@ -157,7 +156,7 @@ pub struct PublicKeyPackage { /// correct view of participant's public keys to perform verification before /// publishing a signature. signer_pubkeys represents all signers for a /// signing operation. - pub(crate) signer_pubkeys: HashMap, + pub(crate) signer_pubkeys: HashMap, /// group_public represents the joint public key for the entire group. pub group_public: VerificationKey, } @@ -168,7 +167,8 @@ pub struct PublicKeyPackage { /// Under the hood, this performs verifiable secret sharing, which itself uses /// Shamir secret sharing, from which each share becomes a participant's secret /// key. The output from this function is a set of shares along with one single -/// commitment that participants use to verify the integrity of the share. +/// commitment that participants use to verify the integrity of the share. The +/// number of signers is limited to 255. pub fn keygen_with_dealer( num_signers: u8, threshold: u8, @@ -181,7 +181,7 @@ pub fn keygen_with_dealer( let group_public = VerificationKey::from(&secret.0); let shares = generate_shares(&secret, num_signers, threshold, rng)?; let mut sharepackages: Vec = Vec::with_capacity(num_signers as usize); - let mut signer_pubkeys: HashMap = HashMap::with_capacity(num_signers as usize); + let mut signer_pubkeys: HashMap = HashMap::with_capacity(num_signers as usize); for share in shares { let signer_public = Public(SpendAuth::basepoint() * share.value.0); @@ -301,7 +301,7 @@ fn generate_shares( value += secret.0; shares.push(Share { - receiver_index: index, + receiver_index: index as u64, value: Secret(value), commitment: commitment.clone(), }); @@ -363,14 +363,14 @@ impl SigningNonces { /// SigningCommitment can be used for exactly *one* signature. #[derive(Copy, Clone)] pub struct SigningCommitments { - index: u8, + index: u64, hiding: jubjub::ExtendedPoint, binding: jubjub::ExtendedPoint, } -impl From<(u8, &SigningNonces)> for SigningCommitments { +impl From<(u64, &SigningNonces)> for SigningCommitments { /// For SpendAuth signatures only, not Binding signatures, in RedJubjub/Zcash. - fn from((index, nonces): (u8, &SigningNonces)) -> Self { + fn from((index, nonces): (u64, &SigningNonces)) -> Self { Self { index, hiding: SpendAuth::basepoint() * nonces.hiding, @@ -400,7 +400,7 @@ pub struct SignatureResponse(Scalar); #[derive(Clone, Copy, Default)] pub struct SignatureShare { /// Represents the participant index. - pub(crate) index: u8, + pub(crate) index: u64, /// This participant's signature over the message. pub(crate) signature: SignatureResponse, } @@ -437,9 +437,14 @@ impl SignatureShare { /// perform the first round. Batching entails generating more than one /// nonce/commitment pair at a time. Nonces should be stored in secret storage /// for later use, whereas the commitments are published. + +/// The number of nonces is limited to 255. This limit can be increased if it +/// turns out to be too conservative. +// TODO: Make sure the above is a correct statement, fix if needed in: +// https://github.com/ZcashFoundation/redjubjub/issues/111 pub fn preprocess( num_nonces: u8, - participant_index: u8, + participant_index: u64, rng: &mut R, ) -> (Vec, Vec) where @@ -459,7 +464,7 @@ where /// Generates the binding factor that ensures each signature share is strongly /// bound to a signing set, specific set of commitments, and a specific message. -fn gen_rho_i(index: u8, signing_package: &SigningPackage) -> Scalar { +fn gen_rho_i(index: u64, signing_package: &SigningPackage) -> Scalar { // Hash signature message with HStar before deriving the binding factor. // // To avoid a collision with other inputs to the hash that generates the @@ -489,7 +494,7 @@ fn gen_rho_i(index: u8, signing_package: &SigningPackage) -> Scalar { /// Schnorr signature. fn gen_group_commitment( signing_package: &SigningPackage, - bindings: &HashMap, + bindings: &HashMap, ) -> Result { let identity = jubjub::ExtendedPoint::identity(); let mut accumulator = identity; @@ -527,7 +532,7 @@ fn gen_challenge( /// Generates the lagrange coefficient for the i'th participant. fn gen_lagrange_coeff( - signer_index: u8, + signer_index: u64, signing_package: &SigningPackage, ) -> Result { let mut num = Scalar::one(); @@ -563,7 +568,7 @@ pub fn sign( participant_nonces: SigningNonces, share_package: &SharePackage, ) -> Result { - let mut bindings: HashMap = + let mut bindings: HashMap = HashMap::with_capacity(signing_package.signing_commitments.len()); for comm in signing_package.signing_commitments.iter() { @@ -616,7 +621,7 @@ pub fn aggregate( signing_shares: &[SignatureShare], pubkeys: &PublicKeyPackage, ) -> Result, &'static str> { - let mut bindings: HashMap = + let mut bindings: HashMap = HashMap::with_capacity(signing_package.signing_commitments.len()); for comm in signing_package.signing_commitments.iter() { diff --git a/tests/frost.rs b/tests/frost.rs index 678d743..84971e9 100644 --- a/tests/frost.rs +++ b/tests/frost.rs @@ -10,7 +10,7 @@ fn check_sign_with_dealer() { let threshold = 3; let (shares, pubkeys) = frost::keygen_with_dealer(numsigners, threshold, &mut rng).unwrap(); - let mut nonces: HashMap> = + let mut nonces: HashMap> = HashMap::with_capacity(threshold as usize); let mut commitments: Vec = Vec::with_capacity(threshold as usize); @@ -18,8 +18,8 @@ fn check_sign_with_dealer() { for participant_index in 1..(threshold + 1) { // Generate one (1) nonce and one SigningCommitments instance for each // participant, up to _threshold_. - let (nonce, commitment) = frost::preprocess(1, participant_index, &mut rng); - nonces.insert(participant_index, nonce); + let (nonce, commitment) = frost::preprocess(1, participant_index as u64, &mut rng); + nonces.insert(participant_index as u64, nonce); commitments.push(commitment[0]); }