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::{
17//! AggregateSignatureType, AggregationError, Clerk, Initializer, KeyRegistration, Parameters,
18//! Signer, SingleSignature,
19//! };
20//!
21//! let nparties = 4; // Use a small number of parties for this example
22//! type D = Blake2b<U32>; // Setting the hash function for convenience
23//!
24//! let mut rng = ChaCha20Rng::from_seed([0u8; 32]); // create and initialize rng
25//! let mut msg = [0u8; 16]; // setting an arbitrary message
26//! rng.fill_bytes(&mut msg);
27//!
28//! // In the following, we will have 4 parties try to sign `msg`, then aggregate and
29//! // verify those signatures.
30//!
31//! //////////////////////////
32//! // initialization phase //
33//! //////////////////////////
34//!
35//! // Set low parameters for testing
36//! // XXX: not for production
37//! let params = Parameters {
38//! m: 100, // Security parameter XXX: not for production
39//! k: 2, // Quorum parameter XXX: not for production
40//! phi_f: 0.2, // Lottery parameter XXX: not for production
41//! };
42//!
43//! // Generate some arbitrary stake for each party
44//! // Stake is an integer.
45//! // Total stake of all parties is total stake in the system.
46//! let stakes = (0..nparties)
47//! .into_iter()
48//! .map(|_| 1 + (rng.next_u64() % 9999))
49//! .collect::<Vec<_>>();
50//!
51//! // Create a new key registry from the parties and their stake
52//! let mut key_reg = KeyRegistration::init();
53//!
54//! // For each party, crate a Initializer.
55//! // This struct can create keys for the party.
56//! let mut ps: Vec<Initializer> = Vec::with_capacity(nparties);
57//! for stake in stakes {
58//! // Create keys for this party
59//! let p = Initializer::new(params, stake, &mut rng);
60//! // Register keys with the KeyRegistration service
61//! key_reg
62//! .register(p.stake, p.verification_key())
63//! .unwrap();
64//! ps.push(p);
65//! }
66//!
67//! // Close the key registration.
68//! let closed_reg = key_reg.close();
69//!
70//! // Finalize the Initializer and turn it into a Signer, which can execute the
71//! // rest of the protocol.
72//! let ps = ps
73//! .into_par_iter()
74//! .map(|p| p.new_signer(closed_reg.clone()).unwrap())
75//! .collect::<Vec<Signer<D>>>();
76//!
77//! /////////////////////
78//! // operation phase //
79//! /////////////////////
80//!
81//! // Next, each party tries to sign the message for each index available.
82//! // We collect the successful signatures into a vec.
83//! let sigs = ps
84//! .par_iter()
85//! .filter_map(|p| {
86//! return p.sign(&msg);
87//! })
88//! .collect::<Vec<SingleSignature>>();
89//!
90//! // Clerk can aggregate and verify signatures.
91//! let clerk = Clerk::from_signer(&ps[0]);
92//!
93//! // Aggregate and verify the signatures
94//! let msig = clerk.aggregate(&sigs, &msg);
95//! match msig {
96//! Ok(aggr) => {
97//! println!("Aggregate ok");
98//! assert!(aggr
99//! .verify(&msg, &clerk.compute_avk(), ¶ms)
100//! .is_ok());
101//! }
102//! Err(error) => assert!(
103//! matches!(
104//! error.downcast_ref::<AggregationError>(),
105//! Some(AggregationError::NotEnoughSignatures { .. })
106//! ),
107//! "Unexpected error: {error}"
108//! ),
109//! }
110//! # Ok(())
111//! # }
112//! ```
113
114mod aggregate_signature;
115mod bls_multi_signature;
116mod eligibility_check;
117mod error;
118mod key_registration;
119mod merkle_tree;
120mod parameters;
121mod participant;
122mod single_signature;
123
124pub use aggregate_signature::{
125 AggregateSignature, AggregateSignatureType, AggregateVerificationKey, BasicVerifier, Clerk,
126};
127pub use error::{
128 AggregateSignatureError, AggregationError, MultiSignatureError, RegisterError, SignatureError,
129};
130pub use key_registration::{ClosedKeyRegistration, KeyRegistration};
131pub use parameters::Parameters;
132pub use participant::{Initializer, Signer, VerificationKey, VerificationKeyProofOfPossession};
133pub use single_signature::{SingleSignature, SingleSignatureWithRegisteredParty};
134
135#[cfg(feature = "benchmark-internals")]
136pub use bls_multi_signature::{
137 BlsProofOfPossession, BlsSignature, BlsSigningKey, BlsVerificationKey,
138 BlsVerificationKeyProofOfPossession,
139};
140
141/// The quantity of stake held by a party, represented as a `u64`.
142pub type Stake = u64;
143
144/// Quorum index for signatures.
145/// An aggregate signature (`StmMultiSig`) must have at least `k` unique indices.
146pub type Index = u64;
147
148/// Mithril-stm error type
149pub type StmError = anyhow::Error;
150
151/// Mithril-stm result type
152pub type StmResult<T> = anyhow::Result<T, StmError>;
153
154// Aliases
155#[deprecated(since = "0.5.0", note = "Use `AggregateSignature` instead")]
156pub use aggregate_signature::AggregateSignature as StmAggrSig;
157
158#[deprecated(since = "0.5.0", note = "Use `AggregateVerificationKey` instead")]
159pub use aggregate_signature::AggregateVerificationKey as StmAggrVerificationKey;
160
161#[deprecated(since = "0.5.0", note = "Use `Clerk` instead")]
162pub use aggregate_signature::Clerk as StmClerk;
163
164#[deprecated(since = "0.5.0", note = "Use `ClosedKeyRegistration` instead")]
165pub use key_registration::ClosedKeyRegistration as ClosedKeyReg;
166
167#[deprecated(since = "0.5.0", note = "Use `KeyRegistration` instead")]
168pub use key_registration::KeyRegistration as KeyReg;
169
170#[deprecated(since = "0.5.0", note = "Use `Parameters` instead")]
171pub use parameters::Parameters as StmParameters;
172
173#[deprecated(since = "0.5.0", note = "Use `Initializer` instead")]
174pub use participant::Initializer as StmInitializer;
175
176#[deprecated(since = "0.5.0", note = "Use `Signer` instead")]
177pub use participant::Signer as StmSigner;
178
179#[deprecated(since = "0.5.0", note = "Use `VerificationKey` instead")]
180pub use participant::VerificationKey as StmVerificationKey;
181
182#[deprecated(
183 since = "0.5.0",
184 note = "Use `VerificationKeyProofOfPossession` instead"
185)]
186pub use participant::VerificationKeyProofOfPossession as StmVerificationKeyPoP;
187
188#[deprecated(since = "0.5.0", note = "Use `SingleSignature` instead")]
189pub use single_signature::SingleSignature as StmSig;
190
191#[deprecated(since = "0.5.0", note = "Use `BasicVerifier` instead")]
192pub use aggregate_signature::BasicVerifier as CoreVerifier;
193
194#[deprecated(
195 since = "0.5.0",
196 note = "Use `SingleSignatureWithRegisteredParty` instead"
197)]
198pub use single_signature::SingleSignatureWithRegisteredParty as StmSigRegParty;