Skip to content

Commit b5543e6

Browse files
committed
Randomized pairing checker, some helpers and refactoring
Signed-off-by: lovesh <lovesh.bond@gmail.com>
1 parent eb3bc88 commit b5543e6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1127
-514
lines changed

bbs_plus/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bbs_plus"
3-
version = "0.8.0"
3+
version = "0.9.0"
44
edition.workspace = true
55
authors.workspace = true
66
license.workspace = true
@@ -19,7 +19,7 @@ ark-std.workspace = true
1919
digest.workspace = true
2020
rayon = {workspace = true, optional = true}
2121
schnorr_pok = { version = "0.7.0", default-features = false, path = "../schnorr_pok" }
22-
dock_crypto_utils = { version = "0.5.0", default-features = false, path = "../utils" }
22+
dock_crypto_utils = { version = "0.6.0", default-features = false, path = "../utils" }
2323
serde.workspace = true
2424
serde_with.workspace = true
2525
zeroize.workspace = true

bbs_plus/src/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use serde::Serialize;
88

99
#[derive(Debug, Serialize)]
1010
pub enum BBSPlusError {
11+
CannotInvert0,
1112
NoMessageToSign,
1213
MessageCountIncompatibleWithSigParams(usize, usize),
1314
InvalidMessageIdx(usize),

bbs_plus/src/proof.rs

Lines changed: 163 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ use ark_std::{
7272
vec::Vec,
7373
One, UniformRand,
7474
};
75+
use dock_crypto_utils::randomized_pairing_check::RandomizedPairingChecker;
7576
use dock_crypto_utils::serde_utils::*;
7677
use schnorr_pok::{error::SchnorrError, SchnorrCommitment, SchnorrResponse};
7778
use 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
}

bbs_plus/src/setup.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//! ```
3131
3232
use crate::error::BBSPlusError;
33-
use ark_ec::{msm::VariableBaseMSM, AffineCurve, PairingEngine, ProjectiveCurve};
33+
use ark_ec::{AffineCurve, PairingEngine, ProjectiveCurve};
3434
use ark_ff::{to_bytes, PrimeField, SquareRootField};
3535
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError};
3636
use ark_std::collections::BTreeMap;
@@ -49,6 +49,7 @@ use zeroize::Zeroize;
4949
use dock_crypto_utils::hashing_utils::{
5050
field_elem_from_seed, projective_group_elem_from_try_and_incr,
5151
};
52+
use dock_crypto_utils::msm::variable_base_msm;
5253
use dock_crypto_utils::serde_utils::*;
5354

5455
#[cfg(feature = "parallel")]
@@ -207,10 +208,7 @@ macro_rules! impl_sig_params {
207208
blinding: &E::Fr,
208209
) -> Result<E::$group_affine, BBSPlusError> {
209210
#[cfg(feature = "parallel")]
210-
let (mut bases, mut scalars): (
211-
Vec<E::$group_affine>,
212-
Vec<<<E as ark_ec::PairingEngine>::Fr as PrimeField>::BigInt>,
213-
) = {
211+
let (mut bases, mut scalars): (Vec<E::$group_affine>, Vec<E::Fr>) = {
214212
// Need to manually check that no message index exceeds the maximum number of messages allowed
215213
// because this function can be called with only uncommitted messages; so size of BTreeMap is
216214
// not representative of the number of messages
@@ -220,12 +218,12 @@ macro_rules! impl_sig_params {
220218
}
221219
}
222220
cfg_into_iter!(messages)
223-
.map(|(i, msg)| (self.h[i].clone(), msg.into_repr()))
221+
.map(|(i, msg)| (self.h[i].clone(), *msg))
224222
.unzip()
225223
};
226224

227225
#[cfg(not(feature = "parallel"))]
228-
let (mut bases, mut scalars) = {
226+
let (mut bases, mut scalars): (Vec<E::$group_affine>, Vec<E::Fr>) = {
229227
let mut bases = Vec::with_capacity(messages.len());
230228
let mut scalars = Vec::with_capacity(messages.len());
231229
for (i, msg) in messages.into_iter() {
@@ -234,14 +232,14 @@ macro_rules! impl_sig_params {
234232
return Err(BBSPlusError::InvalidMessageIdx(i));
235233
}
236234
bases.push(self.h[i].clone());
237-
scalars.push(msg.into_repr());
235+
scalars.push(*msg);
238236
}
239237
(bases, scalars)
240238
};
241239

242240
bases.push(self.h_0.clone());
243-
scalars.push(blinding.into_repr());
244-
Ok(VariableBaseMSM::multi_scalar_mul(&bases, &scalars).into_affine())
241+
scalars.push(*blinding);
242+
Ok(variable_base_msm(&bases, &scalars).into_affine())
245243
}
246244

247245
/// Compute `b` from the paper (equivalently 'A*{e+x}').

bbs_plus/src/signature.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ macro_rules! impl_signature_alg {
230230

231231
let e = E::Fr::rand(rng);
232232
// 1/(e+x)
233-
let e_plus_x_inv = (e + sk.0).inverse().unwrap();
233+
let e_plus_x_inv = (e + sk.0).inverse().ok_or(BBSPlusError::CannotInvert0)?;
234234

235235
// {commitment + b} * {1/(e+x)}
236236
let commitment_plus_b = b.add_mixed(commitment);

benches/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ authors.workspace = true
66
license.workspace = true
77

88
[dependencies]
9-
bbs_plus = { version = "0.8.0", default-features = false, path = "../bbs_plus" }
9+
bbs_plus = { version = "0.9.0", default-features = false, path = "../bbs_plus" }
1010
schnorr_pok = { version = "0.7.0", default-features = false, path = "../schnorr_pok" }
11-
vb_accumulator = { version = "0.9.0", default-features = false, path = "../vb_accumulator" }
11+
vb_accumulator = { version = "0.10.0", default-features = false, path = "../vb_accumulator" }
1212
test_utils = { version = "0.1.0", default-features = false, path = "../test_utils" }
1313
ark-ff.workspace = true
1414
ark-ec.workspace = true

benches/benches/schnorr_protocol.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use ark_bls12_381::Bls12_381;
2-
use ark_ec::msm::VariableBaseMSM;
32
use ark_ec::PairingEngine;
43
use ark_ec::{AffineCurve, ProjectiveCurve};
54
use ark_ff::PrimeField;
@@ -74,11 +73,7 @@ macro_rules! bench_vector {
7473
.into_iter()
7574
.map(|_| Fr::rand(&mut rng))
7675
.collect::<Vec<_>>();
77-
let y = VariableBaseMSM::multi_scalar_mul(
78-
&bases,
79-
&witnesses.iter().map(|w| w.into_repr()).collect::<Vec<_>>(),
80-
)
81-
.into_affine();
76+
let y = variable_base_msm(&bases, &witnesses).into_affine();
8277
bases_vec.push(bases);
8378
witnesses_vec.push(witnesses);
8479
y_vec.push(y);

compressed_sigma/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "compressed_sigma"
3-
version = "0.0.1"
3+
version = "0.0.2"
44
edition.workspace = true
55
authors.workspace = true
66
license.workspace = true
@@ -15,7 +15,7 @@ ark-sponge = { version = "^0.3.0", default-features = false }
1515
ark-poly = { version = "^0.3.0", default-features = false }
1616
rayon = {workspace = true, optional = true}
1717
digest.workspace = true
18-
dock_crypto_utils = { version = "0.5.0", default-features = false, path = "../utils" }
18+
dock_crypto_utils = { version = "0.6.0", default-features = false, path = "../utils" }
1919

2020
[dev-dependencies]
2121
blake2.workspace = true

0 commit comments

Comments
 (0)