Skip to content
Draft
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
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions mithril-stm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ benchmark-internals = [] # For benchmarking multi_sig
future_proof_system = [] # For activating future proof systems

[dependencies]
anyhow = { workspace = true }
blake2 = "0.10.6"
# Enforce blst portable feature for runtime detection of Intel ADX instruction set.
blst = { version = "0.3.16", features = ["portable"] }
Expand Down
19 changes: 9 additions & 10 deletions mithril-stm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,15 @@ match msig {
println!("Aggregate ok");
assert!(aggr.verify(&msg, &clerk.compute_aggregate_verification_key(), &params).is_ok());
}
Err(AggregationError::NotEnoughSignatures(n, k)) => {
println!("Not enough signatures");
assert!(n < params.k && k == params.k)
}
Err(AggregationError::UsizeConversionInvalid) => {
println!("Invalid usize conversion");
}
Err(AggregationError::UnsupportedProofSystem(aggregate_signature_type)) => {
println!("Unsupported proof system: {:?}", aggregate_signature_type);
}
Err(error) => assert!(
matches!(
error.downcast_ref::<AggregationError>(),
Some(AggregationError::NotEnoughSignatures { .. })
| Some(AggregationError::UsizeConversionInvalid)
| Some(AggregationError::UnsupportedProofSystem { .. })
),
"Unexpected error: {error}"
),
}
```

Expand Down
22 changes: 14 additions & 8 deletions mithril-stm/src/aggregate_signature/basic_verifier.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use anyhow::anyhow;
use std::collections::{BTreeMap, HashMap, HashSet};

use crate::bls_multi_signature::{BlsSignature, BlsVerificationKey};
use crate::key_registration::RegisteredParty;
use crate::merkle_tree::MerkleTreeLeaf;
use crate::{
AggregationError, CoreVerifierError, Index, Parameters, SingleSignature,
SingleSignatureWithRegisteredParty, Stake,
SingleSignatureWithRegisteredParty, Stake, StmResult,
};

/// Full node verifier including the list of eligible signers and the total stake of the system.
Expand Down Expand Up @@ -56,7 +57,7 @@ impl BasicVerifier {
signatures: &[SingleSignatureWithRegisteredParty],
parameters: &Parameters,
msg: &[u8],
) -> Result<(), CoreVerifierError> {
) -> StmResult<()> {
let mut nr_indices = 0;
let mut unique_indices = HashSet::new();

Expand All @@ -71,10 +72,13 @@ impl BasicVerifier {
}

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

Ok(())
Expand All @@ -93,7 +97,7 @@ impl BasicVerifier {
params: &Parameters,
msg: &[u8],
sigs: &[SingleSignatureWithRegisteredParty],
) -> Result<Vec<SingleSignatureWithRegisteredParty>, AggregationError> {
) -> StmResult<Vec<SingleSignatureWithRegisteredParty>> {
let mut sig_by_index: BTreeMap<Index, &SingleSignatureWithRegisteredParty> =
BTreeMap::new();
let mut removal_idx_by_vk: HashMap<&SingleSignatureWithRegisteredParty, Vec<Index>> =
Expand Down Expand Up @@ -169,7 +173,9 @@ impl BasicVerifier {
}
}
}
Err(AggregationError::NotEnoughSignatures(count, params.k))
Err(anyhow!(AggregationError::NotEnoughSignatures(
count, params.k
)))
}

/// Given a slice of `sig_reg_list`, this function returns a new list of `sig_reg_list` with only valid indices.
Expand All @@ -189,7 +195,7 @@ impl BasicVerifier {
params: &Parameters,
msg: &[u8],
sigs: &[SingleSignatureWithRegisteredParty],
) -> Result<Vec<SingleSignatureWithRegisteredParty>, AggregationError> {
) -> StmResult<Vec<SingleSignatureWithRegisteredParty>> {
Self::select_valid_signatures_for_k_indices(total_stake, params, msg, sigs)
}

Expand Down Expand Up @@ -218,7 +224,7 @@ impl BasicVerifier {
signatures: &[SingleSignature],
parameters: &Parameters,
msg: &[u8],
) -> Result<(), CoreVerifierError> {
) -> StmResult<()> {
let sig_reg_list = signatures
.iter()
.map(|sig| SingleSignatureWithRegisteredParty {
Expand Down
23 changes: 14 additions & 9 deletions mithril-stm/src/aggregate_signature/clerk.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use blake2::digest::{Digest, FixedOutput};

use crate::{
AggregateSignature, AggregateSignatureType, AggregateVerificationKey, AggregationError,
ClosedKeyRegistration, Index, Parameters, Signer, SingleSignature, Stake, VerificationKey,
AggregateSignature, AggregateSignatureType, AggregateVerificationKey, ClosedKeyRegistration,
Index, Parameters, Signer, SingleSignature, Stake, StmResult, VerificationKey,
aggregate_signature::ConcatenationProof,
};
use blake2::digest::{Digest, FixedOutput};

#[cfg(feature = "future_proof_system")]
use anyhow::anyhow;

#[cfg(feature = "future_proof_system")]
use crate::AggregationError;

/// `Clerk` can verify and aggregate `SingleSignature`s and verify `AggregateSignature`s.
/// Clerks can only be generated with the registration closed.
Expand Down Expand Up @@ -62,7 +67,7 @@ impl<D: Digest + Clone + FixedOutput + Send + Sync> Clerk<D> {
&self,
sigs: &[SingleSignature],
msg: &[u8],
) -> Result<AggregateSignature<D>, AggregationError> {
) -> StmResult<AggregateSignature<D>> {
self.aggregate_signatures_with_type(sigs, msg, AggregateSignatureType::default())
}

Expand All @@ -72,14 +77,14 @@ impl<D: Digest + Clone + FixedOutput + Send + Sync> Clerk<D> {
sigs: &[SingleSignature],
msg: &[u8],
aggregate_signature_type: AggregateSignatureType,
) -> Result<AggregateSignature<D>, AggregationError> {
) -> StmResult<AggregateSignature<D>> {
match aggregate_signature_type {
AggregateSignatureType::Concatenation => Ok(AggregateSignature::Concatenation(
ConcatenationProof::aggregate_signatures(self, sigs, msg)?,
)),
#[cfg(feature = "future_proof_system")]
AggregateSignatureType::Future => Err(AggregationError::UnsupportedProofSystem(
aggregate_signature_type,
AggregateSignatureType::Future => Err(anyhow!(
AggregationError::UnsupportedProofSystem(aggregate_signature_type)
)),
}
}
Expand All @@ -96,7 +101,7 @@ impl<D: Digest + Clone + FixedOutput + Send + Sync> Clerk<D> {
&self,
sigs: &[SingleSignature],
msg: &[u8],
) -> Result<AggregateSignature<D>, AggregationError> {
) -> StmResult<AggregateSignature<D>> {
Self::aggregate_signatures(self, sigs, msg)
}

Expand Down
53 changes: 29 additions & 24 deletions mithril-stm/src/aggregate_signature/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ mod tests {
use rand_chacha::ChaCha20Rng;
use rand_core::{RngCore, SeedableRng};

use crate::merkle_tree::MerkleBatchPath;
use crate::{
AggregateSignature, AggregateSignatureType, AggregationError, BasicVerifier, Clerk,
CoreVerifierError, Initializer, KeyRegistration, Parameters, Signer, SingleSignature,
Initializer, KeyRegistration, Parameters, Signer, SingleSignature,
SingleSignatureWithRegisteredParty, Stake, bls_multi_signature::BlsVerificationKey,
};
use crate::{StmResult, merkle_tree::MerkleBatchPath};

type Sig = AggregateSignature<D>;
type D = Blake2b<U32>;
Expand Down Expand Up @@ -147,7 +147,7 @@ mod tests {

#[derive(Debug)]
struct ProofTest {
msig: Result<Sig, AggregationError>,
msig: StmResult<Sig>,
clerk: Clerk<D>,
msg: [u8; 16],
}
Expand Down Expand Up @@ -262,12 +262,13 @@ mod tests {
let verify_result = aggr.verify(&msg, &clerk.compute_aggregate_verification_key(), &params);
assert!(verify_result.is_ok(), "Verification failed: {verify_result:?}");
}
Err(AggregationError::NotEnoughSignatures(n, k)) =>
assert!(n < params.k || k == params.k),
Err(AggregationError::UsizeConversionInvalid) =>
unreachable!(),
Err(AggregationError::UnsupportedProofSystem(_)) =>
unreachable!(),
Err(error) => { assert!(
matches!(
error.downcast_ref::<AggregationError>(),
Some(AggregationError::NotEnoughSignatures{..})
),
"Unexpected error: {error:?}");
}
}
}

Expand Down Expand Up @@ -303,11 +304,13 @@ mod tests {
batch_msgs.push(msg.to_vec());
batch_params.push(params);
}
Err(AggregationError::NotEnoughSignatures(_n, _k)) => {
assert!(sigs.len() < params.k as usize)
Err(error) => { assert!(
matches!(
error.downcast_ref::<AggregationError>(),
Some(AggregationError::NotEnoughSignatures{..})
),
"Unexpected error: {error:?}");
}
Err(AggregationError::UsizeConversionInvalid) => unreachable!(),
Err(AggregationError::UnsupportedProofSystem(_)) => unreachable!(),
}
}

Expand Down Expand Up @@ -428,14 +431,14 @@ mod tests {
let clerk = Clerk::new_clerk_from_signer(&ps[0]);
let aggr_sig_type = AggregateSignatureType::Concatenation;

let msig = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type);
match msig {
Err(AggregationError::NotEnoughSignatures(n, k)) =>
assert!(n < params.k && params.k == k),
_ =>
unreachable!(),
let error = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type).expect_err("Not enough quorum should fail!");
assert!(
matches!(
error.downcast_ref::<AggregationError>(),
Some(AggregationError::NotEnoughSignatures{..})
),
"Unexpected error: {error:?}");
}
}
}

proptest! {
Expand Down Expand Up @@ -561,11 +564,13 @@ mod tests {
Ok(_) => {
assert!(verify_result.is_ok(), "Verification failed: {verify_result:?}");
}
Err(CoreVerifierError::NoQuorum(nr_indices, _k)) => {
assert!((nr_indices) < params.k);
Err(error) => { assert!(
matches!(
error.downcast_ref::<AggregationError>(),
Some(AggregationError::NotEnoughSignatures{..})
),
"Unexpected error: {error:?}");
}
Err(CoreVerifierError::IndexNotUnique) => unreachable!(),
_ => unreachable!(),
}
}

Expand Down
16 changes: 7 additions & 9 deletions mithril-stm/src/aggregate_signature/proof/concatenation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::bls_multi_signature::{BlsSignature, BlsVerificationKey};
use crate::key_registration::RegisteredParty;
use crate::merkle_tree::MerkleBatchPath;
use crate::{
AggregateVerificationKey, AggregationError, BasicVerifier, Parameters, SingleSignature,
SingleSignatureWithRegisteredParty, StmAggregateSignatureError,
AggregateVerificationKey, BasicVerifier, Parameters, SingleSignature,
SingleSignatureWithRegisteredParty, StmAggregateSignatureError, StmResult,
};

/// `ConcatenationProof` uses the "concatenation" proving system (as described in Section 4.3 of the original paper.)
Expand Down Expand Up @@ -36,7 +36,7 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
clerk: &Clerk<D>,
sigs: &[SingleSignature],
msg: &[u8],
) -> Result<ConcatenationProof<D>, AggregationError> {
) -> StmResult<ConcatenationProof<D>> {
let sig_reg_list = sigs
.iter()
.map(|sig| SingleSignatureWithRegisteredParty {
Expand Down Expand Up @@ -83,7 +83,7 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
msg: &[u8],
avk: &AggregateVerificationKey<D>,
parameters: &Parameters,
) -> Result<(Vec<BlsSignature>, Vec<BlsVerificationKey>), StmAggregateSignatureError<D>> {
) -> StmResult<(Vec<BlsSignature>, Vec<BlsVerificationKey>)> {
let msgp = avk.get_merkle_tree_batch_commitment().concatenate_with_message(msg);
BasicVerifier::preliminary_verify(
&avk.get_total_stake(),
Expand Down Expand Up @@ -117,7 +117,7 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
msg: &[u8],
avk: &AggregateVerificationKey<D>,
parameters: &Parameters,
) -> Result<(), StmAggregateSignatureError<D>> {
) -> StmResult<()> {
let msgp = avk.get_merkle_tree_batch_commitment().concatenate_with_message(msg);
let (sigs, vks) = self.preliminary_verify(msg, avk, parameters)?;

Expand All @@ -131,7 +131,7 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
msgs: &[Vec<u8>],
avks: &[AggregateVerificationKey<D>],
parameters: &[Parameters],
) -> Result<(), StmAggregateSignatureError<D>> {
) -> StmResult<()> {
let batch_size = stm_signatures.len();
assert_eq!(
batch_size,
Expand Down Expand Up @@ -195,9 +195,7 @@ impl<D: Clone + Digest + FixedOutput + Send + Sync> ConcatenationProof<D> {
}

///Extract a concatenation proof from a byte slice.
pub fn from_bytes(
bytes: &[u8],
) -> Result<ConcatenationProof<D>, StmAggregateSignatureError<D>> {
pub fn from_bytes(bytes: &[u8]) -> StmResult<ConcatenationProof<D>> {
let mut bytes_index = 0;

let mut u64_bytes = [0u8; 8];
Expand Down
Loading
Loading