Crate frost_ed448

Crate frost_ed448 

Source
Expand description

An implementation of Schnorr signatures on the Ed448 curve for both single and threshold numbers of signers (FROST).

§Example: key generation with trusted dealer and FROST signing

Creating a key with a trusted dealer and splitting into shares; then signing a message and aggregating the signature. Note that the example just simulates a distributed scenario in a single thread and it abstracts away any communication between peers.

use frost_ed448 as frost;
use std::collections::BTreeMap;

let mut rng = rand::rngs::OsRng;
let max_signers = 5;
let min_signers = 3;
let (shares, pubkey_package) = frost::keys::generate_with_dealer(
    max_signers,
    min_signers,
    frost::keys::IdentifierList::Default,
    &mut rng,
)?;

// 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: BTreeMap<_, _> = BTreeMap::new();

for (identifier, secret_share) in shares {
    let key_package = frost::keys::KeyPackage::try_from(secret_share)?;
    key_packages.insert(identifier, key_package);
}

let mut nonces_map = BTreeMap::new();
let mut commitments_map = BTreeMap::new();

////////////////////////////////////////////////////////////////////////////
// Round 1: generating nonces and signing commitments for each participant
////////////////////////////////////////////////////////////////////////////

// In practice, each iteration of this loop will be executed by its respective participant.
for participant_index in 1..=min_signers {
    let participant_identifier = participant_index.try_into().expect("should be nonzero");
    let key_package = &key_packages[&participant_identifier];
    // Generate one (1) nonce and one SigningCommitments instance for each
    // participant, up to _threshold_.
    let (nonces, commitments) = frost::round1::commit(
        key_package.signing_share(),
        &mut rng,
    );
    // In practice, the nonces must be kept by the participant to use in the
    // next round, while the commitment must be sent to the coordinator
    // (or to every other participant if there is no coordinator) using
    // an authenticated channel.
    nonces_map.insert(participant_identifier, nonces);
    commitments_map.insert(participant_identifier, commitments);
}

// 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 = BTreeMap::new();
let message = "message to sign".as_bytes();
let signing_package = frost::SigningPackage::new(commitments_map, message);

////////////////////////////////////////////////////////////////////////////
// Round 2: each participant generates their signature share
////////////////////////////////////////////////////////////////////////////

// In practice, each iteration of this loop will be executed by its respective participant.
for participant_identifier in nonces_map.keys() {
    let key_package = &key_packages[participant_identifier];

    let nonces = &nonces_map[participant_identifier];

    // Each participant generates their signature share.
    let signature_share = frost::round2::sign(&signing_package, nonces, key_package)?;

    // In practice, the signature share must be sent to the Coordinator
    // using an authenticated channel.
    signature_shares.insert(*participant_identifier, signature_share);
}

////////////////////////////////////////////////////////////////////////////
// Aggregation: collects the signing shares from all participants,
// generates the final signature.
////////////////////////////////////////////////////////////////////////////

// Aggregate (also verifies the signature shares)
let group_signature = frost::aggregate(&signing_package, &signature_shares, &pubkey_package)?;


// Check that the threshold signature can be verified by the group public
// key (the verification key).
let is_signature_valid = pubkey_package
    .verifying_key()
    .verify(message, &group_signature)
    .is_ok();
assert!(is_signature_valid);

§Features

  • serde (enabled by default) — Enable serde support for types that need to be communicated. You can use serde to serialize structs with any encoder that supports serde (e.g. JSON with serde_json).
  • serialization (enabled by default) — Enable a default serialization format. Enables serde.
  • cheater-detection (enabled by default) — Enable cheater detection

Re-exports§

pub use frost_core::serde;serde
pub use rand_core;

Modules§

keys
FROST(Ed448, SHAKE256) keys, key generation, key shares.
round1
FROST(Ed448, SHAKE256) Round 1 functionality and types.
round2
FROST(Ed448, SHAKE256) Round 2 functionality and types, for signature share generation.

Structs§

Ed448Group
An implementation of the FROST(Ed448, SHAKE256) ciphersuite group.
Ed448ScalarField
An implementation of the FROST(Ed448, SHAKE256) ciphersuite scalar field.
Ed448Shake256
An implementation of the FROST(Ed448, SHAKE256) ciphersuite.

Enums§

FieldError
An error related to a scalar Field.
GroupError
An error related to a Group (usually an elliptic curve or constructed from one) or one of its Elements.

Traits§

Ciphersuite
A FROST ciphersuite specifies the underlying prime-order group details and cryptographic hash function.
Field
A prime order finite field GF(q) over which all scalar values for our prime order group can be multiplied are defined.
Group
A prime-order group (or subgroup) that provides everything we need to create and verify Schnorr signatures.

Functions§

aggregate
Verifies each FROST(Ed448, SHAKE256) participant’s signature share, and if all are valid, aggregates the shares into a signature to publish.

Type Aliases§

Error
An error.
Identifier
A FROST(Ed448, SHAKE256) participant identifier.
Signature
A Schnorr signature on FROST(Ed448, SHAKE256).
SigningKey
A signing key for a Schnorr signature on FROST(Ed448, SHAKE256).
SigningPackage
Generated by the coordinator of the signing operation and distributed to each signing party.
VerifyingKey
A valid verifying key for Schnorr signatures on FROST(Ed448, SHAKE256).