Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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 `Digest` generic is changed with a 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
4 changes: 2 additions & 2 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 H = MithrilMembershipDigest;

let nparties = 32;
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
Expand Down
25 changes: 15 additions & 10 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)
where
H: Digest + Clone + Sync + Send + Default + FixedOutput,
H: MembershipDigest,
{
println!("+-------------------+");
println!("| Hash: {hash_name} |");
Expand Down Expand Up @@ -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!("+-------------------------+");
}
32 changes: 15 additions & 17 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<H: 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<H>> = 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 @@ -83,7 +81,7 @@ fn batch_benches<H>(
params: Parameters,
hashing_alg: &str,
) where
H: Clone + Debug + Digest + FixedOutput + Send + Sync,
H: MembershipDigest,
{
let mut group = c.benchmark_group(format!("STM/{hashing_alg}"));
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
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
7 changes: 3 additions & 4 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 H = MithrilMembershipDigest;

fn main() {
let nparties = 4;
Expand Down
30 changes: 28 additions & 2 deletions mithril-stm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
//!
//! use mithril_stm::{
//! AggregateSignatureType, AggregationError, Clerk, Initializer, KeyRegistration, Parameters,
//! Signer, SingleSignature,
//! Signer, SingleSignature, MithrilMembershipDigest
//! };
//!
//! let nparties = 4; // Use a small number of parties for this example
//! type D = Blake2b<U32>; // Setting the hash function for convenience
//! type D = MithrilMembershipDigest; // Setting the hash function for convenience
//!
//! let mut rng = ChaCha20Rng::from_seed([0u8; 32]); // create and initialize rng
//! let mut msg = [0u8; 16]; // setting an arbitrary message
Expand Down Expand Up @@ -128,6 +128,12 @@ pub use signature_scheme::{
#[cfg(all(feature = "benchmark-internals", feature = "future_snark"))]
pub use signature_scheme::{SchnorrSignature, SchnorrSigningKey, SchnorrVerificationKey};

#[cfg(feature = "future_snark")]
use blake2::digest::consts::U64;
use blake2::{Blake2b, digest::consts::U32};
use digest::{Digest, FixedOutput};
use std::fmt::Debug;

/// The quantity of stake held by a party, represented as a `u64`.
pub type Stake = u64;

Expand All @@ -140,3 +146,23 @@ pub type StmError = anyhow::Error;

/// Mithril-stm result type
pub type StmResult<T> = anyhow::Result<T, StmError>;

/// Trait defining the different hash types for different proof systems.
pub trait MembershipDigest: Clone {
type ConcatenationHash: Digest + FixedOutput + Clone + Debug + Send + Sync;
#[cfg(feature = "future_snark")]
type SnarkHash: Digest + FixedOutput + Clone + Debug + Send + Sync;
}

/// Default Mithril Membership Digest
#[derive(Clone, Debug, Default)]
pub struct MithrilMembershipDigest {}

/// Default implementation of MembershipDigest for Mithril
/// TODO: `SnarkHash` will be changed with Poseidon. For now, we use `Blake2b<U64>` (`U64` is set
/// for having something different than the `ConcatenationHash`) as a placeholder.
impl MembershipDigest for MithrilMembershipDigest {
type ConcatenationHash = Blake2b<U32>;
#[cfg(feature = "future_snark")]
type SnarkHash = Blake2b<U64>;
}
Loading