mithril_stm/aggregate_signature/
signature.rs1use blake2::digest::{Digest, FixedOutput};
2
3use serde::{Deserialize, Serialize};
4
5use crate::bls_multi_signature::{Signature, VerificationKey};
6use crate::key_reg::RegParty;
7use crate::merkle_tree::BatchPath;
8use crate::{
9 CoreVerifier, StmAggrVerificationKey, StmAggregateSignatureError, StmParameters, StmSigRegParty,
10};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
16#[serde(bound(
17 serialize = "BatchPath<D>: Serialize",
18 deserialize = "BatchPath<D>: Deserialize<'de>"
19))]
20pub struct StmAggrSig<D: Clone + Digest + FixedOutput> {
21 pub(crate) signatures: Vec<StmSigRegParty>,
22 pub batch_proof: BatchPath<D>,
24}
25
26impl<D: Clone + Digest + FixedOutput + Send + Sync> StmAggrSig<D> {
27 fn preliminary_verify(
34 &self,
35 msg: &[u8],
36 avk: &StmAggrVerificationKey<D>,
37 parameters: &StmParameters,
38 ) -> Result<(Vec<Signature>, Vec<VerificationKey>), StmAggregateSignatureError<D>> {
39 let msgp = avk.get_mt_commitment().concat_with_msg(msg);
40 CoreVerifier::preliminary_verify(
41 &avk.get_total_stake(),
42 &self.signatures,
43 parameters,
44 &msgp,
45 )?;
46
47 let leaves = self
48 .signatures
49 .iter()
50 .map(|r| r.reg_party)
51 .collect::<Vec<RegParty>>();
52
53 avk.get_mt_commitment().check(&leaves, &self.batch_proof)?;
54
55 Ok(CoreVerifier::collect_sigs_vks(&self.signatures))
56 }
57
58 pub fn verify(
65 &self,
66 msg: &[u8],
67 avk: &StmAggrVerificationKey<D>,
68 parameters: &StmParameters,
69 ) -> Result<(), StmAggregateSignatureError<D>> {
70 let msgp = avk.get_mt_commitment().concat_with_msg(msg);
71 let (sigs, vks) = self.preliminary_verify(msg, avk, parameters)?;
72
73 Signature::verify_aggregate(msgp.as_slice(), &vks, &sigs)?;
74 Ok(())
75 }
76
77 #[cfg(feature = "batch-verify-aggregates")]
79 pub fn batch_verify(
80 stm_signatures: &[Self],
81 msgs: &[Vec<u8>],
82 avks: &[StmAggrVerificationKey<D>],
83 parameters: &[StmParameters],
84 ) -> Result<(), StmAggregateSignatureError<D>> {
85 let batch_size = stm_signatures.len();
86 assert_eq!(
87 batch_size,
88 msgs.len(),
89 "Number of messages should correspond to size of the batch"
90 );
91 assert_eq!(
92 batch_size,
93 avks.len(),
94 "Number of avks should correspond to size of the batch"
95 );
96 assert_eq!(
97 batch_size,
98 parameters.len(),
99 "Number of parameters should correspond to size of the batch"
100 );
101
102 let mut aggr_sigs = Vec::with_capacity(batch_size);
103 let mut aggr_vks = Vec::with_capacity(batch_size);
104 for (idx, sig_group) in stm_signatures.iter().enumerate() {
105 sig_group.preliminary_verify(&msgs[idx], &avks[idx], ¶meters[idx])?;
106 let grouped_sigs: Vec<Signature> = sig_group
107 .signatures
108 .iter()
109 .map(|sig_reg| sig_reg.sig.sigma)
110 .collect();
111 let grouped_vks: Vec<VerificationKey> = sig_group
112 .signatures
113 .iter()
114 .map(|sig_reg| sig_reg.reg_party.0)
115 .collect();
116
117 let (aggr_vk, aggr_sig) = Signature::aggregate(&grouped_vks, &grouped_sigs).unwrap();
118 aggr_sigs.push(aggr_sig);
119 aggr_vks.push(aggr_vk);
120 }
121
122 let concat_msgs: Vec<Vec<u8>> = msgs
123 .iter()
124 .zip(avks.iter())
125 .map(|(msg, avk)| avk.get_mt_commitment().concat_with_msg(msg))
126 .collect();
127
128 Signature::batch_verify_aggregates(&concat_msgs, &aggr_vks, &aggr_sigs)?;
129 Ok(())
130 }
131
132 pub fn to_bytes(&self) -> Vec<u8> {
139 let mut out = Vec::new();
140 let proof_type: u8 = 0;
144 out.extend_from_slice(&proof_type.to_be_bytes());
145 out.extend_from_slice(&u64::try_from(self.signatures.len()).unwrap().to_be_bytes());
146 for sig_reg in &self.signatures {
147 out.extend_from_slice(
148 &u64::try_from(sig_reg.to_bytes().len())
149 .unwrap()
150 .to_be_bytes(),
151 );
152 out.extend_from_slice(&sig_reg.to_bytes());
153 }
154 let proof = &self.batch_proof;
155 out.extend_from_slice(&proof.to_bytes());
156
157 out
158 }
159
160 pub fn from_bytes(bytes: &[u8]) -> Result<StmAggrSig<D>, StmAggregateSignatureError<D>> {
162 let mut u8_bytes = [0u8; 1];
163 let mut bytes_index = 0;
164
165 u8_bytes.copy_from_slice(
166 bytes
167 .get(..1)
168 .ok_or(StmAggregateSignatureError::SerializationError)?,
169 );
170 bytes_index += 1;
171 let proof_type = u8::from_be_bytes(u8_bytes);
172 if proof_type != 0 {
173 return Err(StmAggregateSignatureError::SerializationError);
174 }
175
176 let mut u64_bytes = [0u8; 8];
177 u64_bytes.copy_from_slice(
178 bytes
179 .get(bytes_index..bytes_index + 8)
180 .ok_or(StmAggregateSignatureError::SerializationError)?,
181 );
182 let total_sigs = usize::try_from(u64::from_be_bytes(u64_bytes))
183 .map_err(|_| StmAggregateSignatureError::SerializationError)?;
184 bytes_index += 8;
185
186 let mut sig_reg_list = Vec::with_capacity(total_sigs);
187 for _ in 0..total_sigs {
188 u64_bytes.copy_from_slice(
189 bytes
190 .get(bytes_index..bytes_index + 8)
191 .ok_or(StmAggregateSignatureError::SerializationError)?,
192 );
193 let sig_reg_size = usize::try_from(u64::from_be_bytes(u64_bytes))
194 .map_err(|_| StmAggregateSignatureError::SerializationError)?;
195 let sig_reg = StmSigRegParty::from_bytes::<D>(
196 bytes
197 .get(bytes_index + 8..bytes_index + 8 + sig_reg_size)
198 .ok_or(StmAggregateSignatureError::SerializationError)?,
199 )?;
200 bytes_index += 8 + sig_reg_size;
201 sig_reg_list.push(sig_reg);
202 }
203
204 let batch_proof = BatchPath::from_bytes(
205 bytes
206 .get(bytes_index..)
207 .ok_or(StmAggregateSignatureError::SerializationError)?,
208 )?;
209
210 Ok(StmAggrSig {
211 signatures: sig_reg_list,
212 batch_proof,
213 })
214 }
215}