Skip to content

Commit d590778

Browse files
committed
feat(stm): implement support for multiple proof types in clerk
1 parent d272cb2 commit d590778

File tree

10 files changed

+139
-74
lines changed

10 files changed

+139
-74
lines changed

demo/protocol-demo/src/demonstrator.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use hex::ToHex;
2+
use mithril_stm::AggregateSignatureType;
23
use rand_core::{CryptoRng, RngCore};
34
use serde::{Deserialize, Serialize};
45
use std::collections::HashMap;
@@ -142,7 +143,12 @@ impl Party {
142143
message: &Vec<u8>,
143144
signatures: &[ProtocolSingleSignature],
144145
) -> Option<&ProtocolMultiSignature> {
145-
let msig = self.clerk.as_ref().unwrap().aggregate_signatures(signatures, message);
146+
let aggregate_signature_type = AggregateSignatureType::Concatenation;
147+
let msig = self.clerk.as_ref().unwrap().aggregate_signatures_with_type(
148+
signatures,
149+
message,
150+
aggregate_signature_type,
151+
);
146152
match msig {
147153
Ok(aggregate_signature) => {
148154
println!("Party #{}: aggregate signature computed", self.party_id);

mithril-stm/benches/size_benches.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use blake2::{
44
digest::consts::{U32, U64},
55
};
66
use mithril_stm::{
7-
BasicVerifier, Clerk, Initializer, KeyRegistration, Parameters, Signer, SingleSignature,
8-
SingleSignatureWithRegisteredParty, Stake, VerificationKey,
7+
AggregateSignatureType, BasicVerifier, Clerk, Initializer, KeyRegistration, Parameters, Signer,
8+
SingleSignature, SingleSignatureWithRegisteredParty, Stake, VerificationKey,
99
};
1010
use rand_chacha::ChaCha20Rng;
1111
use rand_core::{RngCore, SeedableRng};
@@ -51,7 +51,10 @@ where
5151
let clerk = Clerk::new_clerk_from_signer(&ps[0]);
5252

5353
// Aggregate with random parties
54-
let aggr = clerk.aggregate_signatures(&sigs, &msg).unwrap();
54+
let aggr_sig_type = AggregateSignatureType::Concatenation;
55+
let aggr = clerk
56+
.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type)
57+
.unwrap();
5558

5659
println!(
5760
"k = {} | m = {} | nr parties = {}; {} bytes",

mithril-stm/benches/stm.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1+
use std::fmt::Debug;
2+
13
use blake2::digest::{Digest, FixedOutput};
24
use blake2::{Blake2b, digest::consts::U32};
35
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
4-
use mithril_stm::{
5-
AggregateSignature, BasicVerifier, Clerk, Initializer, KeyRegistration, Parameters, Signer,
6-
Stake, VerificationKey,
7-
};
86
use rand_chacha::ChaCha20Rng;
97
use rand_core::{RngCore, SeedableRng};
108
use rayon::prelude::*;
11-
use std::fmt::Debug;
9+
10+
use mithril_stm::{
11+
AggregateSignature, AggregateSignatureType, BasicVerifier, Clerk, Initializer, KeyRegistration,
12+
Parameters, Signer, Stake, VerificationKey,
13+
};
1214

1315
/// This benchmark framework is not ideal. We really have to think what is the best mechanism for
1416
/// benchmarking these signatures, over which parameters, how many times to run them, etc:
@@ -67,9 +69,10 @@ where
6769
let sigs = signers.par_iter().filter_map(|p| p.sign(&msg)).collect::<Vec<_>>();
6870

6971
let clerk = Clerk::new_clerk_from_signer(&signers[0]);
72+
let aggregate_signature_type = AggregateSignatureType::Concatenation;
7073

7174
group.bench_function(BenchmarkId::new("Aggregation", &param_string), |b| {
72-
b.iter(|| clerk.aggregate_signatures(&sigs, &msg))
75+
b.iter(|| clerk.aggregate_signatures_with_type(&sigs, &msg, aggregate_signature_type))
7376
});
7477
}
7578

@@ -129,7 +132,10 @@ fn batch_benches<H>(
129132
let sigs = signers.par_iter().filter_map(|p| p.sign(&msg)).collect::<Vec<_>>();
130133

131134
let clerk = Clerk::new_clerk_from_signer(&signers[0]);
132-
let msig = clerk.aggregate_signatures(&sigs, &msg).unwrap();
135+
let aggregate_signature_type = AggregateSignatureType::Concatenation;
136+
let msig = clerk
137+
.aggregate_signatures_with_type(&sigs, &msg, aggregate_signature_type)
138+
.unwrap();
133139

134140
batch_avks.push(clerk.compute_aggregate_verification_key());
135141
batch_stms.push(msig);

mithril-stm/examples/key_registration.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
//! but instead by all the participants in the signature process. Contrarily to the full protocol
33
//! run presented in `tests/integration.rs`, we explicitly treat each party individually.
44
use blake2::{Blake2b, digest::consts::U32};
5-
use mithril_stm::{
6-
Clerk, ClosedKeyRegistration, Initializer, KeyRegistration, Parameters, Stake,
7-
VerificationKeyProofOfPossession,
8-
};
9-
105
use rand_chacha::ChaCha20Rng;
116
use rand_core::{RngCore, SeedableRng};
127

8+
use mithril_stm::{
9+
AggregateSignatureType, Clerk, ClosedKeyRegistration, Initializer, KeyRegistration, Parameters,
10+
Stake, VerificationKeyProofOfPossession,
11+
};
12+
1313
type H = Blake2b<U32>;
1414

1515
fn main() {
@@ -113,7 +113,8 @@ fn main() {
113113
let clerk = Clerk::new_clerk_from_closed_key_registration(&params, &closed_registration);
114114

115115
// Now we aggregate the signatures
116-
let msig_1 = match clerk.aggregate_signatures(&complete_sigs_1, &msg) {
116+
let aggr_sig_type = AggregateSignatureType::Concatenation;
117+
let msig_1 = match clerk.aggregate_signatures_with_type(&complete_sigs_1, &msg, aggr_sig_type) {
117118
Ok(s) => s,
118119
Err(e) => {
119120
panic!("Aggregation failed: {e:?}")
@@ -125,7 +126,7 @@ fn main() {
125126
.is_ok()
126127
);
127128

128-
let msig_2 = match clerk.aggregate_signatures(&complete_sigs_2, &msg) {
129+
let msig_2 = match clerk.aggregate_signatures_with_type(&complete_sigs_2, &msg, aggr_sig_type) {
129130
Ok(s) => s,
130131
Err(e) => {
131132
panic!("Aggregation failed: {e:?}")
@@ -137,7 +138,7 @@ fn main() {
137138
.is_ok()
138139
);
139140

140-
let msig_3 = clerk.aggregate_signatures(&incomplete_sigs_3, &msg);
141+
let msig_3 = clerk.aggregate_signatures_with_type(&incomplete_sigs_3, &msg, aggr_sig_type);
141142
assert!(msig_3.is_err());
142143
}
143144

mithril-stm/src/aggregate_signature/clerk.rs

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use blake2::digest::{Digest, FixedOutput};
22

33
use crate::{
4-
AggregateSignature, AggregateVerificationKey, AggregationError, BasicVerifier,
5-
ClosedKeyRegistration, Index, Parameters, Signer, SingleSignature,
6-
SingleSignatureWithRegisteredParty, Stake, VerificationKey,
4+
AggregateSignature, AggregateSignatureType, AggregateVerificationKey, AggregationError,
5+
ClosedKeyRegistration, Index, Parameters, Signer, SingleSignature, Stake, VerificationKey,
76
aggregate_signature::ConcatenationProof,
87
};
98

@@ -57,50 +56,34 @@ impl<D: Digest + Clone + FixedOutput + Send + Sync> Clerk<D> {
5756
Self::new_clerk_from_signer(signer)
5857
}
5958

60-
/// Aggregate a set of signatures for their corresponding indices.
61-
///
62-
/// This function first deduplicates the repeated signatures, and if there are enough signatures, it collects the merkle tree indexes of unique signatures.
63-
/// The list of merkle tree indexes is used to create a batch proof, to prove that all signatures are from eligible signers.
64-
///
65-
/// It returns an instance of `AggregateSignature`.
59+
/// Aggregate a set of signatures.
60+
#[deprecated(since = "0.6.0", note = "Use `aggregate_signatures_with_type` instead")] // TODO: Update since version
6661
pub fn aggregate_signatures(
6762
&self,
6863
sigs: &[SingleSignature],
6964
msg: &[u8],
7065
) -> Result<AggregateSignature<D>, AggregationError> {
71-
let sig_reg_list = sigs
72-
.iter()
73-
.map(|sig| SingleSignatureWithRegisteredParty {
74-
sig: sig.clone(),
75-
reg_party: self.closed_reg.reg_parties[sig.signer_index as usize],
76-
})
77-
.collect::<Vec<SingleSignatureWithRegisteredParty>>();
78-
79-
let avk = AggregateVerificationKey::from(&self.closed_reg);
80-
let msgp = avk.get_merkle_tree_batch_commitment().concatenate_with_message(msg);
81-
let mut unique_sigs = BasicVerifier::select_valid_signatures_for_k_indices(
82-
&self.closed_reg.total_stake,
83-
&self.params,
84-
&msgp,
85-
&sig_reg_list,
86-
)?;
87-
88-
unique_sigs.sort_unstable();
66+
let proof_type = AggregateSignatureType::Concatenation;
8967

90-
let mt_index_list = unique_sigs
91-
.iter()
92-
.map(|sig_reg| sig_reg.sig.signer_index as usize)
93-
.collect::<Vec<usize>>();
94-
95-
let batch_proof = self
96-
.closed_reg
97-
.merkle_tree
98-
.compute_merkle_tree_batch_path(mt_index_list);
68+
self.aggregate_signatures_with_type(sigs, msg, proof_type)
69+
}
9970

100-
Ok(AggregateSignature::Concatenation(ConcatenationProof {
101-
signatures: unique_sigs,
102-
batch_proof,
103-
}))
71+
/// Aggregate a set of signatures with a given proof type.
72+
pub fn aggregate_signatures_with_type(
73+
&self,
74+
sigs: &[SingleSignature],
75+
msg: &[u8],
76+
aggregate_signature_type: AggregateSignatureType,
77+
) -> Result<AggregateSignature<D>, AggregationError> {
78+
match aggregate_signature_type {
79+
AggregateSignatureType::Concatenation => Ok(AggregateSignature::Concatenation(
80+
ConcatenationProof::aggregate_signatures(self, sigs, msg)?,
81+
)),
82+
#[cfg(feature = "future_proof_system")]
83+
AggregateSignatureType::Future => Err(AggregationError::UnsupportedProofSystem(
84+
aggregate_signature_type,
85+
)),
86+
}
10487
}
10588

10689
/// Aggregate a set of signatures for their corresponding indices.
@@ -110,6 +93,7 @@ impl<D: Digest + Clone + FixedOutput + Send + Sync> Clerk<D> {
11093
///
11194
/// It returns an instance of `AggregateSignature`.
11295
#[deprecated(since = "0.5.0", note = "Use `aggregate_signatures` instead")]
96+
#[allow(deprecated)]
11397
pub fn aggregate(
11498
&self,
11599
sigs: &[SingleSignature],

mithril-stm/src/aggregate_signature/mod.rs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ mod tests {
2424
use rand_chacha::ChaCha20Rng;
2525
use rand_core::{RngCore, SeedableRng};
2626

27-
use crate::bls_multi_signature::BlsVerificationKey;
2827
use crate::merkle_tree::MerkleBatchPath;
2928
use crate::{
3029
AggregateSignature, AggregationError, BasicVerifier, Clerk, CoreVerifierError, Initializer,
3130
KeyRegistration, Parameters, Signer, SingleSignature, SingleSignatureWithRegisteredParty,
3231
Stake,
3332
};
33+
use crate::{AggregateSignatureType, bls_multi_signature::BlsVerificationKey};
3434

3535
type Sig = AggregateSignature<D>;
3636
type D = Blake2b<U32>;
@@ -169,7 +169,8 @@ mod tests {
169169
let all_ps: Vec<usize> = (0..n).collect();
170170
let sigs = find_signatures(&msg, &ps, &all_ps);
171171

172-
let msig = clerk.aggregate_signatures(&sigs, &msg);
172+
let aggr_sig_type = AggregateSignatureType::Concatenation;
173+
let msig = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type);
173174
ProofTest { msig, clerk, msg }
174175
})
175176
})
@@ -252,10 +253,11 @@ mod tests {
252253
let params = Parameters { m, k, phi_f: 0.2 };
253254
let ps = setup_equal_parties(params, nparties);
254255
let clerk = Clerk::new_clerk_from_signer(&ps[0]);
256+
let aggr_sig_type = AggregateSignatureType::Concatenation;
255257

256258
let all_ps: Vec<usize> = (0..nparties).collect();
257259
let sigs = find_signatures(&msg, &ps, &all_ps);
258-
let msig = clerk.aggregate_signatures(&sigs, &msg);
260+
let msig = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type);
259261

260262
match msig {
261263
Ok(aggr) => {
@@ -265,7 +267,9 @@ mod tests {
265267
Err(AggregationError::NotEnoughSignatures(n, k)) =>
266268
assert!(n < params.k || k == params.k),
267269
Err(AggregationError::UsizeConversionInvalid) =>
268-
unreachable!()
270+
unreachable!(),
271+
Err(AggregationError::UnsupportedProofSystem(_)) =>
272+
unreachable!(),
269273
}
270274
}
271275

@@ -277,6 +281,7 @@ mod tests {
277281
seed in any::<[u8;32]>(),
278282
batch_size in 2..10,
279283
) {
284+
let aggr_sig_type = AggregateSignatureType::Concatenation;
280285
let mut rng = ChaCha20Rng::from_seed(seed);
281286
let mut aggr_avks = Vec::new();
282287
let mut aggr_stms = Vec::new();
@@ -291,7 +296,7 @@ mod tests {
291296

292297
let all_ps: Vec<usize> = (0..nparties).collect();
293298
let sigs = find_signatures(&msg, &ps, &all_ps);
294-
let msig = clerk.aggregate_signatures(&sigs, &msg);
299+
let msig = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type);
295300

296301
match msig {
297302
Ok(aggr) => {
@@ -304,6 +309,7 @@ mod tests {
304309
assert!(sigs.len() < params.k as usize)
305310
}
306311
Err(AggregationError::UsizeConversionInvalid) => unreachable!(),
312+
Err(AggregationError::UnsupportedProofSystem(_)) => unreachable!(),
307313
}
308314
}
309315

@@ -317,7 +323,7 @@ mod tests {
317323

318324
let all_ps: Vec<usize> = (0..nparties).collect();
319325
let sigs = find_signatures(&msg, &ps, &all_ps);
320-
let fake_msig = clerk.aggregate_signatures(&sigs, &msg);
326+
let fake_msig = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type);
321327

322328
aggr_stms[0] = fake_msig.unwrap();
323329
assert!(AggregateSignature::batch_verify(&aggr_stms, &batch_msgs, &aggr_avks, &batch_params).is_err());
@@ -381,10 +387,11 @@ mod tests {
381387
let params = Parameters { m: 10, k: 5, phi_f: 1.0 };
382388
let ps = setup_equal_parties(params, nparties);
383389
let clerk = Clerk::new_clerk_from_signer(&ps[0]);
390+
let aggr_sig_type = AggregateSignatureType::Concatenation;
384391

385392
let all_ps: Vec<usize> = (0..nparties).collect();
386393
let sigs = find_signatures(&msg, &ps, &all_ps);
387-
let msig = clerk.aggregate_signatures(&sigs, &msg);
394+
let msig = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type);
388395
if let Ok(aggr) = msig {
389396
let bytes: Vec<u8> = aggr.to_bytes();
390397
let aggr2 = AggregateSignature::from_bytes(&bytes).unwrap();
@@ -421,8 +428,9 @@ mod tests {
421428
assert!(sigs.len() < params.k as usize);
422429

423430
let clerk = Clerk::new_clerk_from_signer(&ps[0]);
431+
let aggr_sig_type = AggregateSignatureType::Concatenation;
424432

425-
let msig = clerk.aggregate_signatures(&sigs, &msg);
433+
let msig = clerk.aggregate_signatures_with_type(&sigs, &msg, aggr_sig_type);
426434
match msig {
427435
Err(AggregationError::NotEnoughSignatures(n, k)) =>
428436
assert!(n < params.k && params.k == k),

0 commit comments

Comments
 (0)