Skip to content

Commit bfc74f8

Browse files
committed
[Future work] WIPA work
1 parent a2f87dc commit bfc74f8

5 files changed

Lines changed: 85 additions & 69 deletions

File tree

src/crs.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::whisk::{from_bytes_g1affine, to_bytes_g1affine};
1212
use crate::N_BLINDERS;
1313

1414
/// crs_H, crs_G_t, crs_G_u
15-
pub const CRS_EXTRA_POINTS: usize = 3;
15+
pub const CRS_EXTRA_POINTS: usize = 3; // Should be 4
1616

1717
/// The Curdleproofs CRS
1818
#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
@@ -23,6 +23,7 @@ pub struct CurdleproofsCrs {
2323
pub vec_H: Vec<G1Affine>,
2424
/// Base used in the *SameScalar* argument
2525
pub H: G1Projective,
26+
// pub G: G1Projective
2627
/// Base used in the *SameScalar* argument
2728
pub G_t: G1Projective,
2829
/// Base used in the *SameScalar* argument
@@ -35,8 +36,8 @@ pub struct CurdleproofsCrs {
3536

3637
impl CurdleproofsCrs {
3738
pub fn from_points(ell: usize, points: &[G1Affine]) -> Result<Self, String> {
38-
let n = ell + N_BLINDERS;
39-
let num_points = n + CRS_EXTRA_POINTS;
39+
let n = ell + N_BLINDERS; // Do we need + N_BLINDERS in BP+?
40+
let num_points = n + CRS_EXTRA_POINTS;
4041
if points.len() < num_points {
4142
return Err("not enough points".to_owned());
4243
}
@@ -52,14 +53,15 @@ impl CurdleproofsCrs {
5253
H: points[n].into(),
5354
G_t: points[n + 1].into(),
5455
G_u: points[n + 2].into(),
56+
// G: points[n + 3].into(),
5557
G_sum,
5658
H_sum,
5759
})
5860
}
5961

6062
/// Generate a randomly generated (unsafe) CRS
6163
pub fn generate_crs(ell: usize) -> Self {
62-
let num_points = ell + N_BLINDERS + CRS_EXTRA_POINTS;
64+
let num_points = ell + N_BLINDERS + CRS_EXTRA_POINTS; // Again N_BLINDERS
6365
let mut rng = StdRng::seed_from_u64(0u64);
6466

6567
let points = iter::repeat_with(|| G1Projective::rand(&mut rng).into_affine())
@@ -81,6 +83,7 @@ pub struct CurdleproofsCrsHex {
8183
pub vec_G: Vec<G1AffineHex>,
8284
pub vec_H: Vec<G1AffineHex>,
8385
pub H: G1AffineHex,
86+
// pub G: G1AffineHex,
8487
pub G_t: G1AffineHex,
8588
pub G_u: G1AffineHex,
8689
pub G_sum: G1AffineHex,
@@ -94,6 +97,7 @@ impl TryFrom<&CurdleproofsCrs> for CurdleproofsCrsHex {
9497
vec_G: to_hex_g1affine_vec(&value.vec_G)?,
9598
vec_H: to_hex_g1affine_vec(&value.vec_H)?,
9699
H: to_hex_g1affine(&value.H.into())?,
100+
// G: to_hex_g1affine(&value.G.into())?,
97101
G_t: to_hex_g1affine(&value.G_t.into())?,
98102
G_u: to_hex_g1affine(&value.G_u.into())?,
99103
G_sum: to_hex_g1affine(&value.G_sum)?,
@@ -109,6 +113,7 @@ impl TryInto<CurdleproofsCrs> for &CurdleproofsCrsHex {
109113
vec_G: from_hex_g1affine_vec(&self.vec_G)?,
110114
vec_H: from_hex_g1affine_vec(&self.vec_H)?,
111115
H: from_hex_g1affine(&self.H)?.into(),
116+
// G: from_hex_g1affine(&self.G)?.into(),
112117
G_t: from_hex_g1affine(&self.G_t)?.into(),
113118
G_u: from_hex_g1affine(&self.G_u)?.into(),
114119
G_sum: from_hex_g1affine(&self.G_sum)?,

src/curdleproofs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ impl CurdleproofsProof {
9696
&crs.vec_G,
9797
&crs.vec_H,
9898
&crs.H,
99+
// &crs.G,
99100
A,
100101
M,
101102
&vec_a,

src/grand_product_argument.rs

Lines changed: 69 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,26 @@ use ark_ec::CurveGroup;
77
use ark_ff::{Field, One};
88
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write};
99
use ark_std::rand::RngCore;
10-
use ark_std::Zero;
11-
10+
use ark_std::{UniformRand, Zero};
11+
use itertools::iterate;
1212
use crate::transcript::CurdleproofsTranscript;
1313
use merlin::Transcript;
1414

1515
use crate::errors::ProofError;
16-
use crate::inner_product_argument::InnerProductProof;
16+
use crate::inner_product_argument::{InnerProductProof, WeightedInnerProductProof};
1717
use crate::msm_accumulator::MsmAccumulator;
18-
use crate::util::{generate_blinders, inner_product, msm};
18+
use crate::util::{generate_blinders, inner_product, msm, weighted_inner_product};
1919

2020
/// A GrandProduct proof object
21-
#[derive(Clone, Debug, CanonicalSerialize, CanonicalDeserialize)]
21+
#[derive(Clone, Debug)]
2222
pub struct GrandProductProof {
2323
C: G1Projective,
24+
25+
P: G1Projective,
2426

2527
r_p: Fr,
2628

27-
ipa_proof: InnerProductProof,
29+
wipa_proof: WeightedInnerProductProof,
2830
}
2931

3032
impl GrandProductProof {
@@ -44,6 +46,7 @@ impl GrandProductProof {
4446
crs_G_vec: &Vec<G1Affine>,
4547
crs_H_vec: &Vec<G1Affine>,
4648
crs_U: &G1Projective, // This is actually H in the paper
49+
crs_G: &G1Projective,
4750

4851
B: G1Projective,
4952
gprod_result: Fr,
@@ -73,15 +76,13 @@ impl GrandProductProof {
7376
}
7477

7578
let vec_c_blinders = generate_blinders(rng, n_blinders); // vec_r_c in the paper
76-
let C = msm(crs_G_vec, &vec_c) + msm(crs_H_vec, &vec_c_blinders);
77-
79+
7880
// Compute r_p
7981
let vec_r_b_plus_alpha: Vec<Fr> =
8082
vec_b_blinders.iter().map(|r_b_i| *r_b_i + alpha).collect();
8183
let r_p = inner_product(&vec_r_b_plus_alpha, &vec_c_blinders);
82-
83-
transcript.append(b"gprod_step2", &C);
8484
transcript.append(b"gprod_step2", &r_p);
85+
8586
let beta = transcript.get_and_append_challenge(b"gprod_beta");
8687
let beta_inv = beta.inverse().expect("beta must have an inverse");
8788

@@ -101,7 +102,7 @@ impl GrandProductProof {
101102
.map(|H_i| H_i.mul(beta_inv.pow([ell_plus_one])).into_affine())
102103
.collect();
103104

104-
// Build the new b' and d vectors
105+
// Build b' for the d vector
105106
let mut vec_b_prime: Vec<Fr> = Vec::with_capacity(ell);
106107
let mut pow_beta = beta;
107108
for b_i in vec_b.into_iter() {
@@ -124,45 +125,63 @@ impl GrandProductProof {
124125
.iter()
125126
.map(|f_i| beta.pow([ell_plus_one]) * f_i)
126127
.collect();
127-
128-
// Create D commitment
129-
let vec_alphabeta: Vec<Fr> = iter::repeat(alpha * (beta.pow([ell_plus_one])))
130-
.take(n_blinders)
131-
.collect();
132-
let D = B - msm(&vec_G_prime, &vec_beta_powers) + msm(&vec_H_prime, &vec_alphabeta);
133-
128+
134129
// Step 4
135130
// Build G
136131
let mut vec_G = crs_G_vec.clone();
137132
vec_G.extend(crs_H_vec);
138133
// Build G'
139134
vec_G_prime.extend(vec_H_prime);
140-
141-
let inner_prod =
135+
136+
let y = Fr::one();
137+
138+
let weighted_inner_prod =
142139
r_p * beta.pow([(ell + 1) as u64]) + gprod_result * beta.pow([ell as u64]) - Fr::one();
143140

144141
vec_c.extend(vec_c_blinders);
145142
vec_d.extend(vec_d_blinders);
143+
144+
let C = G1Projective::rand(rng);
145+
let D = G1Projective::rand(rng);
146+
147+
let wip = weighted_inner_product(&vec_c, &vec_d, y);
148+
149+
let alphawip = transcript.get_and_append_challenge(b"alphawip");
150+
151+
// P = <a * G> + <b_L * H_R> + c * g + alpha*h
152+
let g_z: G1Projective = *crs_G * wip;
153+
let h_alpha: G1Projective = *crs_U * alphawip;
154+
let gz_halpha: G1Projective = g_z + h_alpha;
155+
let c_G: G1Projective = (0..n)
156+
.map(|i| crs_G_vec[i] * vec_c[i])
157+
.fold(gz_halpha, |acc, x| acc + x);
158+
159+
let P = (0..n)
160+
.map(|i| crs_H_vec[i] * &vec_d[i])
161+
.fold(c_G, |acc, x:G1Projective| acc + x);
146162

147163
// Sanity checks
148-
debug_assert!(inner_product(&vec_c, &vec_d) == inner_prod); // check inner product
164+
debug_assert!(wip == weighted_inner_prod); // check inner product
149165
debug_assert!((msm(&vec_G, &vec_c) - C).is_zero()); // check C commitment
150166
debug_assert!((msm(&vec_G_prime, &vec_d) - D).is_zero()); // check D commitment
151167

152-
let ipa_proof = InnerProductProof::new(
168+
let wipa_proof = WeightedInnerProductProof::new(
153169
vec_G,
154170
vec_G_prime,
171+
crs_G,
155172
crs_U,
156-
C,
157-
D,
158-
inner_prod,
173+
P,
174+
wip,
159175
vec_c,
160176
vec_d,
177+
y,
178+
alphawip,
161179
transcript,
162180
rng,
163181
);
182+
164183

165-
GrandProductProof { C, r_p, ipa_proof }
184+
GrandProductProof { C, P, r_p, wipa_proof }
166185
}
167186

168187
/// Verify a GrandProduct proof
@@ -182,9 +201,11 @@ impl GrandProductProof {
182201

183202
crs_G_vec: &Vec<G1Affine>,
184203
crs_H_vec: &Vec<G1Affine>,
204+
crs_G: &G1Projective,
185205
crs_U: &G1Projective, // This is actually H in the paper
186206
crs_G_sum: &G1Affine,
187207
crs_H_sum: &G1Affine,
208+
P: &G1Projective,
188209

189210
B: G1Projective,
190211
gprod_result: Fr,
@@ -227,38 +248,26 @@ impl GrandProductProof {
227248
let mut vec_G = crs_G_vec.clone();
228249
vec_G.extend(crs_H_vec);
229250

230-
let inner_prod =
251+
let weightedInnerProduct =
231252
self.r_p * beta.pow([ell_plus_one]) + gprod_result * beta.pow([ell as u64]) - Fr::one();
232253

233-
self.ipa_proof.verify(
234-
&vec_G,
254+
let y = Fr::one();
255+
256+
self.wipa_proof.verify(
257+
crs_G_vec,
258+
crs_H_vec,
259+
crs_G,
235260
crs_U,
236-
self.C,
237-
D,
238-
inner_prod,
239-
vec_u,
261+
*P,
262+
weightedInnerProduct,
263+
y,
240264
transcript,
241265
msm_accumulator,
242266
rng,
243267
)?;
244268

245269
Ok(())
246270
}
247-
248-
pub fn serialize<W: Write>(&self, mut w: W) -> Result<(), SerializationError> {
249-
self.C.serialize_compressed(&mut w)?;
250-
self.r_p.serialize_compressed(&mut w)?;
251-
self.ipa_proof.serialize(&mut w)?;
252-
Ok(())
253-
}
254-
255-
pub fn deserialize<R: Read>(mut r: R, log2_n: usize) -> Result<Self, SerializationError> {
256-
Ok(Self {
257-
C: G1Projective::deserialize_compressed(&mut r)?,
258-
r_p: Fr::deserialize_compressed(&mut r)?,
259-
ipa_proof: InnerProductProof::deserialize(&mut r, log2_n)?,
260-
})
261-
}
262271
}
263272

264273
#[cfg(test)]
@@ -286,20 +295,25 @@ mod tests {
286295
.take(n_blinders)
287296
.collect();
288297
let crs_U = G1Projective::rand(&mut rng);
298+
let crs_G = G1Projective::rand(&mut rng);
289299
let crs_G_sum: G1Affine = sum_affine_points(&crs_G_vec);
290300
let crs_H_sum: G1Affine = sum_affine_points(&crs_H_vec);
291301

292302
let vec_b: Vec<Fr> = iter::repeat_with(|| rng.gen()).take(ell).collect();
293303
let vec_b_blinders = generate_blinders(&mut rng, n_blinders);
294304

295305
// Compute gprod result without the blinders
296-
let gprod_result = vec_b.iter().product();
306+
let mut gprod_result = Fr::one();
307+
for &b in &vec_b {
308+
gprod_result *= b;
309+
}
297310

298311
let B = msm(&crs_G_vec, &vec_b) + msm(&crs_H_vec, &vec_b_blinders);
299312

300313
let gprod_proof = GrandProductProof::new(
301314
&crs_G_vec,
302315
&crs_H_vec,
316+
&crs_G,
303317
&crs_U,
304318
B,
305319
gprod_result,
@@ -317,9 +331,11 @@ mod tests {
317331
.verify(
318332
&crs_G_vec,
319333
&crs_H_vec,
334+
&crs_G,
320335
&crs_U,
321336
&crs_G_sum,
322337
&crs_H_sum,
338+
&gprod_proof.P,
323339
B,
324340
gprod_result,
325341
n_blinders,
@@ -339,9 +355,11 @@ mod tests {
339355
.verify(
340356
&crs_G_vec,
341357
&crs_H_vec,
358+
&crs_G,
342359
&crs_U,
343360
&crs_G_sum,
344361
&crs_H_sum,
362+
&gprod_proof.P,
345363
B,
346364
gprod_result + Fr::one(),
347365
n_blinders,
@@ -359,9 +377,11 @@ mod tests {
359377
.verify(
360378
&crs_G_vec,
361379
&crs_H_vec,
380+
&crs_G,
362381
&crs_U,
363382
&crs_G_sum,
364383
&crs_H_sum,
384+
&gprod_proof.P,
365385
B.mul(Fr::rand(&mut rng)),
366386
gprod_result,
367387
n_blinders,

src/inner_product_argument.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub struct InnerProductProof {
3838
d_final: Fr,
3939
}
4040

41+
#[derive(Clone, Debug)]
4142
pub struct WeightedInnerProductProof {
4243
vec_L: Vec<G1Projective>,
4344
vec_R: Vec<G1Projective>,
@@ -669,7 +670,6 @@ impl WeightedInnerProductProof {
669670

670671
P: G1Projective, // no need for mut
671672
z: Fr,
672-
vec_u: Vec<Fr>,
673673
y: Fr,
674674

675675
transcript: &mut Transcript,
@@ -966,7 +966,6 @@ mod tests {
966966
&crs_H,
967967
P.clone(),
968968
z.clone(),
969-
vec_u.clone(),
970969
y_scalar.clone(),
971970
&mut transcript_verifier,
972971
&mut msm_accumulator,
@@ -989,7 +988,6 @@ mod tests {
989988
&crs_H,
990989
P.clone(),
991990
z + Fr::one(),
992-
vec_u.clone(),
993991
y_scalar.clone(),
994992
&mut transcript_verifier,
995993
&mut msm_accumulator,

0 commit comments

Comments
 (0)