mithril_stm/bls_multi_signature/
mod.rs1pub(super) mod helper;
4mod proof_of_possession;
5mod signature;
6mod signing_key;
7mod verification_key;
8
9pub use crate::bls_multi_signature::proof_of_possession::ProofOfPossession;
10pub use crate::bls_multi_signature::signature::Signature;
11pub use crate::bls_multi_signature::signing_key::SigningKey;
12pub use crate::bls_multi_signature::verification_key::{VerificationKey, VerificationKeyPoP};
13
14use serde::de::Visitor;
15use serde::{Deserialize, Deserializer, Serialize, Serializer};
16
17pub(crate) const POP: &[u8] = b"PoP";
19
20macro_rules! impl_serde {
25 ($st:ty,$visitor:ident,$size:expr) => {
26 impl Serialize for $st {
27 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
28 where
29 S: Serializer,
30 {
31 use serde::ser::SerializeTuple;
32 let mut seq = serializer.serialize_tuple($size)?;
33 for e in self.to_bytes().iter() {
34 seq.serialize_element(e)?;
35 }
36 seq.end()
37 }
38 }
39
40 impl<'de> Deserialize<'de> for $st {
41 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
42 where
43 D: Deserializer<'de>,
44 {
45 struct $visitor;
46
47 impl<'de> Visitor<'de> for $visitor {
48 type Value = $st;
49
50 fn expecting(
51 &self,
52 formatter: &mut ::core::fmt::Formatter,
53 ) -> ::core::fmt::Result {
54 formatter
55 .write_str(format!("a multi signature {}", stringify!($st)).as_str())
56 }
57
58 fn visit_seq<A>(self, mut seq: A) -> Result<$st, A::Error>
59 where
60 A: serde::de::SeqAccess<'de>,
61 {
62 let mut bytes = [0u8; $size];
63 for i in 0..$size {
64 bytes[i] =
65 seq.next_element()?.ok_or(serde::de::Error::invalid_length(
66 i,
67 &format!("expected bytes{}", $size.to_string()).as_str(),
68 ))?;
69 }
70 <$st>::from_bytes(&bytes).map_err(|_| {
71 serde::de::Error::custom(
72 &format!("deserialization failed [{}]", stringify!($st)).as_str(),
73 )
74 })
75 }
76 }
77
78 deserializer.deserialize_tuple($size, $visitor)
79 }
80 }
81 };
82}
83impl_serde!(SigningKey, SigningKeyVisitor, 32);
84impl_serde!(VerificationKey, VerificationKeyVisitor, 96);
85impl_serde!(ProofOfPossession, ProofOfPossessionVisitor, 96);
86impl_serde!(Signature, SignatureVisitor, 48);
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use crate::bls_multi_signature::helper::unsafe_helpers::{p1_affine_to_sig, p2_affine_to_vk};
92 use crate::error::{MultiSignatureError, RegisterError};
93 use crate::key_reg::KeyReg;
94 use blst::{blst_p1, blst_p2};
95 use proptest::prelude::*;
96 use rand_chacha::ChaCha20Rng;
97 use rand_core::SeedableRng;
98
99 impl PartialEq for SigningKey {
100 fn eq(&self, other: &Self) -> bool {
101 self.to_blst_sk().to_bytes() == other.to_blst_sk().to_bytes()
102 }
103 }
104
105 impl Eq for SigningKey {}
106
107 proptest! {
108 #![proptest_config(ProptestConfig::with_cases(1000))]
109
110 #[test]
111 fn test_sig(
112 msg in prop::collection::vec(any::<u8>(), 1..128),
113 seed in any::<[u8;32]>(),
114 ) {
115 let sk = SigningKey::gen(&mut ChaCha20Rng::from_seed(seed));
116 let vk = VerificationKey::from(&sk);
117 let sig = sk.sign(&msg);
118
119 sig.verify(&msg, &vk).unwrap();
120 }
121
122 #[test]
123 fn test_invalid_sig(msg in prop::collection::vec(any::<u8>(), 1..128), seed in any::<[u8;32]>()) {
124 let mut rng = ChaCha20Rng::from_seed(seed);
125 let sk1 = SigningKey::gen(&mut rng);
126 let vk1 = VerificationKey::from(&sk1);
127 let sk2 = SigningKey::gen(&mut rng);
128 let fake_sig = sk2.sign(&msg);
129
130 let result = fake_sig.verify(&msg, &vk1);
131 assert_eq!(result, Err(MultiSignatureError::SignatureInvalid(fake_sig)));
132 }
133
134 #[test]
135 fn test_infinity_sig(msg in prop::collection::vec(any::<u8>(), 1..128), seed in any::<[u8;32]>()) {
136 let mut rng = ChaCha20Rng::from_seed(seed);
137 let sk = SigningKey::gen(&mut rng);
138 let vk = VerificationKey::from(&sk);
139
140 let p1 = blst_p1::default();
141 let sig_infinity = Signature(p1_affine_to_sig(&p1));
142
143 let result = sig_infinity.verify(&msg, &vk);
144 assert_eq!(result, Err(MultiSignatureError::SignatureInfinity(sig_infinity)));
145 }
146
147 #[test]
148 fn test_infinity_vk(seed in any::<[u8;32]>()) {
149 let mut rng = ChaCha20Rng::from_seed(seed);
150 let sk = SigningKey::gen(&mut rng);
151 let pop = ProofOfPossession::from(&sk);
152
153 let p2 = blst_p2::default();
154 let vk_infinity = VerificationKey(p2_affine_to_vk(&p2));
155 let vkpop_infinity = VerificationKeyPoP { vk: vk_infinity, pop };
156
157 let result = vkpop_infinity.check();
158 assert_eq!(result, Err(MultiSignatureError::VerificationKeyInfinity(Box::new(vkpop_infinity.vk))));
159 }
160
161 #[test]
162 fn test_keyreg_with_infinity_vk(num_sigs in 2..16usize, seed in any::<[u8;32]>()) {
163 let mut rng = ChaCha20Rng::from_seed(seed);
164 let mut kr = KeyReg::init();
165
166 let sk = SigningKey::gen(&mut rng);
167 let pop = ProofOfPossession::from(&sk);
168 let p2 = blst_p2::default();
169 let vk_infinity = VerificationKey(p2_affine_to_vk(&p2));
170 let vkpop_infinity = VerificationKeyPoP { vk: vk_infinity, pop };
171
172 for _ in 0..num_sigs {
173 let sk = SigningKey::gen(&mut rng);
174 let vkpop = VerificationKeyPoP::from(&sk);
175 let _ = kr.register(1, vkpop);
176 }
177
178 let result = kr.register(1, vkpop_infinity);
179 assert_eq!(result, Err(RegisterError::VerificationKeyInfinity(Box::new(vkpop_infinity.vk))));
180 }
181
182 #[test]
183 fn test_aggregate_sig(msg in prop::collection::vec(any::<u8>(), 1..128),
184 num_sigs in 2..16,
185 seed in any::<[u8;32]>(),
186 ) {
187 let mut rng = ChaCha20Rng::from_seed(seed);
188 let mut mvks = Vec::new();
189 let mut sigs = Vec::new();
190 for _ in 0..num_sigs {
191 let sk = SigningKey::gen(&mut rng);
192 let vk = VerificationKey::from(&sk);
193 let sig = sk.sign(&msg);
194 assert!(sig.verify(&msg, &vk).is_ok());
195 sigs.push(sig);
196 mvks.push(vk);
197 }
198
199 let result = Signature::verify_aggregate(&msg, &mvks, &sigs);
200 assert!(result.is_ok(), "Aggregate verification failed {result:?}");
201 }
202
203 #[test]
204 fn test_eval_sanity_check(msg in prop::collection::vec(any::<u8>(), 1..128),
205 idx in any::<u64>(),
206 seed in any::<[u8;32]>()) {
207 let sk = SigningKey::gen(&mut ChaCha20Rng::from_seed(seed));
208 let sig = sk.sign(&msg);
209 sig.eval(&msg, idx);
210 }
211
212 #[test]
213 fn serialize_deserialize_vk(seed in any::<u64>()) {
214 let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed);
215 let sk = SigningKey::gen(&mut rng);
216 let vk = VerificationKey::from(&sk);
217 let vk_bytes = vk.to_bytes();
218 let vk2 = VerificationKey::from_bytes(&vk_bytes).unwrap();
219 assert_eq!(vk, vk2);
220 let vkpop = VerificationKeyPoP::from(&sk);
221 let vkpop_bytes = vkpop.to_bytes();
222 let vkpop2: VerificationKeyPoP = VerificationKeyPoP::from_bytes(&vkpop_bytes).unwrap();
223 assert_eq!(vkpop, vkpop2);
224
225 let encoded = bincode::serialize(&vk).unwrap();
227 assert_eq!(encoded, vk_bytes);
228 let decoded: VerificationKey = bincode::deserialize(&encoded).unwrap();
229 assert_eq!(vk, decoded);
230 let encoded = bincode::serialize(&vkpop).unwrap();
231 let decoded: VerificationKeyPoP = bincode::deserialize(&encoded).unwrap();
232 assert_eq!(vkpop, decoded);
233 }
234
235 #[test]
236 fn serialize_deserialize_sk(seed in any::<u64>()) {
237 let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed);
238 let sk = SigningKey::gen(&mut rng);
239 let sk_bytes: [u8; 32] = sk.to_bytes();
240 let sk2 = SigningKey::from_bytes(&sk_bytes).unwrap();
241 assert_eq!(sk, sk2);
242
243 let encoded = bincode::serialize(&sk).unwrap();
245 let decoded: SigningKey = bincode::deserialize(&encoded).unwrap();
246 assert_eq!(sk, decoded);
247
248 let decoded_bytes: SigningKey = bincode::deserialize(&sk_bytes).unwrap();
250 assert_eq!(sk, decoded_bytes);
251 }
252
253 #[test]
254 fn batch_verify(num_batches in 2..10usize,
255 seed in any::<[u8;32]>(),
256 ) {
257 let mut rng = ChaCha20Rng::from_seed(seed);
258 let num_sigs = 10;
259 let mut batch_msgs = Vec::new();
260 let mut batch_vk = Vec::new();
261 let mut batch_sig = Vec::new();
262 for _ in 0..num_batches {
263 let mut msg = [0u8; 32];
264 rng.fill_bytes(&mut msg);
265 let mut mvks = Vec::new();
266 let mut sigs = Vec::new();
267 for _ in 0..num_sigs {
268 let sk = SigningKey::gen(&mut rng);
269 let vk = VerificationKey::from(&sk);
270 let sig = sk.sign(&msg);
271 sigs.push(sig);
272 mvks.push(vk);
273 }
274 assert!(Signature::verify_aggregate(&msg, &mvks, &sigs).is_ok());
275 let (agg_vk, agg_sig) = Signature::aggregate(&mvks, &sigs).unwrap();
276 batch_msgs.push(msg.to_vec());
277 batch_vk.push(agg_vk);
278 batch_sig.push(agg_sig);
279 }
280 assert!(Signature::batch_verify_aggregates(&batch_msgs, &batch_vk, &batch_sig).is_ok());
281
282 let mut msg = [0u8; 32];
284 rng.fill_bytes(&mut msg);
285 let sk = SigningKey::gen(&mut rng);
286 let fake_sig = sk.sign(&msg);
287 batch_sig[0] = fake_sig;
288
289 let batch_result = Signature::batch_verify_aggregates(&batch_msgs, &batch_vk, &batch_sig);
290 assert_eq!(batch_result, Err(MultiSignatureError::BatchInvalid));
291 }
292 }
293}