mithril_stm/aggregate_signature/
basic_verifier.rs1use std::collections::{BTreeMap, HashMap, HashSet};
2
3use crate::bls_multi_signature::{BlsSignature, BlsVerificationKey};
4use crate::key_registration::RegisteredParty;
5use crate::merkle_tree::MerkleTreeLeaf;
6use crate::{
7 AggregationError, CoreVerifierError, Index, Parameters, SingleSignature,
8 SingleSignatureWithRegisteredParty, Stake,
9};
10
11pub struct BasicVerifier {
13 pub eligible_parties: Vec<RegisteredParty>,
15 pub total_stake: Stake,
17}
18
19impl BasicVerifier {
20 pub fn setup(public_signers: &[(BlsVerificationKey, Stake)]) -> Self {
25 let mut total_stake: Stake = 0;
26 let mut unique_parties = HashSet::new();
27 for signer in public_signers.iter() {
28 let (res, overflow) = total_stake.overflowing_add(signer.1);
29 if overflow {
30 panic!("Total stake overflow");
31 }
32 total_stake = res;
33 unique_parties.insert(MerkleTreeLeaf(signer.0, signer.1));
34 }
35
36 let mut eligible_parties: Vec<_> = unique_parties.into_iter().collect();
37 eligible_parties.sort_unstable();
38 BasicVerifier {
39 eligible_parties,
40 total_stake,
41 }
42 }
43
44 pub(crate) fn preliminary_verify(
46 total_stake: &Stake,
47 signatures: &[SingleSignatureWithRegisteredParty],
48 parameters: &Parameters,
49 msg: &[u8],
50 ) -> Result<(), CoreVerifierError> {
51 let mut nr_indices = 0;
52 let mut unique_indices = HashSet::new();
53
54 for sig_reg in signatures {
55 sig_reg
56 .sig
57 .check_indices(parameters, &sig_reg.reg_party.1, msg, total_stake)?;
58 for &index in &sig_reg.sig.indexes {
59 unique_indices.insert(index);
60 nr_indices += 1;
61 }
62 }
63
64 if nr_indices != unique_indices.len() {
65 return Err(CoreVerifierError::IndexNotUnique);
66 }
67 if (nr_indices as u64) < parameters.k {
68 return Err(CoreVerifierError::NoQuorum(nr_indices as u64, parameters.k));
69 }
70
71 Ok(())
72 }
73
74 pub fn dedup_sigs_for_indices(
83 total_stake: &Stake,
84 params: &Parameters,
85 msg: &[u8],
86 sigs: &[SingleSignatureWithRegisteredParty],
87 ) -> Result<Vec<SingleSignatureWithRegisteredParty>, AggregationError> {
88 let mut sig_by_index: BTreeMap<Index, &SingleSignatureWithRegisteredParty> =
89 BTreeMap::new();
90 let mut removal_idx_by_vk: HashMap<&SingleSignatureWithRegisteredParty, Vec<Index>> =
91 HashMap::new();
92
93 for sig_reg in sigs.iter() {
94 if sig_reg
95 .sig
96 .verify_core(
97 params,
98 &sig_reg.reg_party.0,
99 &sig_reg.reg_party.1,
100 msg,
101 total_stake,
102 )
103 .is_err()
104 {
105 continue;
106 }
107 for index in sig_reg.sig.indexes.iter() {
108 let mut insert_this_sig = false;
109 if let Some(&previous_sig) = sig_by_index.get(index) {
110 let sig_to_remove_index = if sig_reg.sig.sigma < previous_sig.sig.sigma {
111 insert_this_sig = true;
112 previous_sig
113 } else {
114 sig_reg
115 };
116
117 if let Some(indexes) = removal_idx_by_vk.get_mut(sig_to_remove_index) {
118 indexes.push(*index);
119 } else {
120 removal_idx_by_vk.insert(sig_to_remove_index, vec![*index]);
121 }
122 } else {
123 insert_this_sig = true;
124 }
125
126 if insert_this_sig {
127 sig_by_index.insert(*index, sig_reg);
128 }
129 }
130 }
131
132 let mut dedup_sigs: HashSet<SingleSignatureWithRegisteredParty> = HashSet::new();
133 let mut count: u64 = 0;
134
135 for (_, &sig_reg) in sig_by_index.iter() {
136 if dedup_sigs.contains(sig_reg) {
137 continue;
138 }
139 let mut deduped_sig = sig_reg.clone();
140 if let Some(indexes) = removal_idx_by_vk.get(sig_reg) {
141 deduped_sig.sig.indexes = deduped_sig
142 .sig
143 .indexes
144 .clone()
145 .into_iter()
146 .filter(|i| !indexes.contains(i))
147 .collect();
148 }
149
150 let size: Result<u64, _> = deduped_sig.sig.indexes.len().try_into();
151 if let Ok(size) = size {
152 if dedup_sigs.contains(&deduped_sig) {
153 panic!("Should not reach!");
154 }
155 dedup_sigs.insert(deduped_sig);
156 count += size;
157
158 if count >= params.k {
159 return Ok(dedup_sigs.into_iter().collect());
160 }
161 }
162 }
163
164 Err(AggregationError::NotEnoughSignatures(count, params.k))
165 }
166
167 pub(crate) fn collect_sigs_vks(
170 sig_reg_list: &[SingleSignatureWithRegisteredParty],
171 ) -> (Vec<BlsSignature>, Vec<BlsVerificationKey>) {
172 let sigs = sig_reg_list
173 .iter()
174 .map(|sig_reg| sig_reg.sig.sigma)
175 .collect::<Vec<BlsSignature>>();
176 let vks = sig_reg_list
177 .iter()
178 .map(|sig_reg| sig_reg.reg_party.0)
179 .collect::<Vec<BlsVerificationKey>>();
180
181 (sigs, vks)
182 }
183
184 pub fn verify(
188 &self,
189 signatures: &[SingleSignature],
190 parameters: &Parameters,
191 msg: &[u8],
192 ) -> Result<(), CoreVerifierError> {
193 let sig_reg_list = signatures
194 .iter()
195 .map(|sig| SingleSignatureWithRegisteredParty {
196 sig: sig.clone(),
197 reg_party: self.eligible_parties[sig.signer_index as usize],
198 })
199 .collect::<Vec<SingleSignatureWithRegisteredParty>>();
200
201 let unique_sigs =
202 Self::dedup_sigs_for_indices(&self.total_stake, parameters, msg, &sig_reg_list)?;
203
204 Self::preliminary_verify(&self.total_stake, &unique_sigs, parameters, msg)?;
205
206 let (sigs, vks) = Self::collect_sigs_vks(&unique_sigs);
207
208 BlsSignature::verify_aggregate(msg.to_vec().as_slice(), &vks, &sigs)?;
209
210 Ok(())
211 }
212}