mithril_stm/
lib.rs

1#![doc = include_str!("../README.md")]
2//! Implementation of Stake-based Threshold Multisignatures
3//! Top-level API for Mithril Stake-based Threshold Multisignature scheme.
4//! See figure 6 of [the paper](https://eprint.iacr.org/2021/916) for most of the
5//! protocol.
6//!
7//! What follows is a simple example showing the usage of STM.
8//!
9//! ```rust
10//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
11//! use blake2::{Blake2b, digest::consts::U32};
12//! use rand_chacha::ChaCha20Rng;
13//! use rand_core::{RngCore, SeedableRng};
14//! use rayon::prelude::*; // We use par_iter to speed things up
15//!
16//! use mithril_stm::{StmClerk, StmParameters, StmSig, KeyReg, StmInitializer, StmSigner, AggregationError};
17//!
18//! let nparties = 4; // Use a small number of parties for this example
19//! type D = Blake2b<U32>; // Setting the hash function for convenience
20//!
21//! let mut rng = ChaCha20Rng::from_seed([0u8; 32]); // create and initialize rng
22//! let mut msg = [0u8; 16]; // setting an arbitrary message
23//! rng.fill_bytes(&mut msg);
24//!
25//! // In the following, we will have 4 parties try to sign `msg`, then aggregate and
26//! // verify those signatures.
27//!
28//! //////////////////////////
29//! // initialization phase //
30//! //////////////////////////
31//!
32//! // Set low parameters for testing
33//! // XXX: not for production
34//! let params = StmParameters {
35//!     m: 100, // Security parameter XXX: not for production
36//!     k: 2, // Quorum parameter XXX: not for production
37//!     phi_f: 0.2, // Lottery parameter XXX: not for production
38//! };
39//!
40//! // Generate some arbitrary stake for each party
41//! // Stake is an integer.
42//! // Total stake of all parties is total stake in the system.
43//! let stakes = (0..nparties)
44//!     .into_iter()
45//!     .map(|_| 1 + (rng.next_u64() % 9999))
46//!     .collect::<Vec<_>>();
47//!
48//! // Create a new key registry from the parties and their stake
49//! let mut key_reg = KeyReg::init();
50//!
51//! // For each party, crate a StmInitializer.
52//! // This struct can create keys for the party.
53//! let mut ps: Vec<StmInitializer> = Vec::with_capacity(nparties);
54//! for stake in stakes {
55//!     // Create keys for this party
56//!     let p = StmInitializer::setup(params, stake, &mut rng);
57//!     // Register keys with the KeyReg service
58//!     key_reg
59//!         .register(p.stake, p.verification_key())
60//!         .unwrap();
61//!     ps.push(p);
62//! }
63//!
64//! // Close the key registration.
65//! let closed_reg = key_reg.close();
66//!
67//! // Finalize the StmInitializer and turn it into a StmSigner, which can execute the
68//! // rest of the protocol.
69//! let ps = ps
70//!     .into_par_iter()
71//!     .map(|p| p.new_signer(closed_reg.clone()).unwrap())
72//!     .collect::<Vec<StmSigner<D>>>();
73//!
74//! /////////////////////
75//! // operation phase //
76//! /////////////////////
77//!
78//! // Next, each party tries to sign the message for each index available.
79//! // We collect the successful signatures into a vec.
80//! let sigs = ps
81//!     .par_iter()
82//!     .filter_map(|p| {
83//!         return p.sign(&msg);
84//!     })
85//!     .collect::<Vec<StmSig>>();
86//!
87//! // StmClerk can aggregate and verify signatures.
88//! let clerk = StmClerk::from_signer(&ps[0]);
89//!
90//! // Aggregate and verify the signatures
91//! let msig = clerk.aggregate(&sigs, &msg);
92//! match msig {
93//!     Ok(aggr) => {
94//!         println!("Aggregate ok");
95//!         assert!(aggr
96//!             .verify(&msg, &clerk.compute_avk(), &params)
97//!             .is_ok());
98//!     }
99//!     Err(AggregationError::NotEnoughSignatures(n, k)) => {
100//!         println!("Not enough signatures");
101//!         assert!(n < params.k && k == params.k)
102//!     }
103//!     Err(_) => unreachable!(),
104//! }
105//! # Ok(())
106//! # }
107//! ```
108
109mod aggregate_signature;
110mod bls_multi_signature;
111mod eligibility_check;
112mod error;
113mod key_reg;
114mod merkle_tree;
115mod parameters;
116mod participant;
117mod single_signature;
118
119pub use aggregate_signature::{CoreVerifier, StmAggrSig, StmAggrVerificationKey, StmClerk};
120pub use error::{
121    AggregationError, CoreVerifierError, RegisterError, StmAggregateSignatureError,
122    StmSignatureError,
123};
124pub use key_reg::{ClosedKeyReg, KeyReg};
125pub use parameters::StmParameters;
126pub use participant::{StmInitializer, StmSigner, StmVerificationKey, StmVerificationKeyPoP};
127pub use single_signature::{StmSig, StmSigRegParty};
128
129#[cfg(feature = "benchmark-internals")]
130pub use bls_multi_signature::{
131    ProofOfPossession, Signature, SigningKey, VerificationKey, VerificationKeyPoP,
132};
133
134/// The quantity of stake held by a party, represented as a `u64`.
135pub type Stake = u64;
136
137/// Quorum index for signatures.
138/// An aggregate signature (`StmMultiSig`) must have at least `k` unique indices.
139pub type Index = u64;