Skip to content

Commit

Permalink
incorporate frost repo fixes; add into_positive_y() for RedPallas
Browse files Browse the repository at this point in the history
  • Loading branch information
conradoplg committed Jul 22, 2023
1 parent a9c910a commit c4021a4
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 34 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ pasta_curves = { version = "0.5", default-features = false }
rand_core = { version = "0.6", default-features = false }
serde = { version = "1", optional = true, features = ["derive"] }
thiserror = { version = "1.0", optional = true }
frost-rerandomized = { version = "0.6.0", optional = true }
# frost-rerandomized = { version = "0.6.0", optional = true }
frost-rerandomized = { git = "https://github.com/ZcashFoundation/frost.git", rev = "a1834dccd046d852e368c565474e78af77b5d9a8", features=["test-impl"], optional = true }

[dependencies.zeroize]
version = "1"
Expand All @@ -50,7 +51,8 @@ proptest = "1.0"
rand = "0.8"
rand_chacha = "0.3"
serde_json = "1.0"
frost-rerandomized = { version = "0.6.0", features=["test-impl"] }
# frost-rerandomized = { version = "0.6.0", features=["test-impl"] }
frost-rerandomized = { git = "https://github.com/ZcashFoundation/frost.git", rev = "a1834dccd046d852e368c565474e78af77b5d9a8", features=["test-impl"] }
num-bigint = "0.4.3"
num-traits = "0.2.15"

Expand All @@ -66,6 +68,7 @@ std = ["blake2b_simd/std", "thiserror", "zeroize", "alloc",
alloc = ["hex"]
nightly = []
frost = ["std", "frost-rerandomized"]
serde = ["dep:serde", "frost-rerandomized?/serde"]
default = ["std"]

[[bench]]
Expand Down
72 changes: 56 additions & 16 deletions src/frost/redjubjub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ use group::GroupEncoding;
#[cfg(feature = "alloc")]
use group::{ff::Field as FFField, ff::PrimeField};

use frost_rerandomized::{
frost_core::{frost, Ciphersuite, Field, FieldError, Group, GroupError},
RandomizedParams,
// Re-exports in our public API
#[cfg(feature = "serde")]
pub use frost_rerandomized::frost_core::serde;
pub use frost_rerandomized::frost_core::{
frost, Ciphersuite, Field, FieldError, Group, GroupError,
};
pub use rand_core;

use rand_core::{CryptoRng, RngCore};

Expand Down Expand Up @@ -198,15 +201,37 @@ pub mod keys {
frost::keys::generate_with_dealer(max_signers, min_signers, identifiers, &mut rng)
}

/// Splits an existing key into FROST shares.
///
/// This is identical to [`generate_with_dealer`] but receives an existing key
/// instead of generating a fresh one. This is useful in scenarios where
/// the key needs to be generated externally or must be derived from e.g. a
/// seed phrase.
pub fn split<R: RngCore + CryptoRng>(
key: &SigningKey,
max_signers: u16,
min_signers: u16,
identifiers: IdentifierList,
rng: &mut R,
) -> Result<(HashMap<Identifier, SecretShare>, PublicKeyPackage), Error> {
frost::keys::split(key, max_signers, min_signers, identifiers, rng)
}

/// Secret and public key material generated by a dealer performing
/// [`keygen_with_dealer`].
/// [`generate_with_dealer`].
///
/// # Security
///
/// To derive a FROST(Jubjub, BLAKE2b-512) keypair, the receiver of the [`SecretShare`] *must* call
/// .into(), which under the hood also performs validation.
pub type SecretShare = frost::keys::SecretShare<J>;

/// A secret scalar value representing a signer's share of the group secret.
pub type SigningShare = frost::keys::SigningShare<J>;

/// A public group element that represents a single signer's public verification share.
pub type VerifyingShare = frost::keys::VerifyingShare<J>;

/// A FROST(Jubjub, BLAKE2b-512) keypair, which can be generated either by a trusted dealer or using
/// a DKG.
///
Expand All @@ -221,7 +246,22 @@ pub mod keys {
/// Used for verification purposes before publishing a signature.
pub type PublicKeyPackage = frost::keys::PublicKeyPackage<J>;

/// Contains the commitments to the coefficients for our secret polynomial _f_,
/// used to generate participants' key shares.
///
/// [`VerifiableSecretSharingCommitment`] contains a set of commitments to the coefficients (which
/// themselves are scalars) for a secret polynomial f, where f is used to
/// generate each ith participant's key share f(i). Participants use this set of
/// commitments to perform verifiable secret sharing.
///
/// Note that participants MUST be assured that they have the *same*
/// [`VerifiableSecretSharingCommitment`], either by performing pairwise comparison, or by using
/// some agreed-upon public location for publication, where each participant can
/// ensure that they received the correct (and same) value.
pub type VerifiableSecretSharingCommitment = frost::keys::VerifiableSecretSharingCommitment<J>;

pub mod dkg;
pub mod repairable;
}

/// FROST(Jubjub, BLAKE2b-512) Round 1 functionality and types.
Expand All @@ -242,6 +282,9 @@ pub mod round1 {
/// SigningCommitment can be used for exactly *one* signature.
pub type SigningCommitments = frost::round1::SigningCommitments<J>;

/// A commitment to a signing nonce share.
pub type NonceCommitment = frost::round1::NonceCommitment<J>;

/// Performed once by each participant selected for the signing operation.
///
/// Generates the signing nonces and commitments to be used in the signing
Expand Down Expand Up @@ -269,9 +312,8 @@ pub mod round2 {
/// shares into the joint signature.
pub type SignatureShare = frost::round2::SignatureShare<J>;

/// Generated by the coordinator of the signing operation and distributed to
/// each signing party
pub type SigningPackage = frost::SigningPackage<J>;
/// A randomizer. A random scalar which is used to randomize the key.
pub type Randomizer = frost_rerandomized::Randomizer<J>;

/// Performed once by each participant selected for the signing operation.
///
Expand All @@ -285,20 +327,18 @@ pub mod round2 {
signing_package: &SigningPackage,
signer_nonces: &round1::SigningNonces,
key_package: &keys::KeyPackage,
randomizer_point: &<<J as Ciphersuite>::Group as Group>::Element,
randomizer: Randomizer,
) -> Result<SignatureShare, Error> {
frost_rerandomized::sign(
signing_package,
signer_nonces,
key_package,
randomizer_point,
)
frost_rerandomized::sign(signing_package, signer_nonces, key_package, randomizer)
}
}

/// A Schnorr signature on FROST(Jubjub, BLAKE2b-512).
pub type Signature = frost_rerandomized::frost_core::Signature<J>;

/// Randomized parameters for a signing instance of randomized FROST.
pub type RandomizedParams = frost_rerandomized::RandomizedParams<J>;

/// Verifies each FROST(Jubjub, BLAKE2b-512) participant's signature share, and if all are valid,
/// aggregates the shares into a signature to publish.
///
Expand All @@ -315,10 +355,10 @@ pub type Signature = frost_rerandomized::frost_core::Signature<J>;
/// can avoid that step. However, at worst, this results in a denial of
/// service attack due to publishing an invalid signature.
pub fn aggregate(
signing_package: &round2::SigningPackage,
signing_package: &SigningPackage,
signature_shares: &HashMap<Identifier, round2::SignatureShare>,
pubkeys: &keys::PublicKeyPackage,
randomized_params: &RandomizedParams<J>,
randomized_params: &RandomizedParams,
) -> Result<Signature, Error> {
frost_rerandomized::aggregate(
signing_package,
Expand Down
55 changes: 55 additions & 0 deletions src/frost/redjubjub/keys/repairable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//! Repairable Threshold Scheme
//!
//! Implements the Repairable Threshold Scheme (RTS) from <https://eprint.iacr.org/2017/1155>.
//! 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 jubjub::Scalar;

use crate::frost::redjubjub::{
frost, Ciphersuite, CryptoRng, Error, Identifier, JubjubBlake2b512, RngCore,
};

use super::{SecretShare, VerifiableSecretSharingCommitment};

/// Step 1 of RTS.
///
/// Generates the "delta" values from `helper_i` to help `participant` recover their share
/// 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.
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> {
frost::keys::repairable::repair_share_step_1(helpers, share_i, rng, participant)
}

/// Step 2 of RTS.
///
/// Generates the `sigma` values from all `deltas` received from `helpers`
/// to help `participant` recover their share.
/// `sigma` is the sum of all received `delta` and the `delta_i` generated for `helper_i`.
///
/// Returns a scalar
pub fn repair_share_step_2(deltas_j: &[Scalar]) -> Scalar {
frost::keys::repairable::repair_share_step_2::<JubjubBlake2b512>(deltas_j)
}

/// Step 3 of RTS
///
/// The `participant` sums all `sigma_j` received to compute the `share`. The `SecretShare`
/// is made up of the `identifier`and `commitment` of the `participant` as well as the
/// `value` which is the `SigningShare`.
pub fn repair_share_step_3(
sigmas: &[Scalar],
identifier: Identifier,
commitment: &VerifiableSecretSharingCommitment,
) -> SecretShare {
frost::keys::repairable::repair_share_step_3(sigmas, identifier, commitment)
}
Loading

0 comments on commit c4021a4

Please sign in to comment.