Skip to content

Commit d62c0c8

Browse files
committed
Add docs and support for 16 bit chunks in SAVER
Signed-off-by: lovesh <lovesh.bond@gmail.com>
1 parent c9eec71 commit d62c0c8

35 files changed

+1230
-918
lines changed

bbs_plus/src/proof.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Proof of knowledge of the signature and corresponding messages as per section 4.5 of the paper
2-
//! https://eprint.iacr.org/2016/663.pdf
2+
//! <https://eprint.iacr.org/2016/663.pdf>
33
//! # Examples
44
//!
55
//! Creating proof of knowledge of signature and verifying it:

bbs_plus/src/setup.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,16 @@ macro_rules! impl_sig_params {
110110
/// Generate params by hashing a known string. The hash function is vulnerable to timing
111111
/// attack but since all this is public knowledge, it is fine.
112112
/// This is useful if people need to be convinced that the discrete log of group elements wrt each other is not known.
113-
pub fn new<D: Digest>(label: &[u8], n: usize) -> Self {
114-
// Need n+2 elements of signature group and 1 element of other group
115-
let mut sig_group_elems = Vec::with_capacity(n + 2);
113+
pub fn new<D: Digest>(label: &[u8], message_count: usize) -> Self {
114+
assert_ne!(message_count, 0);
115+
// Need message_count+2 elements of signature group and 1 element of other group
116+
let mut sig_group_elems = Vec::with_capacity(message_count + 2);
116117
// Group element by hashing `label`||`g1` as string.
117118
let g1 = projective_group_elem_from_try_and_incr::<E::$group_affine, D>(
118119
&to_bytes![label, " : g1".as_bytes()].unwrap(),
119120
);
120-
// h_0 and h[i] for i in 1 to n
121-
let mut h = cfg_into_iter!((0..=n))
121+
// h_0 and h[i] for i in 1 to message_count
122+
let mut h = cfg_into_iter!((0..=message_count))
122123
.map(|i| {
123124
projective_group_elem_from_try_and_incr::<E::$group_affine, D>(
124125
&to_bytes![label, " : h_".as_bytes(), i as u64].unwrap(),
@@ -148,11 +149,12 @@ macro_rules! impl_sig_params {
148149
}
149150

150151
/// Generate params using a random number generator
151-
pub fn generate_using_rng<R>(rng: &mut R, n: usize) -> Self
152+
pub fn generate_using_rng<R>(rng: &mut R, message_count: usize) -> Self
152153
where
153154
R: RngCore,
154155
{
155-
let h = (0..n)
156+
assert_ne!(message_count, 0);
157+
let h = (0..message_count)
156158
.into_iter()
157159
.map(|_| E::$group_projective::rand(rng))
158160
.collect::<Vec<E::$group_projective>>();

benches/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ ark-ff = { version = "^0.3.0", default-features = false }
1414
ark-ec = { version = "^0.3.0", default-features = false }
1515
ark-std = { version = "^0.3.0", default-features = false }
1616
ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "curve" ] }
17+
serde = { version = "1.0", default-features = false, features = ["derive"] }
18+
serde_with = { version = "1.10.0", default-features = false, features = ["macros"] }
19+
dock_crypto_utils = { default-features = false, path = "../utils" }
1720

1821
[dev-dependencies]
1922
criterion = "0.3"

benches/benches/schnorr_protocol.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ark_bls12_381::Bls12_381;
2+
use ark_ec::msm::VariableBaseMSM;
23
use ark_ec::PairingEngine;
34
use ark_ec::{AffineCurve, ProjectiveCurve};
45
use ark_ff::PrimeField;
@@ -8,12 +9,13 @@ use ark_std::{
89
rand::{rngs::StdRng, SeedableRng},
910
UniformRand,
1011
};
12+
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
13+
use dock_crypto_utils::serde_utils::*;
1114
use schnorr_pok::{
1215
error::SchnorrError, impl_proof_of_knowledge_of_discrete_log, SchnorrCommitment,
1316
};
14-
15-
use ark_ec::msm::VariableBaseMSM;
16-
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
17+
use serde::{Deserialize, Serialize};
18+
use serde_with::serde_as;
1719

1820
type Fr = <Bls12_381 as PairingEngine>::Fr;
1921

proof_system/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ ark-relations = { version = "^0.3.0", default-features = false }
3232
[dependencies.legogroth16]
3333
git = "https://github.com/lovesh/legogro16"
3434
#branch = "comm-wit"
35-
rev = '00dfaf6e75464b8a246db7912eeb48070d10e067'
35+
rev = '5bc5e4af466c1bb84a636e18002dcffeeb0d1899'
3636
default-features = false
3737

3838
[dev-dependencies]

proof_system/src/derived_params.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
//! Parameters derived from parameters during proof generation and verification. Used to prevent repeatedly creating these parameters.
2-
use crate::prelude::bound_check::BoundCheckProtocol;
1+
//! Parameters derived from other parameters during proof generation and verification. Used to prevent repeatedly
2+
//! creating these parameters.
3+
4+
use crate::sub_protocols::bound_check_legogroth16::BoundCheckProtocol;
35
use crate::sub_protocols::saver::SaverProtocol;
46
use ark_ec::PairingEngine;
57
use ark_std::{collections::BTreeMap, marker::PhantomData, vec, vec::Vec};
@@ -14,17 +16,23 @@ use saver::saver_groth16::{
1416
PreparedVerifyingKey as SaverPreparedVerifyingKey, VerifyingKey as SaverVerifyingKey,
1517
};
1618

19+
/// Allows creating a new derived parameter from reference to original parameter
1720
pub trait DerivedParams<'a, Ref, DP> {
1821
fn new_derived(orig: &Ref) -> DP;
1922
}
2023

2124
pub struct DerivedParamsTracker<'a, Ref: PartialEq, DP, E> {
25+
/// References to the original parameter to which the derivation is applied
2226
origs_ref: Vec<&'a Ref>,
27+
/// The newly created derived param. The key in the map is reference to the original parameter and serves
28+
/// as a unique identifier for the derived param.
2329
derived_params: BTreeMap<usize, DP>,
30+
/// Maps a statement identifier to a derived parameter identifier.
2431
derived_params_for_statement: BTreeMap<usize, usize>,
2532
phantom: PhantomData<E>,
2633
}
2734

35+
/// Maps statement identifiers to derived params
2836
pub struct StatementDerivedParams<DP> {
2937
derived_params: BTreeMap<usize, DP>,
3038
derived_params_for_statement: BTreeMap<usize, usize>,
@@ -42,11 +50,14 @@ where
4250
phantom: PhantomData,
4351
}
4452
}
53+
4554
pub fn find(&self, orig: &Ref) -> Option<usize> {
4655
self.origs_ref.iter().position(|v: &&Ref| **v == *orig)
4756
}
4857

49-
pub fn update_for_orig(&mut self, orig: &'a Ref, s_idx: usize) {
58+
/// Creates a new derived param for the statement index if need be else store the reference to
59+
/// old parameter.
60+
pub fn on_new_statement_idx(&mut self, orig: &'a Ref, s_idx: usize) {
5061
if let Some(k) = self.find(orig) {
5162
self.derived_params_for_statement.insert(s_idx, k);
5263
} else {
@@ -58,6 +69,7 @@ where
5869
}
5970
}
6071

72+
/// Finished tracking derived params, return map of statement to derived params
6173
pub fn finish(self) -> StatementDerivedParams<DP> {
6274
StatementDerivedParams {
6375
derived_params: self.derived_params,

proof_system/src/lib.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,30 @@
55
//! The idea is to represent each relation to be proved as a [`Statement`], and any relations between
66
//! [`Statement`]s as a [`MetaStatement`]. Both of these types contain public (known to both prover
77
//! and verifier) information and are contained in a [`ProofSpec`] whose goal is to unambiguously
8-
//! define what needs to be proven. The prover then uses a [`Witness`] per [`Statement`] and creates a
9-
//! [`StatementProof`] per [`Statement`]. All [`StatementProof`]s are grouped together in a [`Proof`]
10-
//! and the verifier then uses the [`ProofSpec`] and [`Proof`] to verify the proof. Currently it is
8+
//! define what needs to be proven. Some [`Statement`]s are specific to either the prover or the verifier
9+
//! as those protocols require prover and verifier to use different public parameters. An example is Groth16
10+
//! based SNARK protocols where the prover needs to have a proving key and the verifier needs to
11+
//! have a verifying key. Both the prover and verifier can know both the proving and verifying key but
12+
//! they don't need to thus for such protocols, there are different [`Statement`]s for prover and verifier,
13+
//! like [`SaverProver`] and [`SaverVerifier`] are statements for prover and verifier respectively,
14+
//! executing SAVER protocol.
15+
//! Several [`Statement`]s might need same public parameters like proving knowledge of several BBS+
16+
//! from the same signer, or verifiable encryption of several messages for the same decryptor. Its not
17+
//! very efficient to pass the same parameters to each [`Statement`] especially when using this code's WASM
18+
//! bindings as the same values will be serialized and deserialized every time. To avoid this, caller can
19+
//! put all such public parameters as [`SetupParams`] in an array and then reference those by their index
20+
//! while creating an [`Statement`]. This array of [`SetupParams`] is then included in the [`ProofSpec`]
21+
//! and used by the prover and verifier during proof creation and verification respectively.
22+
//!
23+
//! After creating the [`ProofSpec`], the prover uses a [`Witness`] per [`Statement`] and creates a
24+
//! corresponding [`StatementProof`]. All [`StatementProof`]s are grouped together in a [`Proof`].
25+
//! The verifier also creates its [`ProofSpec`] and uses it to verify the given proof. Currently it is
1126
//! assumed that there is one [`StatementProof`] per [`Statement`] and one [`Witness`] per [`Statement`]
1227
//! and [`StatementProof`]s appear in the same order in [`Proof`] as [`Statement`]s do in [`ProofSpec`].
28+
//!
1329
//! [`Statement`], [`Witness`] and [`StatementProof`] are enums whose variants will be entities from different
14-
//! protocols. Each of these protocols are variants of the enum [`SubProtocol`].
30+
//! protocols. Each of these protocols are variants of the enum [`SubProtocol`]. [`SubProtocol`]s can internally
31+
//! call other [`SubProtocol`]s, eg [`SaverProtocol`] invokes several [`SchnorrProtocol`]s
1532
//!
1633
//! Currently supports
1734
//! - proof of knowledge of a BBS+ signature and signed messages
@@ -38,18 +55,29 @@
3855
//! message satisfies some upper and lower bounds i.e. min <= signed message <= max. This is a range proof.
3956
//! - test `pok_of_bbs_plus_sig_and_verifiable_encryption` shows how to verifiably encrypt a message signed with BBS+ such
4057
//! that the verifier cannot decrypt it but still ensure that it is encrypted correctly for the specified decryptor.
58+
//! - test `pok_of_bbs_plus_sig_with_reusing_setup_params` shows proving knowledge of several BBS+ signatures
59+
//! using [`SetupParams`]s. Here the same signers are used in multiple signatures thus their public params
60+
//! can be put as a variant of enum [`SetupParams`]. Similarly test
61+
//! `pok_of_knowledge_in_pedersen_commitment_and_equality_with_commitment_key_reuse` shows use of [`SetupParams`]
62+
//! when the same commitment key is reused in several commitments and test `pok_of_bbs_plus_sig_and_verifiable_encryption_of_many_messages`
63+
//! shows use of [`SetupParams`] when several messages are used in verifiable encryption for the same decryptor.
4164
//!
4265
//! *Note*: This design is largely inspired from my work at Hyperledger Ursa.
4366
//!
4467
//! *Note*: The design is tentative and will likely change as more protocols are integrated.
4568
//!
4669
//! [`Statement`]: crate::statement::Statement
4770
//! [`MetaStatement`]: crate::meta_statement::MetaStatement
71+
//! [`SaverProver`]: crate::statement::saver::SaverProver
72+
//! [`SaverVerifier`]: crate::statement::saver::SaverVerifier
73+
//! [`SetupParams`]: crate::setup_params::SetupParams
4874
//! [`ProofSpec`]: crate::proof_spec::ProofSpec
4975
//! [`Witness`]: crate::witness::Witness
5076
//! [`StatementProof`]: crate::statement_proof::StatementProof
5177
//! [`Proof`]: crate::proof::Proof
5278
//! [`SubProtocol`]: crate::sub_protocols::SubProtocol
79+
//! [`SaverProtocol`]: crate::sub_protocols::saver::SaverProtocol
80+
//! [`SchnorrProtocol`]: crate::sub_protocols::schnorr::SchnorrProtocol
5381
5482
extern crate core;
5583

@@ -75,6 +103,6 @@ pub mod prelude {
75103
pub use crate::setup_params::*;
76104
pub use crate::statement::*;
77105
pub use crate::statement_proof::*;
78-
pub use crate::sub_protocols::*;
106+
pub use crate::sub_protocols::bound_check_legogroth16::generate_snark_srs_bound_check;
79107
pub use crate::witness::*;
80108
}

proof_system/src/meta_statement.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! Used to express relation between `Statement`s
2+
13
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError};
24
use ark_std::{
35
collections::BTreeSet,

proof_system/src/proof.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::sub_protocols::accumulator::{
2525
AccumulatorMembershipSubProtocol, AccumulatorNonMembershipSubProtocol,
2626
};
2727
use crate::sub_protocols::bbs_plus::PoKBBSSigG1SubProtocol;
28-
use crate::sub_protocols::bound_check::BoundCheckProtocol;
28+
use crate::sub_protocols::bound_check_legogroth16::BoundCheckProtocol;
2929
use crate::sub_protocols::saver::SaverProtocol;
3030
use crate::sub_protocols::schnorr::SchnorrProtocol;
3131
use dock_crypto_utils::hashing_utils::field_elem_from_try_and_incr;
@@ -91,7 +91,7 @@ where
9191
}
9292
}
9393

94-
// Prepare commitment keys for running Schnorr protocol
94+
// Prepare commitment keys for running Schnorr protocols of all statements.
9595
let (bound_check_comm, ek_comm, chunked_comm) = proof_spec.derive_commitment_keys()?;
9696

9797
let mut sub_protocols =
@@ -277,6 +277,7 @@ where
277277
if let Some(ctx) = &proof_spec.context {
278278
challenge_bytes.extend_from_slice(ctx);
279279
}
280+
280281
// Get each sub-protocol's challenge contribution
281282
for p in sub_protocols.iter() {
282283
p.challenge_contribution(&mut challenge_bytes)?;
@@ -312,7 +313,9 @@ where
312313
));
313314
}
314315

316+
// Prepare commitment keys for running Schnorr protocols of all statements.
315317
let (bound_check_comm, ek_comm, chunked_comm) = proof_spec.derive_commitment_keys()?;
318+
// Prepared required parameters for pairings
316319
let (derived_lego_vk, derived_gens, derived_ek, derived_saver_vk) =
317320
proof_spec.derive_prepared_parameters()?;
318321

proof_system/src/proof_spec.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ where
8181
}
8282

8383
/// Derive commitment keys for Schnorr protocol from public params. This is done to avoid
84-
/// creating them if the same public params are used in multiple statements.
84+
/// creating them if the same public params are used in multiple statements and is effectively a
85+
/// pre-processing step done for optimization.
8586
pub fn derive_commitment_keys(
8687
&self,
8788
) -> Result<
@@ -136,8 +137,9 @@ where
136137
_ => panic!("This should never happen"),
137138
};
138139

139-
derived_ek_comm.update_for_orig(enc_key, s_idx);
140-
derived_chunked_comm.update_for_orig(tuple_map.get(&s_idx).unwrap(), s_idx);
140+
derived_ek_comm.on_new_statement_idx(enc_key, s_idx);
141+
derived_chunked_comm
142+
.on_new_statement_idx(tuple_map.get(&s_idx).unwrap(), s_idx);
141143
}
142144
Statement::BoundCheckLegoGroth16Prover(_)
143145
| Statement::BoundCheckLegoGroth16Verifier(_) => {
@@ -150,7 +152,7 @@ where
150152
}
151153
_ => panic!("This should never happen"),
152154
};
153-
derived_bound_check_comm.update_for_orig(verifying_key, s_idx);
155+
derived_bound_check_comm.on_new_statement_idx(verifying_key, s_idx);
154156
}
155157
_ => (),
156158
}
@@ -163,7 +165,7 @@ where
163165
}
164166

165167
/// Derive prepared keys for performing pairings. This is done to avoid preparing the same
166-
/// parameters again.
168+
/// parameters again and is effectively a pre-processing step done for optimization.
167169
pub fn derive_prepared_parameters(
168170
&self,
169171
) -> Result<
@@ -188,17 +190,17 @@ where
188190
match statement {
189191
Statement::SaverVerifier(s) => {
190192
let gens = s.get_encryption_gens(&self.setup_params, s_idx)?;
191-
derived_gens.update_for_orig(gens, s_idx);
193+
derived_gens.on_new_statement_idx(gens, s_idx);
192194

193195
let enc_key = s.get_encryption_key(&self.setup_params, s_idx)?;
194-
derived_ek.update_for_orig(enc_key, s_idx);
196+
derived_ek.on_new_statement_idx(enc_key, s_idx);
195197

196198
let verifying_key = s.get_snark_verifying_key(&self.setup_params, s_idx)?;
197-
derived_saver_vk.update_for_orig(verifying_key, s_idx);
199+
derived_saver_vk.on_new_statement_idx(verifying_key, s_idx);
198200
}
199201
Statement::BoundCheckLegoGroth16Verifier(s) => {
200202
let verifying_key = s.get_verifying_key(&self.setup_params, s_idx)?;
201-
derived_lego_vk.update_for_orig(verifying_key, s_idx);
203+
derived_lego_vk.on_new_statement_idx(verifying_key, s_idx);
202204
}
203205
_ => (),
204206
}

0 commit comments

Comments
 (0)