@@ -72,6 +72,7 @@ use ark_std::{
7272 vec:: Vec ,
7373 One , UniformRand ,
7474} ;
75+ use dock_crypto_utils:: randomized_pairing_check:: RandomizedPairingChecker ;
7576use dock_crypto_utils:: serde_utils:: * ;
7677use schnorr_pok:: { error:: SchnorrError , SchnorrCommitment , SchnorrResponse } ;
7778use serde:: { Deserialize , Serialize } ;
@@ -175,7 +176,7 @@ where
175176
176177 let r1 = E :: Fr :: rand ( rng) ;
177178 let r2 = E :: Fr :: rand ( rng) ;
178- let r3 = r1. inverse ( ) . unwrap ( ) ;
179+ let r3 = r1. inverse ( ) . ok_or ( BBSPlusError :: CannotInvert0 ) ? ;
179180
180181 // b = (e+x) * A = g1 + h_0*s + sum(h_i*m_i) for all i in I
181182 let b = params. b (
@@ -374,9 +375,7 @@ where
374375 pk : & PublicKeyG2 < E > ,
375376 params : & SignatureParamsG1 < E > ,
376377 ) -> Result < ( ) , BBSPlusError > {
377- if self . A_prime . is_zero ( ) {
378- return Err ( BBSPlusError :: ZeroSignature ) ;
379- }
378+ self . verify_except_pairings ( revealed_msgs, challenge, params) ?;
380379
381380 // Verify the randomized signature
382381 if !E :: product_of_pairings ( & [
@@ -390,7 +389,70 @@ where
390389 {
391390 return Err ( BBSPlusError :: PairingCheckFailed ) ;
392391 }
392+ Ok ( ( ) )
393+ }
394+
395+ pub fn verify_with_randomized_pairing_checker (
396+ & self ,
397+ revealed_msgs : & BTreeMap < usize , E :: Fr > ,
398+ challenge : & E :: Fr ,
399+ pk : & PublicKeyG2 < E > ,
400+ params : & SignatureParamsG1 < E > ,
401+ pairing_checker : & mut RandomizedPairingChecker < E > ,
402+ ) -> Result < ( ) , BBSPlusError > {
403+ self . verify_except_pairings ( revealed_msgs, challenge, params) ?;
404+ pairing_checker. add_sources ( self . A_prime , pk. 0 , self . A_bar , params. g2 ) ;
405+ Ok ( ( ) )
406+ }
393407
408+ /// For the verifier to independently calculate the challenge
409+ pub fn challenge_contribution < W : Write > (
410+ & self ,
411+ revealed_msgs : & BTreeMap < usize , E :: Fr > ,
412+ params : & SignatureParamsG1 < E > ,
413+ writer : W ,
414+ ) -> Result < ( ) , BBSPlusError > {
415+ PoKOfSignatureG1Protocol :: compute_challenge_contribution (
416+ & self . A_prime ,
417+ & self . A_bar ,
418+ & self . d ,
419+ & self . T1 ,
420+ & self . T2 ,
421+ revealed_msgs,
422+ params,
423+ writer,
424+ )
425+ }
426+
427+ /// Get the response from post-challenge phase of the Schnorr protocol for the given message index
428+ /// `msg_idx`. Used when comparing message equality
429+ pub fn get_resp_for_message (
430+ & self ,
431+ msg_idx : usize ,
432+ revealed_msg_ids : & BTreeSet < usize > ,
433+ ) -> Result < & E :: Fr , BBSPlusError > {
434+ // Revealed messages are not part of Schnorr protocol
435+ if revealed_msg_ids. contains ( & msg_idx) {
436+ return Err ( BBSPlusError :: InvalidMsgIdxForResponse ( msg_idx) ) ;
437+ }
438+ // Adjust message index as the revealed messages are not part of the Schnorr protocol
439+ let mut adjusted_idx = msg_idx;
440+ for i in revealed_msg_ids {
441+ if * i < msg_idx {
442+ adjusted_idx -= 1 ;
443+ }
444+ }
445+ // 2 added to the index, since 0th and 1st index are reserved for `s'` and `r2`
446+ let r = self . sc_resp_2 . get_response ( 2 + adjusted_idx) ?;
447+ Ok ( r)
448+ }
449+
450+ pub fn verify_schnorr_proofs (
451+ & self ,
452+ revealed_msgs : & BTreeMap < usize , E :: Fr > ,
453+ challenge : & E :: Fr ,
454+ params : & SignatureParamsG1 < E > ,
455+ ) -> Result < ( ) , BBSPlusError > {
394456 // Verify the 1st Schnorr proof
395457 let bases_1 = [ self . A_prime , params. h_0 ] ;
396458 // A_bar - d
@@ -441,46 +503,18 @@ where
441503 Ok ( ( ) )
442504 }
443505
444- /// For the verifier to independently calculate the challenge
445- pub fn challenge_contribution < W : Write > (
506+ /// Verify the proof except the pairing equations. This is useful when doing several verifications (of this
507+ /// protocol or others) and the pairing equations are combined in a randomized pairing check.
508+ fn verify_except_pairings (
446509 & self ,
447510 revealed_msgs : & BTreeMap < usize , E :: Fr > ,
511+ challenge : & E :: Fr ,
448512 params : & SignatureParamsG1 < E > ,
449- writer : W ,
450513 ) -> Result < ( ) , BBSPlusError > {
451- PoKOfSignatureG1Protocol :: compute_challenge_contribution (
452- & self . A_prime ,
453- & self . A_bar ,
454- & self . d ,
455- & self . T1 ,
456- & self . T2 ,
457- revealed_msgs,
458- params,
459- writer,
460- )
461- }
462-
463- /// Get the response from post-challenge phase of the Schnorr protocol for the given message index
464- /// `msg_idx`. Used when comparing message equality
465- pub fn get_resp_for_message (
466- & self ,
467- msg_idx : usize ,
468- revealed_msg_ids : & BTreeSet < usize > ,
469- ) -> Result < & E :: Fr , BBSPlusError > {
470- // Revealed messages are not part of Schnorr protocol
471- if revealed_msg_ids. contains ( & msg_idx) {
472- return Err ( BBSPlusError :: InvalidMsgIdxForResponse ( msg_idx) ) ;
473- }
474- // Adjust message index as the revealed messages are not part of the Schnorr protocol
475- let mut adjusted_idx = msg_idx;
476- for i in revealed_msg_ids {
477- if * i < msg_idx {
478- adjusted_idx -= 1 ;
479- }
514+ if self . A_prime . is_zero ( ) {
515+ return Err ( BBSPlusError :: ZeroSignature ) ;
480516 }
481- // 2 added to the index, since 0th and 1st index are reserved for `s'` and `r2`
482- let r = self . sc_resp_2 . get_response ( 2 + adjusted_idx) ?;
483- Ok ( r)
517+ self . verify_schnorr_proofs ( revealed_msgs, challenge, params)
484518 }
485519}
486520
@@ -1034,4 +1068,94 @@ mod tests {
10341068 }
10351069 }
10361070 }
1071+
1072+ #[ test]
1073+ fn test_PoK_multiple_sigs_with_randomized_pairing_check ( ) {
1074+ let mut rng = StdRng :: seed_from_u64 ( 0u64 ) ;
1075+ let message_count = 5 ;
1076+ let params =
1077+ SignatureParamsG1 :: < Bls12_381 > :: new :: < Blake2b > ( "test" . as_bytes ( ) , message_count) ;
1078+ let keypair = KeypairG2 :: < Bls12_381 > :: generate_using_rng ( & mut rng, & params) ;
1079+
1080+ let sig_count = 10 ;
1081+ let mut msgs = vec ! [ ] ;
1082+ let mut sigs = vec ! [ ] ;
1083+ let mut chal_bytes_prover = vec ! [ ] ;
1084+ let mut poks = vec ! [ ] ;
1085+ let mut proofs = vec ! [ ] ;
1086+ for i in 0 ..sig_count {
1087+ msgs. push (
1088+ ( 0 ..message_count)
1089+ . into_iter ( )
1090+ . map ( |_| Fr :: rand ( & mut rng) )
1091+ . collect :: < Vec < Fr > > ( ) ,
1092+ ) ;
1093+ sigs. push (
1094+ SignatureG1 :: < Bls12_381 > :: new ( & mut rng, & msgs[ i] , & keypair. secret_key , & params)
1095+ . unwrap ( ) ,
1096+ ) ;
1097+ let pok = PoKOfSignatureG1Protocol :: init (
1098+ & mut rng,
1099+ & sigs[ i] ,
1100+ & params,
1101+ & msgs[ i] ,
1102+ BTreeMap :: new ( ) ,
1103+ BTreeSet :: new ( ) ,
1104+ )
1105+ . unwrap ( ) ;
1106+ pok. challenge_contribution ( & BTreeMap :: new ( ) , & params, & mut chal_bytes_prover)
1107+ . unwrap ( ) ;
1108+ poks. push ( pok) ;
1109+ }
1110+
1111+ let challenge_prover = compute_random_oracle_challenge :: < Fr , Blake2b > ( & chal_bytes_prover) ;
1112+
1113+ for pok in poks {
1114+ proofs. push ( pok. gen_proof ( & challenge_prover) . unwrap ( ) ) ;
1115+ }
1116+
1117+ let mut chal_bytes_verifier = vec ! [ ] ;
1118+
1119+ for proof in & proofs {
1120+ proof
1121+ . challenge_contribution ( & BTreeMap :: new ( ) , & params, & mut chal_bytes_verifier)
1122+ . unwrap ( ) ;
1123+ }
1124+
1125+ let challenge_verifier =
1126+ compute_random_oracle_challenge :: < Fr , Blake2b > ( & chal_bytes_verifier) ;
1127+
1128+ let start = Instant :: now ( ) ;
1129+ for proof in proofs. clone ( ) {
1130+ proof
1131+ . verify (
1132+ & BTreeMap :: new ( ) ,
1133+ & challenge_verifier,
1134+ & keypair. public_key ,
1135+ & params,
1136+ )
1137+ . unwrap ( ) ;
1138+ }
1139+ println ! ( "Time to verify {} sigs: {:?}" , sig_count, start. elapsed( ) ) ;
1140+
1141+ let mut pairing_checker = RandomizedPairingChecker :: new_using_rng ( & mut rng, true ) ;
1142+ let start = Instant :: now ( ) ;
1143+ for proof in proofs. clone ( ) {
1144+ proof
1145+ . verify_with_randomized_pairing_checker (
1146+ & BTreeMap :: new ( ) ,
1147+ & challenge_verifier,
1148+ & keypair. public_key ,
1149+ & params,
1150+ & mut pairing_checker,
1151+ )
1152+ . unwrap ( ) ;
1153+ }
1154+ assert ! ( pairing_checker. verify( ) ) ;
1155+ println ! (
1156+ "Time to verify {} sigs using randomized pairing checker: {:?}" ,
1157+ sig_count,
1158+ start. elapsed( )
1159+ ) ;
1160+ }
10371161}
0 commit comments