1#![allow(non_snake_case)]
2
3use crate::error::BBSPlusError;
51use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup, VariableBaseMSM};
52use ark_ff::PrimeField;
53use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
54use ark_std::{cfg_iter, fmt::Debug, rand::RngCore, vec::Vec, UniformRand};
55use digest::{Digest, DynDigest};
56
57use zeroize::{Zeroize, ZeroizeOnDrop};
58
59use core::iter::once;
60use dock_crypto_utils::{
61 affine_group_element_from_byte_slices,
62 aliases::*,
63 concat_slices,
64 hashing_utils::{hash_to_field, projective_group_elem_from_try_and_incr},
65 iter::*,
66 join,
67 misc::{n_projective_group_elements, seq_pairs_satisfy},
68 serde_utils::*,
69 signature::MultiMessageSignatureParams,
70 try_iter::CheckLeft,
71};
72use itertools::process_results;
73
74#[cfg(feature = "parallel")]
75use rayon::prelude::*;
76
77use serde::{Deserialize, Serialize};
78use serde_with::serde_as;
79
80#[serde_as]
82#[derive(
83 Clone,
84 PartialEq,
85 Eq,
86 Debug,
87 CanonicalSerialize,
88 CanonicalDeserialize,
89 Serialize,
90 Deserialize,
91 Zeroize,
92 ZeroizeOnDrop,
93)]
94pub struct SecretKey<F: PrimeField>(#[serde_as(as = "ArkObjectBytes")] pub F);
95
96impl<F: PrimeField> SecretKey<F> {
97 pub const DST: &'static [u8] = b"BBS-SIG-KEYGEN-SALT";
98 pub fn generate_using_seed<D>(seed: &[u8]) -> Self
99 where
100 F: PrimeField,
101 D: Default + DynDigest + Clone,
102 {
103 Self(hash_to_field::<F, D>(Self::DST, seed))
104 }
105}
106
107macro_rules! impl_multi_msg_sig_params {
108 ($name: ident) => {
109 impl<E: Pairing> MultiMessageSignatureParams for $name<E> {
110 fn supported_message_count(&self) -> usize {
111 self.h.len()
112 }
113 }
114
115 impl<E: Pairing> MultiMessageSignatureParams for &$name<E> {
116 fn supported_message_count(&self) -> usize {
117 self.h.len()
118 }
119 }
120 };
121}
122
123macro_rules! impl_sig_params_prepared {
124 ( $group_affine:ident, $group_projective:ident) => {
125 pub fn commit_to_messages<'a, MI>(
133 &self,
134 indexed_messages_sorted_by_index: MI,
135 blinding: &'a E::ScalarField,
136 ) -> Result<E::$group_affine, BBSPlusError>
137 where
138 MI: IntoIterator<Item = (usize, &'a E::ScalarField)>,
139 {
140 let (bases, scalars): (Vec<_>, Vec<_>) = process_results(
141 pair_valid_items_with_slice::<_, _, _, BBSPlusError, _>(
142 indexed_messages_sorted_by_index,
143 CheckLeft(seq_pairs_satisfy(|a, b| a < b)),
144 &self.h,
145 ),
146 |iter| iter.chain(once((&self.h_0, blinding))).unzip(),
147 )?;
148
149 Ok(E::$group_projective::msm_unchecked(&bases, &scalars).into_affine())
150 }
151
152 pub fn b<'a, MI>(
158 &self,
159 indexed_messages_sorted_by_index: MI,
160 s: &'a E::ScalarField,
161 ) -> Result<E::$group_projective, BBSPlusError>
162 where
163 MI: IntoIterator<Item = (usize, &'a E::ScalarField)>,
164 {
165 let commitment = self.commit_to_messages(indexed_messages_sorted_by_index, s)?;
166 Ok(commitment + self.g1)
167 }
168 };
169}
170
171macro_rules! impl_sig_params_prepared_bbs23 {
172 ( $group_affine:ident, $group_projective:ident) => {
173 pub fn commit_to_messages<'a, MI>(
181 &self,
182 indexed_messages_sorted_by_index: MI,
183 ) -> Result<E::$group_affine, BBSPlusError>
184 where
185 MI: IntoIterator<Item = (usize, &'a E::ScalarField)>,
186 {
187 let (bases, scalars): (Vec<_>, Vec<_>) = process_results(
188 pair_valid_items_with_slice::<_, _, _, BBSPlusError, _>(
189 indexed_messages_sorted_by_index,
190 CheckLeft(seq_pairs_satisfy(|a, b| a < b)),
191 &self.h,
192 ),
193 |iter| iter.unzip(),
194 )?;
195
196 Ok(E::$group_projective::msm_unchecked(&bases, &scalars).into_affine())
197 }
198
199 pub fn b<'a, MI>(
205 &self,
206 indexed_messages_sorted_by_index: MI,
207 ) -> Result<E::$group_projective, BBSPlusError>
208 where
209 MI: IntoIterator<Item = (usize, &'a E::ScalarField)>,
210 {
211 let commitment = self.commit_to_messages(indexed_messages_sorted_by_index)?;
212 Ok(commitment + self.g1)
213 }
214 };
215}
216
217macro_rules! impl_sig_params {
218 ( $name:ident, $group_affine:ident, $group_projective:ident, $other_group_affine:ident, $other_group_projective:ident ) => {
219 #[serde_as]
224 #[derive(
225 Clone,
226 PartialEq,
227 Eq,
228 Debug,
229 CanonicalSerialize,
230 CanonicalDeserialize,
231 Serialize,
232 Deserialize,
233 )]
234 pub struct $name<E: Pairing> {
235 #[serde_as(as = "ArkObjectBytes")]
236 pub g1: E::$group_affine,
237 #[serde_as(as = "ArkObjectBytes")]
238 pub g2: E::$other_group_affine,
239 #[serde_as(as = "ArkObjectBytes")]
240 pub h_0: E::$group_affine,
241 #[serde_as(as = "Vec<ArkObjectBytes>")]
243 pub h: Vec<E::$group_affine>,
244 }
245
246 impl<E: Pairing> $name<E> {
247 pub fn new<D: Digest>(label: &[u8], message_count: u32) -> Self {
251 assert_ne!(message_count, 0);
252
253 let ((h, [g1, h_0]), g2) = join!(
254 {
255 let g1 = projective_group_elem_from_try_and_incr::<E::$group_affine, D>(
256 &concat_slices!(label, b" : g1"),
257 );
258 let h_bytes = concat_slices!(label, b" : h_");
259 let h = n_projective_group_elements::<E::$group_affine, D>(
261 0..message_count + 1,
262 &h_bytes,
263 );
264 let g1_and_h: Vec<_> = iter::once(g1).chain(h).collect();
265
266 let mut normalized_g1_and_h =
268 E::$group_projective::normalize_batch(&g1_and_h);
269
270 (
271 normalized_g1_and_h.split_off(2),
272 <[_; 2]>::try_from(normalized_g1_and_h).unwrap(),
273 )
274 },
275 affine_group_element_from_byte_slices!(label, b" : g2")
276 );
277
278 Self { g1, g2, h_0, h }
279 }
280
281 pub fn generate_using_rng<R>(rng: &mut R, message_count: u32) -> Self
283 where
284 R: RngCore,
285 {
286 assert_ne!(message_count, 0);
287 let h = (0..message_count)
288 .into_iter()
289 .map(|_| E::$group_projective::rand(rng))
290 .collect::<Vec<E::$group_projective>>();
291 Self {
292 g1: E::$group_affine::rand(rng),
293 g2: E::$other_group_affine::rand(rng),
294 h_0: E::$group_affine::rand(rng),
295 h: E::$group_projective::normalize_batch(&h),
296 }
297 }
298
299 pub fn is_valid(&self) -> bool {
303 !(self.g1.is_zero()
304 || self.g2.is_zero()
305 || self.h_0.is_zero()
306 || cfg_iter!(self.h).any(|v| v.is_zero()))
307 }
308
309 impl_sig_params_prepared!($group_affine, $group_projective);
310 }
311 };
312}
313
314macro_rules! impl_public_key_generation {
315 ($gen_function_name: ident, $params:ident) => {
316 pub fn $gen_function_name(
318 secret_key: &SecretKey<E::ScalarField>,
319 params: &$params<E>,
320 ) -> Self {
321 Self(params.g2.mul_bigint(secret_key.0.into_bigint()).into())
322 }
323 };
324}
325
326macro_rules! impl_public_key {
327 ( $name:ident, $group:ident, $params:ident ) => {
328 #[serde_as]
332 #[derive(
333 Clone,
334 PartialEq,
335 Eq,
336 Debug,
337 CanonicalSerialize,
338 CanonicalDeserialize,
339 Serialize,
340 Deserialize,
341 )]
342 pub struct $name<E: Pairing>(#[serde_as(as = "ArkObjectBytes")] pub <E as Pairing>::$group);
343
344 impl<E: Pairing> $name<E>
345 where
346 E: Pairing,
347 {
348 impl_public_key_generation!(generate_using_secret_key, $params);
349
350 pub fn is_valid(&self) -> bool {
353 !self.0.is_zero()
354 }
355 }
356 };
357}
358
359macro_rules! impl_keypair_generation {
360 ( $gen_using_seed_fn_name:ident, $gen_using_rng_fn_name:ident, $gen_using_sk_fn_name:ident, $pk: ident, $params:ident ) => {
361 pub fn $gen_using_seed_fn_name<D>(seed: &[u8], params: &$params<E>) -> Self
362 where
363 D: DynDigest + Default + Clone,
364 {
365 let secret_key = SecretKey::<E::ScalarField>::generate_using_seed::<D>(seed);
366 let public_key = $pk::$gen_using_sk_fn_name(&secret_key, params);
367 Self {
368 secret_key,
369 public_key,
370 }
371 }
372
373 pub fn $gen_using_rng_fn_name<R: RngCore>(rng: &mut R, params: &$params<E>) -> Self {
374 let secret_key = SecretKey(E::ScalarField::rand(rng));
375 let public_key = $pk::$gen_using_sk_fn_name(&secret_key, params);
376 Self {
377 secret_key,
378 public_key,
379 }
380 }
381 };
382}
383
384macro_rules! impl_keypair {
385 ( $name:ident, $group:ident, $pk: ident, $params:ident ) => {
386 #[derive(
387 Clone,
388 Debug,
389 Eq,
390 PartialEq,
391 CanonicalSerialize,
392 CanonicalDeserialize,
393 Serialize,
394 Deserialize,
395 Zeroize,
396 ZeroizeOnDrop,
397 )]
398 #[serde(bound = "")]
399 pub struct $name<E: Pairing> {
400 pub secret_key: SecretKey<E::ScalarField>,
401 #[zeroize(skip)]
402 pub public_key: $pk<E>,
403 }
404
405 impl<E: Pairing> $name<E> {
407 impl_keypair_generation!(
408 generate_using_seed,
409 generate_using_rng,
410 generate_using_secret_key,
411 $pk,
412 $params
413 );
414 }
415 };
416}
417
418impl_sig_params!(SignatureParamsG1, G1Affine, G1, G2Affine, G2);
419impl_multi_msg_sig_params!(SignatureParamsG1);
420impl_sig_params!(SignatureParamsG2, G2Affine, G2, G1Affine, G1);
421impl_multi_msg_sig_params!(SignatureParamsG2);
422impl_public_key!(PublicKeyG2, G2Affine, SignatureParamsG1);
423impl_public_key!(PublicKeyG1, G1Affine, SignatureParamsG2);
424impl_keypair!(KeypairG2, G2Projective, PublicKeyG2, SignatureParamsG1);
425impl_keypair!(KeypairG1, G1Projective, PublicKeyG1, SignatureParamsG2);
426
427#[serde_as]
428#[derive(
429 Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
430)]
431pub struct PreparedSignatureParamsG1<E: Pairing> {
432 #[serde_as(as = "ArkObjectBytes")]
433 pub g1: E::G1Affine,
434 #[serde_as(as = "ArkObjectBytes")]
435 pub g2: E::G2Prepared,
436 #[serde_as(as = "ArkObjectBytes")]
437 pub h_0: E::G1Affine,
438 #[serde_as(as = "Vec<ArkObjectBytes>")]
440 pub h: Vec<E::G1Affine>,
441}
442
443#[serde_as]
444#[derive(
445 Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
446)]
447pub struct PreparedPublicKeyG2<E: Pairing>(#[serde_as(as = "ArkObjectBytes")] pub E::G2Prepared);
448
449impl<E: Pairing> From<SignatureParamsG1<E>> for PreparedSignatureParamsG1<E> {
450 fn from(params: SignatureParamsG1<E>) -> Self {
451 Self {
452 g1: params.g1,
453 g2: E::G2Prepared::from(params.g2),
454 h_0: params.h_0,
455 h: params.h,
456 }
457 }
458}
459
460impl_multi_msg_sig_params!(PreparedSignatureParamsG1);
461
462impl<E: Pairing> PreparedSignatureParamsG1<E> {
463 impl_sig_params_prepared!(G1Affine, G1);
464}
465
466impl<E: Pairing> From<PublicKeyG2<E>> for PreparedPublicKeyG2<E> {
467 fn from(pk: PublicKeyG2<E>) -> Self {
468 Self(E::G2Prepared::from(pk.0))
469 }
470}
471
472#[serde_as]
474#[derive(
475 Clone, PartialEq, Eq, Debug, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
476)]
477pub struct SignatureParams23G1<E: Pairing> {
478 #[serde_as(as = "ArkObjectBytes")]
479 pub g1: E::G1Affine,
480 #[serde_as(as = "ArkObjectBytes")]
481 pub g2: E::G2Affine,
482 #[serde_as(as = "Vec<ArkObjectBytes>")]
484 pub h: Vec<E::G1Affine>,
485}
486
487#[serde_as]
489#[derive(
490 Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize, Serialize, Deserialize,
491)]
492pub struct PreparedSignatureParams23G1<E: Pairing> {
493 #[serde_as(as = "ArkObjectBytes")]
494 pub g1: E::G1Affine,
495 #[serde_as(as = "ArkObjectBytes")]
496 pub g2: E::G2Prepared,
497 #[serde_as(as = "Vec<ArkObjectBytes>")]
499 pub h: Vec<E::G1Affine>,
500}
501
502impl<E: Pairing> SignatureParams23G1<E> {
503 pub fn new<D: Digest>(label: &[u8], message_count: u32) -> Self {
507 assert_ne!(message_count, 0);
508 let (g1, g2, h) = join!(
510 affine_group_element_from_byte_slices!(label, b" : g1"),
511 affine_group_element_from_byte_slices!(label, b" : g2"),
512 {
513 let h: Vec<_> = n_projective_group_elements::<E::G1Affine, D>(
514 1..message_count + 1,
515 &concat_slices!(label, b" : h_"),
516 )
517 .collect();
518 E::G1::normalize_batch(&h)
519 }
520 );
521
522 Self { g1, g2, h }
523 }
524
525 pub fn generate_using_rng<R>(rng: &mut R, message_count: u32) -> Self
527 where
528 R: RngCore,
529 {
530 assert_ne!(message_count, 0);
531 let h = (0..message_count)
532 .map(|_| E::G1::rand(rng))
533 .collect::<Vec<E::G1>>();
534 Self {
535 g1: E::G1::rand(rng).into(),
536 g2: E::G2::rand(rng).into(),
537 h: E::G1::normalize_batch(&h),
538 }
539 }
540
541 pub fn is_valid(&self) -> bool {
545 !(self.g1.is_zero() || self.g2.is_zero() || cfg_iter!(self.h).any(|v| v.is_zero()))
546 }
547
548 impl_sig_params_prepared_bbs23!(G1Affine, G1);
549}
550
551impl_multi_msg_sig_params!(SignatureParams23G1);
552
553impl<E: Pairing> From<SignatureParams23G1<E>> for PreparedSignatureParams23G1<E> {
554 fn from(params: SignatureParams23G1<E>) -> Self {
555 Self {
556 g1: params.g1,
557 g2: E::G2Prepared::from(params.g2),
558 h: params.h,
559 }
560 }
561}
562
563impl<E: Pairing> PreparedSignatureParams23G1<E> {
564 impl_sig_params_prepared_bbs23!(G1Affine, G1);
565}
566
567impl_multi_msg_sig_params!(PreparedSignatureParams23G1);
568
569impl<E: Pairing> PublicKeyG2<E> {
570 impl_public_key_generation!(
571 generate_using_secret_key_and_bbs23_params,
572 SignatureParams23G1
573 );
574}
575
576impl<E: Pairing> KeypairG2<E> {
577 impl_keypair_generation!(
578 generate_using_seed_and_bbs23_params,
579 generate_using_rng_and_bbs23_params,
580 generate_using_secret_key_and_bbs23_params,
581 PublicKeyG2,
582 SignatureParams23G1
583 );
584}
585
586#[cfg(test)]
587mod tests {
588 use super::*;
589 use crate::test_serialization;
590 use ark_bls12_381::Bls12_381;
591 use ark_std::rand::{rngs::StdRng, SeedableRng};
592 use blake2::Blake2b512;
593 use schnorr_pok::{
594 compute_random_oracle_challenge,
595 discrete_log::{PokDiscreteLog, PokDiscreteLogProtocol},
596 };
597
598 type Fr = <Bls12_381 as Pairing>::ScalarField;
599
600 macro_rules! test_serz_des {
601 ($keypair:ident, $public_key:ident, $params:ident, $rng:ident, $message_count: ident, $fn_name: ident) => {
602 let params = $params::<Bls12_381>::generate_using_rng(&mut $rng, $message_count);
603 test_serialization!($params<Bls12_381>, params);
604
605 let keypair = $keypair::<Bls12_381>::$fn_name(&mut $rng, ¶ms);
606 test_serialization!($keypair<Bls12_381>, keypair);
607
608 let pk = keypair.public_key.clone();
609 let sk = keypair.secret_key.clone();
610 test_serialization!($public_key<Bls12_381>, pk);
611 test_serialization!(SecretKey<<Bls12_381 as Pairing>::ScalarField>, sk);
612 };
613 }
614
615 macro_rules! test_params {
616 ($params:ident, $message_count: ident) => {
617 let label_1 = "test1".as_bytes();
618 let params_1 = $params::<Bls12_381>::new::<Blake2b512>(&label_1, $message_count);
619 assert!(params_1.is_valid());
620 assert_eq!(params_1.h.len(), $message_count as usize);
621
622 let params_1_again = $params::<Bls12_381>::new::<Blake2b512>(&label_1, $message_count);
624 assert_eq!(params_1_again, params_1);
625
626 let label_2 = "test2".as_bytes();
628 let params_2 = $params::<Bls12_381>::new::<Blake2b512>(&label_2, $message_count);
629 assert_ne!(params_1, params_2);
630 };
631 }
632
633 macro_rules! test_keypair {
634 ($keypair:ident, $public_key:ident, $params:ident, $seed_fn_name: ident, $sk_fn_name: ident) => {
635 let params = $params::<Bls12_381>::new::<Blake2b512>("test".as_bytes(), 5);
636 let seed = [0, 1, 2, 10, 11];
637
638 let sk = SecretKey::generate_using_seed::<Blake2b512>(&seed);
639 assert_eq!(sk, SecretKey::generate_using_seed::<Blake2b512>(&seed));
640
641 let pk = $public_key::<Bls12_381>::$sk_fn_name(&sk, ¶ms);
642
643 let keypair = $keypair::<Bls12_381>::$seed_fn_name::<Blake2b512>(&seed, ¶ms);
644 assert_eq!(
645 keypair,
646 $keypair {
647 secret_key: sk.clone(),
648 public_key: pk
649 }
650 );
651 drop(sk);
652 drop(keypair);
653 };
654 }
655
656 #[test]
657 fn keypair() {
658 test_keypair!(
659 KeypairG2,
660 PublicKeyG2,
661 SignatureParamsG1,
662 generate_using_seed,
663 generate_using_secret_key
664 );
665 test_keypair!(
666 KeypairG1,
667 PublicKeyG1,
668 SignatureParamsG2,
669 generate_using_seed,
670 generate_using_secret_key
671 );
672 test_keypair!(
673 KeypairG2,
674 PublicKeyG2,
675 SignatureParams23G1,
676 generate_using_seed_and_bbs23_params,
677 generate_using_secret_key_and_bbs23_params
678 );
679 }
680
681 #[test]
682 fn serz_deserz() {
683 let mut rng = StdRng::seed_from_u64(0u64);
685 let message_count = 10;
686 test_serz_des!(
687 KeypairG2,
688 PublicKeyG2,
689 SignatureParamsG1,
690 rng,
691 message_count,
692 generate_using_rng
693 );
694 test_serz_des!(
695 KeypairG1,
696 PublicKeyG1,
697 SignatureParamsG2,
698 rng,
699 message_count,
700 generate_using_rng
701 );
702 test_serz_des!(
703 KeypairG2,
704 PublicKeyG2,
705 SignatureParams23G1,
706 rng,
707 message_count,
708 generate_using_rng_and_bbs23_params
709 );
710 }
711
712 #[test]
713 fn params_deterministically() {
714 let message_count = 10;
716 test_params!(SignatureParamsG1, message_count);
717 test_params!(SignatureParamsG2, message_count);
718 test_params!(SignatureParams23G1, message_count);
719 }
720
721 #[test]
722 fn proof_of_knowledge_of_public_key() {
723 macro_rules! check {
724 ($group_affine:ident, $public_key:ident, $params:ident) => {
725 let mut rng = StdRng::seed_from_u64(0u64);
726 let params = $params::<Bls12_381>::new::<Blake2b512>("test".as_bytes(), 5);
727 let seed = [0, 1, 2, 10, 11];
728 let sk = SecretKey::generate_using_seed::<Blake2b512>(&seed);
729 let pk = $public_key::<Bls12_381>::generate_using_secret_key(&sk, ¶ms);
730
731 let base = ¶ms.g2;
732 let witness = sk.0.clone();
733 let blinding = Fr::rand(&mut rng);
734
735 let protocol =
736 PokDiscreteLogProtocol::<<Bls12_381 as Pairing>::$group_affine>::init(
737 witness, blinding, base,
738 );
739
740 let mut chal_contrib_prover = vec![];
741 protocol
742 .challenge_contribution(base, &pk.0, &mut chal_contrib_prover)
743 .unwrap();
744
745 test_serialization!(
746 PokDiscreteLogProtocol<<Bls12_381 as Pairing>::$group_affine>,
747 protocol
748 );
749
750 let challenge_prover =
751 compute_random_oracle_challenge::<Fr, Blake2b512>(&chal_contrib_prover);
752 let proof = protocol.gen_proof(&challenge_prover);
753
754 let mut chal_contrib_verifier = vec![];
755 proof
756 .challenge_contribution(base, &pk.0, &mut chal_contrib_verifier)
757 .unwrap();
758
759 let challenge_verifier =
760 compute_random_oracle_challenge::<Fr, Blake2b512>(&chal_contrib_verifier);
761 assert!(proof.verify(&pk.0, base, &challenge_verifier));
762 assert_eq!(chal_contrib_prover, chal_contrib_verifier);
763 assert_eq!(challenge_prover, challenge_verifier);
764
765 test_serialization!(PokDiscreteLog<<Bls12_381 as Pairing>::$group_affine>, proof);
766 };
767 }
768
769 check!(G2Affine, PublicKeyG2, SignatureParamsG1);
770 check!(G1Affine, PublicKeyG1, SignatureParamsG2);
771 }
772}