Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion demo/protocol-demo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ license = { workspace = true }
repository = { workspace = true }

[dependencies]
blake2 = "0.10.6"
clap = { workspace = true }
hex = { workspace = true }
mithril-common = { path = "../../mithril-common" }
Expand Down
8 changes: 3 additions & 5 deletions demo/protocol-demo/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use mithril_stm::{
AggregateSignature, Clerk, Initializer, KeyRegistration, Parameters, Signer, SingleSignature,
Stake, VerificationKeyProofOfPossession,
AggregateSignature, Clerk, Initializer, KeyRegistration, MithrilMembershipDigest, Parameters,
Signer, SingleSignature, Stake, VerificationKeyProofOfPossession,
};

use blake2::{Blake2b, digest::consts::U32};

// Protocol types alias
type D = Blake2b<U32>;
type D = MithrilMembershipDigest;

/// The id of a mithril party.
pub type ProtocolPartyId = String;
Expand Down
12 changes: 4 additions & 8 deletions mithril-common/src/crypto_helper/cardano/key_certification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@
use std::{collections::HashMap, sync::Arc};

use anyhow::anyhow;
use blake2::{
Blake2b, Digest,
digest::{FixedOutput, consts::U32},
};
use kes_summed_ed25519::kes::Sum6KesSig;
use rand_core::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
use thiserror::Error;

use mithril_stm::{
ClosedKeyRegistration, Initializer, KeyRegistration, Parameters, RegisterError, Signer, Stake,
VerificationKeyProofOfPossession,
ClosedKeyRegistration, Initializer, KeyRegistration, MembershipDigest, MithrilMembershipDigest,
Parameters, RegisterError, Signer, Stake, VerificationKeyProofOfPossession,
};

use crate::{
Expand All @@ -33,7 +29,7 @@ use crate::{
};

// Protocol types alias
type D = Blake2b<U32>;
type D = MithrilMembershipDigest;

/// The KES period that is used to check if the KES keys is expired
pub type KesPeriod = u32;
Expand Down Expand Up @@ -285,7 +281,7 @@ impl KeyRegWrapper {

/// Finalize the key registration.
/// This function disables `ClosedKeyRegistration::register`, consumes the instance of `self`, and returns a `ClosedKeyRegistration`.
pub fn close<D: Digest + FixedOutput>(self) -> ClosedKeyRegistration<D> {
pub fn close<D: MembershipDigest>(self) -> ClosedKeyRegistration<D> {
self.stm_key_reg.close()
}
}
Expand Down
10 changes: 4 additions & 6 deletions mithril-common/src/crypto_helper/codec/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,15 @@ pub trait TryFromBytes: Sized {

mod binary_mithril_stm {
use anyhow::anyhow;
use blake2::Blake2b;

use digest::consts::U32;
use mithril_stm::{
AggregateSignature, AggregateVerificationKey, Initializer, Parameters, SingleSignature,
SingleSignatureWithRegisteredParty, VerificationKey, VerificationKeyProofOfPossession,
AggregateSignature, AggregateVerificationKey, Initializer, MithrilMembershipDigest,
Parameters, SingleSignature, SingleSignatureWithRegisteredParty, VerificationKey,
VerificationKeyProofOfPossession,
};

use super::*;

type D = Blake2b<U32>;
type D = MithrilMembershipDigest;

impl TryToBytes for Parameters {
fn to_bytes_vec(&self) -> StdResult<Vec<u8>> {
Expand Down
7 changes: 3 additions & 4 deletions mithril-common/src/crypto_helper/types/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ use crate::crypto_helper::cardano::{
};

use mithril_stm::{
AggregationError, Clerk, ClosedKeyRegistration, Index, Parameters, Signer, Stake,
AggregationError, Clerk, ClosedKeyRegistration, Index, MithrilMembershipDigest, Parameters,
Signer, Stake,
};

use blake2::{Blake2b, digest::consts::U32};

/// A protocol version
pub type ProtocolVersion<'a> = &'a str;

// Protocol types alias
pub(crate) type D = Blake2b<U32>;
pub(crate) type D = MithrilMembershipDigest;

/// The id of a mithril party.
pub type ProtocolPartyId = String;
Expand Down
6 changes: 6 additions & 0 deletions mithril-stm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.8.0 (12-17-2025)

### Changed

- The `D: Digest` generic is changed with a `D: MembershipDigest` trait supporting multiple hash functions for different proof systems.

## 0.7.0 (12-16-2025)

### Removed
Expand Down
2 changes: 1 addition & 1 deletion mithril-stm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-stm"
version = "0.7.0"
version = "0.8.0"
edition = { workspace = true }
authors = { workspace = true }
homepage = { workspace = true }
Expand Down
6 changes: 3 additions & 3 deletions mithril-stm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ use rayon::prelude::*;

use mithril_stm::{
AggregateSignatureType, AggregationError, Clerk, Initializer, KeyRegistration, Parameters,
Signer, SingleSignature,
Signer, SingleSignature, MithrilMembershipDigest,
};

type H = Blake2b<U32>;
type D = MithrilMembershipDigest;

let nparties = 32;
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
Expand Down Expand Up @@ -108,7 +108,7 @@ let closed_reg = key_reg.close();
let ps = ps
.into_par_iter()
.map(|p| p.create_signer(closed_reg.clone()).unwrap())
.collect::<Vec<Signer<H>>>();
.collect::<Vec<Signer<D>>>();

/////////////////////
// operation phase //
Expand Down
31 changes: 18 additions & 13 deletions mithril-stm/benches/size_benches.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
use blake2::digest::FixedOutput;
use blake2::{
Blake2b, Digest,
digest::consts::{U32, U64},
};
use blake2::{Blake2b, digest::consts::U64};
use rand_chacha::ChaCha20Rng;
use rand_core::{RngCore, SeedableRng};
use rayon::iter::ParallelIterator;
use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator};

use mithril_stm::{
AggregateSignatureType, Clerk, Initializer, KeyRegistration, Parameters, Signer,
SingleSignature,
AggregateSignatureType, Clerk, Initializer, KeyRegistration, MembershipDigest,
MithrilMembershipDigest, Parameters, Signer, SingleSignature,
};

fn size<H>(k: u64, m: u64, nparties: usize, hash_name: &str)
fn size<D>(k: u64, m: u64, nparties: usize, hash_name: &str)
where
H: Digest + Clone + Sync + Send + Default + FixedOutput,
D: MembershipDigest,
{
println!("+-------------------+");
println!("| Hash: {hash_name} |");
Expand All @@ -38,12 +34,12 @@ where
ps.push(p);
}

let closed_reg = key_reg.close::<H>();
let closed_reg = key_reg.close::<D>();

let ps = ps
.into_par_iter()
.map(|p| p.create_signer(closed_reg.clone()).unwrap())
.collect::<Vec<Signer<H>>>();
.collect::<Vec<Signer<D>>>();

let sigs = ps
.par_iter()
Expand All @@ -65,6 +61,15 @@ where
aggr.to_bytes().len(),
);
}
/// Only for size benches
#[derive(Clone, Debug, Default)]
pub struct MembershipDigestU64 {}

impl MembershipDigest for MembershipDigestU64 {
type ConcatenationHash = Blake2b<U64>;
#[cfg(feature = "future_snark")]
type SnarkHash = Blake2b<U64>;
}

fn main() {
println!("+-------------------+");
Expand All @@ -75,8 +80,8 @@ fn main() {

let params: [(u64, u64, usize); 2] = [(445, 2728, 3000), (554, 3597, 3000)];
for (k, m, nparties) in params {
size::<Blake2b<U64>>(k, m, nparties, "Blake2b 512");
size::<Blake2b<U32>>(k, m, nparties, "Blake2b 256");
size::<MembershipDigestU64>(k, m, nparties, "Blake2b 512");
size::<MithrilMembershipDigest>(k, m, nparties, "Blake2b 256");
}
println!("+-------------------------+");
}
36 changes: 17 additions & 19 deletions mithril-stm/benches/stm.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
use std::fmt::Debug;

use blake2::digest::{Digest, FixedOutput};
use blake2::{Blake2b, digest::consts::U32};
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use rand_chacha::ChaCha20Rng;
use rand_core::{RngCore, SeedableRng};
use rayon::prelude::*;

use mithril_stm::{
AggregateSignature, AggregateSignatureType, Clerk, Initializer, KeyRegistration, Parameters,
Signer,
AggregateSignature, AggregateSignatureType, Clerk, Initializer, KeyRegistration,
MembershipDigest, MithrilMembershipDigest, Parameters, Signer,
};

/// This benchmark framework is not ideal. We really have to think what is the best mechanism for
/// benchmarking these signatures, over which parameters, how many times to run them, etc:
/// * Registration depends on the number of parties (should be constant, as it is a lookup table)
/// * Signing depends on the parameter `m`, as it defines the number of lotteries a user can play
/// * Aggregation depends on `k`.
fn stm_benches<H>(c: &mut Criterion, nr_parties: usize, params: Parameters, hashing_alg: &str)
where
H: Clone + Debug + Digest + Send + Sync + FixedOutput + Default,
{
fn stm_benches<D: MembershipDigest>(
c: &mut Criterion,
nr_parties: usize,
params: Parameters,
hashing_alg: &str,
) {
let mut group = c.benchmark_group(format!("STM/{hashing_alg}"));
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let mut msg = [0u8; 16];
Expand Down Expand Up @@ -55,10 +53,10 @@ where

let closed_reg = key_reg.close();

let signers = initializers
let signers: Vec<Signer<D>> = initializers
.into_par_iter()
.map(|p| p.create_signer(closed_reg.clone()).unwrap())
.collect::<Vec<Signer<H>>>();
.collect();

group.bench_function(BenchmarkId::new("Play all lotteries", &param_string), |b| {
b.iter(|| {
Expand All @@ -76,14 +74,14 @@ where
});
}

fn batch_benches<H>(
fn batch_benches<D>(
c: &mut Criterion,
array_batches: &[usize],
nr_parties: usize,
params: Parameters,
hashing_alg: &str,
) where
H: Clone + Debug + Digest + FixedOutput + Send + Sync,
D: MembershipDigest,
{
let mut group = c.benchmark_group(format!("STM/{hashing_alg}"));
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
Expand Down Expand Up @@ -127,7 +125,7 @@ fn batch_benches<H>(
let signers = initializers
.into_par_iter()
.map(|p| p.create_signer(closed_reg.clone()).unwrap())
.collect::<Vec<Signer<H>>>();
.collect::<Vec<Signer<D>>>();

let sigs = signers.par_iter().filter_map(|p| p.sign(&msg)).collect::<Vec<_>>();

Expand Down Expand Up @@ -156,7 +154,7 @@ fn batch_benches<H>(
}

fn batch_stm_benches_blake_300(c: &mut Criterion) {
batch_benches::<Blake2b<U32>>(
batch_benches::<MithrilMembershipDigest>(
c,
&[1, 10, 20, 100],
300,
Expand All @@ -170,7 +168,7 @@ fn batch_stm_benches_blake_300(c: &mut Criterion) {
}

fn stm_benches_blake_300(c: &mut Criterion) {
stm_benches::<Blake2b<U32>>(
stm_benches::<MithrilMembershipDigest>(
c,
300,
Parameters {
Expand All @@ -183,7 +181,7 @@ fn stm_benches_blake_300(c: &mut Criterion) {
}

fn batch_stm_benches_blake_2000(c: &mut Criterion) {
batch_benches::<Blake2b<U32>>(
batch_benches::<MithrilMembershipDigest>(
c,
&[1, 10, 20, 100],
2000,
Expand All @@ -197,7 +195,7 @@ fn batch_stm_benches_blake_2000(c: &mut Criterion) {
}

fn stm_benches_blake_2000(c: &mut Criterion) {
stm_benches::<Blake2b<U32>>(
stm_benches::<MithrilMembershipDigest>(
c,
2000,
Parameters {
Expand Down
9 changes: 4 additions & 5 deletions mithril-stm/examples/key_registration.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
//! This example shows how Key Registration is held. It is not held by a single central party,
//! but instead by all the participants in the signature process. Contrarily to the full protocol
//! run presented in `tests/integration.rs`, we explicitly treat each party individually.
use blake2::{Blake2b, digest::consts::U32};
use rand_chacha::ChaCha20Rng;
use rand_core::{RngCore, SeedableRng};

use mithril_stm::{
AggregateSignatureType, Clerk, ClosedKeyRegistration, Initializer, KeyRegistration, Parameters,
Stake, VerificationKeyProofOfPossession,
AggregateSignatureType, Clerk, ClosedKeyRegistration, Initializer, KeyRegistration,
MithrilMembershipDigest, Parameters, Stake, VerificationKeyProofOfPossession,
};

type H = Blake2b<U32>;
type D = MithrilMembershipDigest;

fn main() {
let nparties = 4;
Expand Down Expand Up @@ -142,7 +141,7 @@ fn main() {
assert!(msig_3.is_err());
}

fn local_reg(ids: &[u64], pks: &[VerificationKeyProofOfPossession]) -> ClosedKeyRegistration<H> {
fn local_reg(ids: &[u64], pks: &[VerificationKeyProofOfPossession]) -> ClosedKeyRegistration<D> {
let mut local_keyreg = KeyRegistration::init();
// data, such as the public key, stake and id.
for (&pk, id) in pks.iter().zip(ids.iter()) {
Expand Down
Loading