1use super::{
11 group::{self, equal, Element, Point, Share, DST, MESSAGE, PROOF_OF_POSSESSION},
12 poly::{self, Eval, PartialSignature},
13 Error,
14};
15use commonware_utils::union_unique;
16use rand::RngCore;
17use rayon::{prelude::*, ThreadPoolBuilder};
18use std::borrow::Cow;
19
20pub fn keypair<R: RngCore>(rng: &mut R) -> (group::Private, group::Public) {
22 let private = group::Private::rand(rng);
23 let mut public = group::Public::one();
24 public.mul(&private);
25 (private, public)
26}
27
28pub fn sign(private: &group::Private, dst: DST, payload: &[u8]) -> group::Signature {
30 let mut s = group::Signature::zero();
31 s.map(dst, payload);
32 s.mul(private);
33 s
34}
35
36pub fn verify(
38 public: &group::Public,
39 dst: DST,
40 payload: &[u8],
41 signature: &group::Signature,
42) -> Result<(), Error> {
43 let mut hm = group::Signature::zero();
44 hm.map(dst, payload);
45 if !equal(public, signature, &hm) {
46 return Err(Error::InvalidSignature);
47 }
48 Ok(())
49}
50
51pub fn sign_proof_of_possession(private: &group::Private) -> group::Signature {
53 let mut public = group::Public::one();
55 public.mul(private);
56
57 sign(private, PROOF_OF_POSSESSION, public.serialize().as_slice())
59}
60
61pub fn verify_proof_of_possession(
63 public: &group::Public,
64 signature: &group::Signature,
65) -> Result<(), Error> {
66 verify(
67 public,
68 PROOF_OF_POSSESSION,
69 public.serialize().as_slice(),
70 signature,
71 )
72}
73
74pub fn sign_message(
81 private: &group::Private,
82 namespace: Option<&[u8]>,
83 message: &[u8],
84) -> group::Signature {
85 let payload = match namespace {
86 Some(namespace) => Cow::Owned(union_unique(namespace, message)),
87 None => Cow::Borrowed(message),
88 };
89 sign(private, MESSAGE, &payload)
90}
91
92pub fn verify_message(
99 public: &group::Public,
100 namespace: Option<&[u8]>,
101 message: &[u8],
102 signature: &group::Signature,
103) -> Result<(), Error> {
104 let payload = match namespace {
105 Some(namespace) => Cow::Owned(union_unique(namespace, message)),
106 None => Cow::Borrowed(message),
107 };
108 verify(public, MESSAGE, &payload, signature)
109}
110
111pub fn partial_sign_proof_of_possession(
113 public: &poly::Public,
114 private: &Share,
115) -> PartialSignature {
116 let threshold_public = poly::public(public);
118
119 let sig = sign(
121 &private.private,
122 PROOF_OF_POSSESSION,
123 threshold_public.serialize().as_slice(),
124 );
125 Eval {
126 value: sig,
127 index: private.index,
128 }
129}
130
131pub fn partial_verify_proof_of_possession(
137 public: &poly::Public,
138 partial: &PartialSignature,
139) -> Result<(), Error> {
140 let threshold_public = poly::public(public);
141 let public = public.evaluate(partial.index);
142 verify(
143 &public.value,
144 PROOF_OF_POSSESSION,
145 threshold_public.serialize().as_slice(),
146 &partial.value,
147 )
148}
149
150pub fn partial_sign_message(
152 private: &Share,
153 namespace: Option<&[u8]>,
154 message: &[u8],
155) -> PartialSignature {
156 let sig = sign_message(&private.private, namespace, message);
157 Eval {
158 value: sig,
159 index: private.index,
160 }
161}
162
163pub fn partial_verify_message(
169 public: &poly::Public,
170 namespace: Option<&[u8]>,
171 message: &[u8],
172 partial: &PartialSignature,
173) -> Result<(), Error> {
174 let public = public.evaluate(partial.index);
175 verify_message(&public.value, namespace, message, &partial.value)
176}
177
178pub fn threshold_signature_recover(
185 threshold: u32,
186 partials: Vec<PartialSignature>,
187) -> Result<group::Signature, Error> {
188 let sigs = partials.len() as u32;
189 if threshold > sigs {
190 return Err(Error::NotEnoughPartialSignatures(threshold, sigs));
191 }
192 poly::Signature::recover(threshold, partials)
193}
194
195pub fn aggregate_public_keys(public_keys: &[group::Public]) -> group::Public {
204 let mut p = group::Public::zero();
205 for pk in public_keys {
206 p.add(pk);
207 }
208 p
209}
210
211pub fn aggregate_signatures(signatures: &[group::Signature]) -> group::Signature {
219 let mut s = group::Signature::zero();
220 for sig in signatures {
221 s.add(sig);
222 }
223 s
224}
225
226pub fn aggregate_verify_multiple_public_keys(
234 public: &[group::Public],
235 namespace: Option<&[u8]>,
236 message: &[u8],
237 signature: &group::Signature,
238) -> Result<(), Error> {
239 let agg_public = aggregate_public_keys(public);
244
245 verify_message(&agg_public, namespace, message, signature)
247}
248
249pub fn aggregate_verify_multiple_messages(
263 public: &group::Public,
264 namespace: Option<&[u8]>,
265 messages: &[&[u8]],
266 signature: &group::Signature,
267 concurrency: usize,
268) -> Result<(), Error> {
269 let pool = ThreadPoolBuilder::new()
271 .num_threads(concurrency)
272 .build()
273 .expect("Unable to build thread pool");
274
275 let hm_sum = pool.install(|| {
277 messages
278 .par_iter()
279 .map(|msg| {
280 let mut hm = group::Signature::zero();
281 match namespace {
282 Some(namespace) => hm.map(MESSAGE, &union_unique(namespace, msg)),
283 None => hm.map(MESSAGE, msg),
284 };
285 hm
286 })
287 .reduce(group::Signature::zero, |mut sum, hm| {
288 sum.add(&hm);
289 sum
290 })
291 });
292
293 if !equal(public, signature, &hm_sum) {
295 return Err(Error::InvalidSignature);
296 }
297 Ok(())
298}
299
300#[cfg(test)]
301mod tests {
302 use super::*;
303 use crate::bls12381::dkg::ops::generate_shares;
304 use blst::BLST_ERROR;
305 use group::{G1, G1_MESSAGE, G1_PROOF_OF_POSSESSION};
306 use rand::prelude::*;
307
308 #[test]
309 fn test_encoding() {
310 let (private, public) = keypair(&mut thread_rng());
312 let (private_bytes, public_bytes) = (private.serialize(), public.serialize());
313
314 let (private_decoded, public_decoded) = (
316 group::Private::deserialize(&private_bytes).unwrap(),
317 group::Public::deserialize(&public_bytes).unwrap(),
318 );
319
320 assert_eq!(private, private_decoded);
322 assert_eq!(public, public_decoded);
323
324 blst::min_pk::SecretKey::from_bytes(private_bytes.as_slice()).unwrap();
326 let blst_public_decoded =
327 blst::min_pk::PublicKey::from_bytes(public_bytes.as_slice()).unwrap();
328 blst_public_decoded.validate().unwrap();
329 let blst_public_encoded = blst_public_decoded.compress().to_vec();
330 assert_eq!(public_bytes, blst_public_encoded.as_slice());
331 }
332
333 fn blst_verify_proof_of_possession(
335 public: &group::Public,
336 signature: &group::Signature,
337 ) -> Result<(), BLST_ERROR> {
338 let msg = public.serialize();
339 let public = blst::min_pk::PublicKey::from_bytes(public.serialize().as_slice()).unwrap();
340 let signature =
341 blst::min_pk::Signature::from_bytes(signature.serialize().as_slice()).unwrap();
342 match signature.verify(true, &msg, PROOF_OF_POSSESSION, &[], &public, true) {
343 BLST_ERROR::BLST_SUCCESS => Ok(()),
344 e => Err(e),
345 }
346 }
347
348 #[test]
349 fn test_single_proof_of_possession() {
350 let (private, public) = keypair(&mut thread_rng());
352 let pop = sign_proof_of_possession(&private);
353
354 verify_proof_of_possession(&public, &pop).expect("PoP should be valid");
356
357 blst_verify_proof_of_possession(&public, &pop).expect("PoP should be valid");
359 }
360
361 #[test]
362 fn test_threshold_proof_of_possession() {
363 let (n, t) = (5, 4);
365 let mut rng = StdRng::seed_from_u64(0);
366 let (public, shares) = generate_shares(&mut rng, None, n, t);
367 let partials: Vec<_> = shares
368 .iter()
369 .map(|s| partial_sign_proof_of_possession(&public, s))
370 .collect();
371 for p in &partials {
372 partial_verify_proof_of_possession(&public, p).expect("signature should be valid");
373 }
374 let threshold_sig = threshold_signature_recover(t, partials).unwrap();
375 let threshold_pub = poly::public(&public);
376
377 verify_proof_of_possession(&threshold_pub, &threshold_sig)
379 .expect("signature should be valid");
380
381 blst_verify_proof_of_possession(&threshold_pub, &threshold_sig)
383 .expect("signature should be valid");
384 }
385
386 #[test]
387 fn test_single_proof_of_possession_min_sig() {
388 let private = group::Private::rand(&mut thread_rng());
390 let mut public = group::G2::one();
391 public.mul(&private);
392 let public_compressed = public.serialize();
393
394 let mut pop = G1::zero();
396 pop.map(G1_PROOF_OF_POSSESSION, &public_compressed);
397 pop.mul(&private);
398
399 let public = blst::min_sig::PublicKey::from_bytes(&public_compressed).unwrap();
401 let signature = blst::min_sig::Signature::from_bytes(pop.serialize().as_slice()).unwrap();
402 let result = match signature.verify(
403 true,
404 &public_compressed,
405 G1_PROOF_OF_POSSESSION,
406 &[],
407 &public,
408 true,
409 ) {
410 BLST_ERROR::BLST_SUCCESS => Ok(()),
411 e => Err(e),
412 };
413 result.expect("signature should be valid");
414 }
415
416 fn blst_verify_message(
418 public: &group::Public,
419 msg: &[u8],
420 signature: &group::Signature,
421 ) -> Result<(), BLST_ERROR> {
422 let public = blst::min_pk::PublicKey::from_bytes(public.serialize().as_slice()).unwrap();
423 let signature =
424 blst::min_pk::Signature::from_bytes(signature.serialize().as_slice()).unwrap();
425 match signature.verify(true, msg, MESSAGE, &[], &public, true) {
426 BLST_ERROR::BLST_SUCCESS => Ok(()),
427 e => Err(e),
428 }
429 }
430
431 #[test]
432 fn test_bad_namespace() {
433 let (private, public) = keypair(&mut thread_rng());
434 let msg = &[1, 9, 6, 9];
435 let sig = sign_message(&private, Some(b"good"), msg);
436 assert!(matches!(
437 verify_message(&public, Some(b"bad"), msg, &sig).unwrap_err(),
438 Error::InvalidSignature
439 ));
440 }
441
442 #[test]
443 fn test_single_message() {
444 let (private, public) = keypair(&mut thread_rng());
445 let msg = &[1, 9, 6, 9];
446 let namespace = b"test";
447 let sig = sign_message(&private, Some(namespace), msg);
448 verify_message(&public, Some(namespace), msg, &sig).expect("signature should be valid");
449 let payload = union_unique(namespace, msg);
450 blst_verify_message(&public, &payload, &sig).expect("signature should be valid");
451 }
452
453 #[test]
454 fn test_threshold_message() {
455 let (n, t) = (5, 4);
457 let mut rng = StdRng::seed_from_u64(0);
458 let (public, shares) = generate_shares(&mut rng, None, n, t);
459 let msg = &[1, 9, 6, 9];
460 let namespace = b"test";
461 let partials: Vec<_> = shares
462 .iter()
463 .map(|s| partial_sign_message(s, Some(namespace), msg))
464 .collect();
465 for p in &partials {
466 partial_verify_message(&public, Some(namespace), msg, p)
467 .expect("signature should be valid");
468 }
469 let threshold_sig = threshold_signature_recover(t, partials).unwrap();
470 let threshold_pub = poly::public(&public);
471
472 verify_message(&threshold_pub, Some(namespace), msg, &threshold_sig)
474 .expect("signature should be valid");
475
476 let payload = union_unique(namespace, msg);
478 blst_verify_message(&threshold_pub, &payload, &threshold_sig)
479 .expect("signature should be valid");
480 }
481
482 #[test]
483 fn test_single_message_min_sig() {
484 let private = group::Private::rand(&mut thread_rng());
486 let mut public = group::G2::one();
487 public.mul(&private);
488
489 let msg = &[1, 9, 6, 9];
491 let namespace = b"test";
492 let payload = union_unique(namespace, msg);
493 let mut signature = G1::zero();
494 signature.map(G1_MESSAGE, &payload);
495 signature.mul(&private);
496
497 let public = blst::min_sig::PublicKey::from_bytes(public.serialize().as_slice()).unwrap();
499 let signature =
500 blst::min_sig::Signature::from_bytes(signature.serialize().as_slice()).unwrap();
501 let result = match signature.verify(true, &payload, G1_MESSAGE, &[], &public, true) {
502 BLST_ERROR::BLST_SUCCESS => Ok(()),
503 e => Err(e),
504 };
505 result.expect("signature should be valid");
506 }
507
508 fn blst_aggregate_verify_multiple_public_keys(
509 public: &[group::Public],
510 message: &[u8],
511 signature: &group::Signature,
512 ) -> Result<(), BLST_ERROR> {
513 let public = public
514 .iter()
515 .map(|pk| blst::min_pk::PublicKey::from_bytes(pk.serialize().as_slice()).unwrap())
516 .collect::<Vec<_>>();
517 let public = public.iter().collect::<Vec<_>>();
518 let signature =
519 blst::min_pk::Signature::from_bytes(signature.serialize().as_slice()).unwrap();
520 match signature.fast_aggregate_verify(true, message, MESSAGE, &public) {
521 BLST_ERROR::BLST_SUCCESS => Ok(()),
522 e => Err(e),
523 }
524 }
525
526 #[test]
527 fn test_aggregate_verify_multiple_public_keys() {
528 let (private1, public1) = keypair(&mut thread_rng());
530 let (private2, public2) = keypair(&mut thread_rng());
531 let (private3, public3) = keypair(&mut thread_rng());
532 let namespace = b"test";
533 let message = b"message";
534 let sig1 = sign_message(&private1, Some(namespace), message);
535 let sig2 = sign_message(&private2, Some(namespace), message);
536 let sig3 = sign_message(&private3, Some(namespace), message);
537 let pks = vec![public1, public2, public3];
538 let signatures = vec![sig1, sig2, sig3];
539
540 let aggregate_sig = aggregate_signatures(&signatures);
542
543 aggregate_verify_multiple_public_keys(&pks, Some(namespace), message, &aggregate_sig)
545 .expect("Aggregated signature should be valid");
546
547 let payload = union_unique(namespace, message);
549 blst_aggregate_verify_multiple_public_keys(&pks, &payload, &aggregate_sig)
550 .expect("Aggregated signature should be valid");
551 }
552
553 #[test]
554 fn test_aggregate_verify_wrong_public_keys() {
555 let (private1, public1) = keypair(&mut thread_rng());
557 let (private2, public2) = keypair(&mut thread_rng());
558 let (private3, _) = keypair(&mut thread_rng());
559 let namespace = b"test";
560 let message = b"message";
561 let sig1 = sign_message(&private1, Some(namespace), message);
562 let sig2 = sign_message(&private2, Some(namespace), message);
563 let sig3 = sign_message(&private3, Some(namespace), message);
564 let signatures = vec![sig1, sig2, sig3];
565
566 let aggregate_sig = aggregate_signatures(&signatures);
568
569 let (_, public4) = keypair(&mut thread_rng());
571 let wrong_pks = vec![public1, public2, public4];
572 let result = aggregate_verify_multiple_public_keys(
573 &wrong_pks,
574 Some(namespace),
575 message,
576 &aggregate_sig,
577 );
578 assert!(matches!(result, Err(Error::InvalidSignature)));
579 }
580
581 #[test]
582 fn test_aggregate_verify_wrong_public_key_count() {
583 let (private1, public1) = keypair(&mut thread_rng());
585 let (private2, public2) = keypair(&mut thread_rng());
586 let (private3, _) = keypair(&mut thread_rng());
587 let namespace = b"test";
588 let message = b"message";
589 let sig1 = sign_message(&private1, Some(namespace), message);
590 let sig2 = sign_message(&private2, Some(namespace), message);
591 let sig3 = sign_message(&private3, Some(namespace), message);
592 let signatures = vec![sig1, sig2, sig3];
593
594 let aggregate_sig = aggregate_signatures(&signatures);
596
597 let wrong_pks = vec![public1, public2];
599 let result = aggregate_verify_multiple_public_keys(
600 &wrong_pks,
601 Some(namespace),
602 message,
603 &aggregate_sig,
604 );
605 assert!(matches!(result, Err(Error::InvalidSignature)));
606 }
607
608 fn blst_aggregate_verify_multiple_messages(
609 public: &group::Public,
610 msgs: &[&[u8]],
611 signature: &group::Signature,
612 ) -> Result<(), BLST_ERROR> {
613 let public = blst::min_pk::PublicKey::from_bytes(public.serialize().as_slice()).unwrap();
614 let pks = vec![&public; msgs.len()];
615 let signature =
616 blst::min_pk::Signature::from_bytes(signature.serialize().as_slice()).unwrap();
617 match signature.aggregate_verify(true, msgs, MESSAGE, &pks, true) {
618 BLST_ERROR::BLST_SUCCESS => Ok(()),
619 e => Err(e),
620 }
621 }
622
623 #[test]
624 fn test_aggregate_verify_multiple_messages() {
625 let (private, public) = keypair(&mut thread_rng());
627 let messages: Vec<&[u8]> = vec![b"Message 1", b"Message 2", b"Message 3"];
628 let namespace = Some(&b"test"[..]);
629 let signatures: Vec<_> = messages
630 .iter()
631 .map(|msg| sign_message(&private, namespace, msg))
632 .collect();
633
634 let aggregate_sig = aggregate_signatures(&signatures);
636
637 aggregate_verify_multiple_messages(&public, namespace, &messages, &aggregate_sig, 4)
639 .expect("Aggregated signature should be valid");
640
641 let messages = messages
643 .iter()
644 .map(|msg| union_unique(b"test", msg))
645 .collect::<Vec<_>>();
646 let messages = messages
647 .iter()
648 .map(|msg| msg.as_slice())
649 .collect::<Vec<_>>();
650 blst_aggregate_verify_multiple_messages(&public, &messages, &aggregate_sig)
651 .expect("Aggregated signature should be valid");
652 }
653
654 #[test]
655 fn test_aggregate_verify_wrong_messages() {
656 let (private, public) = keypair(&mut thread_rng());
658 let messages: Vec<&[u8]> = vec![b"Message 1", b"Message 2", b"Message 3"];
659 let namespace = Some(&b"test"[..]);
660 let signatures: Vec<_> = messages
661 .iter()
662 .map(|msg| sign_message(&private, namespace, msg))
663 .collect();
664
665 let aggregate_sig = aggregate_signatures(&signatures);
667
668 let wrong_messages: Vec<&[u8]> = vec![b"Message 1", b"Message 2", b"Message 4"];
670 let result = aggregate_verify_multiple_messages(
671 &public,
672 namespace,
673 &wrong_messages,
674 &aggregate_sig,
675 4,
676 );
677 assert!(matches!(result, Err(Error::InvalidSignature)));
678 }
679
680 #[test]
681 fn test_aggregate_verify_wrong_message_count() {
682 let (private, public) = keypair(&mut thread_rng());
684 let messages: Vec<&[u8]> = vec![b"Message 1", b"Message 2", b"Message 3"];
685 let namespace = Some(&b"test"[..]);
686 let signatures: Vec<_> = messages
687 .iter()
688 .map(|msg| sign_message(&private, namespace, msg))
689 .collect();
690
691 let aggregate_sig = aggregate_signatures(&signatures);
693
694 let wrong_messages: Vec<&[u8]> = vec![b"Message 1", b"Message 2"];
696 let result = aggregate_verify_multiple_messages(
697 &public,
698 namespace,
699 &wrong_messages,
700 &aggregate_sig,
701 4,
702 );
703 assert!(matches!(result, Err(Error::InvalidSignature)));
704 }
705}