Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Cargo.lock

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

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.7.0 (12-16-2025)

### Removed

- Basic verifier functionality is removed.

## 0.6.4 (12-12-2025)

### Changed
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.6.4"
version = "0.7.0"
edition = { workspace = true }
authors = { workspace = true }
homepage = { workspace = true }
Expand Down
75 changes: 2 additions & 73 deletions mithril-stm/benches/size_benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use rayon::iter::ParallelIterator;
use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator};

use mithril_stm::{
AggregateSignatureType, BasicVerifier, Clerk, Initializer, KeyRegistration, Parameters, Signer,
SingleSignature, SingleSignatureWithRegisteredParty, Stake, VerificationKey,
AggregateSignatureType, Clerk, Initializer, KeyRegistration, Parameters, Signer,
SingleSignature,
};

fn size<H>(k: u64, m: u64, nparties: usize, hash_name: &str)
Expand Down Expand Up @@ -66,68 +66,6 @@ where
);
}

fn core_size<H>(k: u64, m: u64, nparties: usize)
where
H: Digest + Clone + Sync + Send + Default + FixedOutput,
{
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let mut msg = [0u8; 16];
rng.fill_bytes(&mut msg);

let mut public_signers: Vec<(VerificationKey, Stake)> = Vec::with_capacity(nparties);
let mut initializers: Vec<Initializer> = Vec::with_capacity(nparties);

let parties = (0..nparties).map(|_| 1 + (rng.next_u64() % 9999)).collect::<Vec<_>>();

let params = Parameters { k, m, phi_f: 0.2 };

for stake in parties {
let initializer = Initializer::new(params, stake, &mut rng);
initializers.push(initializer.clone());
public_signers.push((
initializer.get_verification_key_proof_of_possession().vk,
initializer.stake,
));
}

let core_verifier = BasicVerifier::new(&public_signers);

let signers: Vec<Signer<H>> = initializers
.into_iter()
.filter_map(|s| s.create_basic_signer(&core_verifier.eligible_parties))
.collect();

let mut signatures: Vec<SingleSignature> = Vec::with_capacity(nparties);
for s in signers {
if let Some(sig) = s.basic_sign(&msg, core_verifier.total_stake) {
signatures.push(sig);
}
}

let sig_reg_list = signatures
.iter()
.map(|sig| SingleSignatureWithRegisteredParty {
sig: sig.clone(),
reg_party: core_verifier.eligible_parties[sig.signer_index as usize],
})
.collect::<Vec<SingleSignatureWithRegisteredParty>>();

let dedup_sigs = BasicVerifier::select_valid_signatures_for_k_indices(
&core_verifier.total_stake,
&params,
&msg,
&sig_reg_list,
)
.unwrap();

let mut size_sigs: usize = 0;
for sig in dedup_sigs {
size_sigs += sig.to_bytes().len();
}

println!("k = {k} | m = {m} | nr parties = {nparties}; {size_sigs} bytes",);
}

fn main() {
println!("+-------------------+");
println!("| Size of proofs |");
Expand All @@ -140,14 +78,5 @@ fn main() {
size::<Blake2b<U64>>(k, m, nparties, "Blake2b 512");
size::<Blake2b<U32>>(k, m, nparties, "Blake2b 256");
}

println!("\n+-------------------------+");
println!("| Size of core signatures |");
println!("+-------------------------+");
println!("+-------------------------+");

for (k, m, nparties) in params {
core_size::<Blake2b<U64>>(k, m, nparties);
}
println!("+-------------------------+");
}
83 changes: 2 additions & 81 deletions mithril-stm/benches/stm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use rand_core::{RngCore, SeedableRng};
use rayon::prelude::*;

use mithril_stm::{
AggregateSignature, AggregateSignatureType, BasicVerifier, Clerk, Initializer, KeyRegistration,
Parameters, Signer, Stake, VerificationKey,
AggregateSignature, AggregateSignatureType, Clerk, Initializer, KeyRegistration, Parameters,
Signer,
};

/// This benchmark framework is not ideal. We really have to think what is the best mechanism for
Expand Down Expand Up @@ -155,59 +155,6 @@ fn batch_benches<H>(
}
}

fn basic_verifier_benches<H>(c: &mut Criterion, nr_parties: usize, params: Parameters)
where
H: Clone + Debug + Digest + Send + Sync + FixedOutput + Default,
{
let mut group = c.benchmark_group("Core verifier");
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let mut msg = [0u8; 16];
rng.fill_bytes(&mut msg);

let mut public_signers: Vec<(VerificationKey, Stake)> = Vec::with_capacity(nr_parties);
let mut initializers: Vec<Initializer> = Vec::with_capacity(nr_parties);

let param_string = format!(
"k: {}, m: {}, nr_parties: {}",
params.k, params.m, nr_parties
);

let stakes = (0..nr_parties)
.map(|_| 1 + (rng.next_u64() % 9999))
.collect::<Vec<_>>();

for stake in stakes {
let initializer = Initializer::new(params, stake, &mut rng);
initializers.push(initializer.clone());
public_signers.push((
initializer.get_verification_key_proof_of_possession().vk,
initializer.stake,
));
}

let core_verifier = BasicVerifier::new(&public_signers);

let signers: Vec<Signer<H>> = initializers
.into_iter()
.filter_map(|s| s.create_basic_signer(&core_verifier.eligible_parties))
.collect();

group.bench_function(BenchmarkId::new("Play all lotteries", &param_string), |b| {
b.iter(|| {
signers[0].basic_sign(&msg, core_verifier.total_stake);
})
});

let signatures = signers
.par_iter()
.filter_map(|p| p.basic_sign(&msg, core_verifier.total_stake))
.collect::<Vec<_>>();

group.bench_function(BenchmarkId::new("Core verification", &param_string), |b| {
b.iter(|| core_verifier.verify(&signatures, &params, &msg))
});
}

fn batch_stm_benches_blake_300(c: &mut Criterion) {
batch_benches::<Blake2b<U32>>(
c,
Expand Down Expand Up @@ -235,18 +182,6 @@ fn stm_benches_blake_300(c: &mut Criterion) {
);
}

fn core_verifier_benches_blake_300(c: &mut Criterion) {
basic_verifier_benches::<Blake2b<U32>>(
c,
300,
Parameters {
m: 150,
k: 25,
phi_f: 0.2,
},
);
}

fn batch_stm_benches_blake_2000(c: &mut Criterion) {
batch_benches::<Blake2b<U32>>(
c,
Expand Down Expand Up @@ -274,23 +209,9 @@ fn stm_benches_blake_2000(c: &mut Criterion) {
);
}

fn core_verifier_benches_blake_2000(c: &mut Criterion) {
basic_verifier_benches::<Blake2b<U32>>(
c,
2000,
Parameters {
m: 1523,
k: 250,
phi_f: 0.2,
},
);
}

criterion_group!(name = benches;
config = Criterion::default().nresamples(1000);
targets =
core_verifier_benches_blake_300,
core_verifier_benches_blake_2000,
stm_benches_blake_300,
stm_benches_blake_2000,
batch_stm_benches_blake_300,
Expand Down
81 changes: 58 additions & 23 deletions mithril-stm/src/proof_system/concatenation.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use anyhow::Context;
use anyhow::{Context, anyhow};
use blake2::digest::{Digest, FixedOutput};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;

use crate::{
AggregateSignatureError, AggregateVerificationKey, BasicVerifier, Clerk, Parameters,
AggregateSignatureError, AggregateVerificationKey, AggregationError, Clerk, Parameters,
RegisteredParty, SingleSignature, SingleSignatureWithRegisteredParty, StmResult,
membership_commitment::MerkleBatchPath,
signature_scheme::{BlsSignature, BlsVerificationKey},
Expand Down Expand Up @@ -43,17 +44,12 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
})
.collect::<Vec<SingleSignatureWithRegisteredParty>>();

let avk = AggregateVerificationKey::from(&clerk.closed_reg);
let msgp = avk.get_merkle_tree_batch_commitment().concatenate_with_message(msg);
let mut unique_sigs = BasicVerifier::select_valid_signatures_for_k_indices(
&clerk.closed_reg.total_stake,
&clerk.params,
&msgp,
&sig_reg_list,
)
.with_context(
|| "Failed to aggregate unique signatures during selection for the k indices.",
)?;
let avk = clerk.compute_aggregate_verification_key();
let mut unique_sigs =
Clerk::select_valid_signatures_for_k_indices(&clerk.params, msg, &sig_reg_list, &avk)
.with_context(
|| "Failed to aggregate unique signatures during selection for the k indices.",
)?;

unique_sigs.sort_unstable();

Expand Down Expand Up @@ -86,13 +82,35 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
parameters: &Parameters,
) -> StmResult<(Vec<BlsSignature>, Vec<BlsVerificationKey>)> {
let msgp = avk.get_merkle_tree_batch_commitment().concatenate_with_message(msg);
BasicVerifier::preliminary_verify(
&avk.get_total_stake(),
&self.signatures,
parameters,
&msgp,
)
.with_context(|| "Preliminary verification of aggregate signatures failed.")?;

let mut nr_indices = 0;
let mut unique_indices = HashSet::new();

for sig_reg in self.signatures.clone() {
sig_reg
.sig
.check_indices(
parameters,
&sig_reg.reg_party.1,
&msgp,
&avk.get_total_stake(),
)
.with_context(|| "Preliminary verification for basic verifier failed.")?;
for &index in &sig_reg.sig.indexes {
unique_indices.insert(index);
nr_indices += 1;
}
}

if nr_indices != unique_indices.len() {
return Err(anyhow!(AggregationError::IndexNotUnique));
}
if (nr_indices as u64) < parameters.k {
return Err(anyhow!(AggregationError::NotEnoughSignatures(
nr_indices as u64,
parameters.k
)));
}

let leaves = self
.signatures
Expand All @@ -104,9 +122,7 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
.verify_leaves_membership_from_batch_path(&leaves, &self.batch_proof)
.with_context(|| "Batch proof is invalid in preliminary verification.")?;

Ok(BasicVerifier::collect_signatures_verification_keys(
&self.signatures,
))
Ok(self.collect_signatures_verification_keys())
}

/// Verify concatenation proof, by checking that
Expand Down Expand Up @@ -243,4 +259,23 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
batch_proof,
})
}

/// Collect and return `Vec<BlsSignature>, Vec<BlsVerificationKey>` which will be used
/// by the aggregate verification.
pub(crate) fn collect_signatures_verification_keys(
&self,
) -> (Vec<BlsSignature>, Vec<BlsVerificationKey>) {
let sigs = self
.signatures
.iter()
.map(|sig_reg| sig_reg.sig.sigma)
.collect::<Vec<BlsSignature>>();
let vks = self
.signatures
.iter()
.map(|sig_reg| sig_reg.reg_party.0)
.collect::<Vec<BlsVerificationKey>>();

(sigs, vks)
}
}
Loading
Loading