Skip to content

Commit 934750c

Browse files
schoppmpcopybara-github
authored andcommitted
Create ZK prover / verifier at ShellVahe construction and re-use it across operations
PiperOrigin-RevId: 859700359
1 parent 745d549 commit 934750c

File tree

6 files changed

+86
-126
lines changed

6 files changed

+86
-126
lines changed

willow/src/shell/vahe.rs

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use merlin::Transcript as MerlinTranscript;
1919
use proofs_rust_proto::{RlweRelationProofListProto, RlweRelationProofProto};
2020
use proto_serialization_traits::{FromProto, ToProto};
2121
use protobuf::{proto, AsView};
22-
use rlwe_relation::{RlweRelationProof, RlweRelationProver, RlweRelationVerifier};
22+
use rlwe_relation::{RlweRelationProof, RlweRelationProverVerifier};
2323
use rlwe_relation_serialization::{rlwe_relation_proof_from_proto, rlwe_relation_proof_to_proto};
2424
use single_thread_hkdf::{compute_hkdf, Seed};
2525
use status::Status;
@@ -100,22 +100,22 @@ pub struct ShellVahe {
100100
ahe: ShellAhe,
101101
q: u128,
102102
public_seed: Seed,
103+
rlwe_zk: RlweRelationProverVerifier,
103104
}
104105

105106
impl ShellVahe {
106-
fn get_transcript_and_proof_seed(
107+
fn transcript_seed(&self) -> &[u8] {
108+
&self.public_seed.as_bytes()
109+
[single_thread_hkdf::seed_length()..2 * single_thread_hkdf::seed_length()]
110+
}
111+
112+
fn transcript(
107113
&self,
108114
operation_name: &'static [u8],
109-
) -> Result<(MerlinTranscript, Seed), status::StatusError> {
110-
let proof_seed = compute_hkdf(
111-
self.public_seed.as_bytes(),
112-
b"",
113-
&[operation_name, b"_proof_seed"].concat(),
114-
16,
115-
)?;
115+
) -> Result<MerlinTranscript, status::StatusError> {
116116
let mut transcript = MerlinTranscript::new(operation_name);
117-
transcript.append_message(b"public_seed:", self.public_seed.as_bytes());
118-
Ok((transcript, proof_seed))
117+
transcript.append_message(b"transcript_seed:", self.transcript_seed());
118+
Ok(transcript)
119119
}
120120
}
121121

@@ -155,14 +155,18 @@ impl AheBase for ShellVahe {
155155
context_string,
156156
b"",
157157
b"ShellVahe.public_seed",
158-
single_thread_hkdf::seed_length(),
158+
2 * single_thread_hkdf::seed_length(), // Separate seeds for transcripts and proofs.
159159
)?;
160160
let mut q = 1;
161161
for modulus in &config.qs {
162162
q *= *modulus as u128;
163163
}
164164
let ahe = ShellAhe::new(config, context_string)?;
165-
Ok(ShellVahe { ahe: ahe, q: q, public_seed: public_seed })
165+
let rlwe_zk = RlweRelationProverVerifier::new(
166+
&public_seed.as_bytes()[..single_thread_hkdf::seed_length()],
167+
ahe.num_coeffs(),
168+
);
169+
Ok(ShellVahe { ahe: ahe, q: q, public_seed: public_seed, rlwe_zk: rlwe_zk })
166170
}
167171

168172
fn aggregate_public_key_shares<'a>(
@@ -253,9 +257,8 @@ impl VerifiableKeyGen for ShellVahe {
253257
let rlwe_witness =
254258
RlweRelationProofWitness { r: &sk_share.0, e: &pk_share_error.0, v: &pk_wraparound };
255259

256-
let (mut transcript, proof_seed) = self.get_transcript_and_proof_seed(b"key_gen")?;
257-
let prover = RlweRelationProver::new(proof_seed.as_bytes(), self.ahe.num_coeffs());
258-
let key_gen_proof = prover.prove(&rlwe_statement, &rlwe_witness, &mut transcript)?;
260+
let mut transcript = self.transcript(b"key_gen")?;
261+
let key_gen_proof = self.rlwe_zk.prove(&rlwe_statement, &rlwe_witness, &mut transcript)?;
259262
Ok((sk_share, pk_share_b, ShellKeyGenProof(key_gen_proof)))
260263
}
261264
}
@@ -273,9 +276,8 @@ impl KeyGenVerify for ShellVahe {
273276
bound_e: 16,
274277
};
275278

276-
let (mut transcript, proof_seed) = self.get_transcript_and_proof_seed(b"key_gen")?;
277-
let verifier = RlweRelationVerifier::new(proof_seed.as_bytes(), self.ahe.num_coeffs());
278-
verifier.verify(&statement, &proof.0, &mut transcript)
279+
let mut transcript = self.transcript(b"key_gen")?;
280+
self.rlwe_zk.verify(&statement, &proof.0, &mut transcript)
279281
}
280282
}
281283

@@ -298,9 +300,8 @@ impl VerifiableEncrypt for ShellVahe {
298300
return Err(status::internal("Ciphertexts from encryption library are malformed."));
299301
}
300302

301-
let (mut transcript, proof_seed) = self.get_transcript_and_proof_seed(b"encryption")?;
303+
let mut transcript = self.transcript(b"encryption")?;
302304
transcript.append_message(b"nonce:", nonce);
303-
let prover = RlweRelationProver::new(proof_seed.as_bytes(), self.ahe.num_coeffs());
304305
let mut proof = vec![];
305306
for i in 0..num_polynomials {
306307
let rlwe_statement = RlweRelationProofStatement {
@@ -318,7 +319,7 @@ impl VerifiableEncrypt for ShellVahe {
318319
e: &metadata.error_e[i],
319320
v: &wraparounds[i],
320321
};
321-
proof.push(prover.prove(&rlwe_statement, &rlwe_witness, &mut transcript)?);
322+
proof.push(self.rlwe_zk.prove(&rlwe_statement, &rlwe_witness, &mut transcript)?);
322323
}
323324
Ok((ciphertext, ShellEncryptionProof(proof)))
324325
}
@@ -338,9 +339,8 @@ impl EncryptVerify for ShellVahe {
338339
));
339340
}
340341

341-
let (mut transcript, proof_seed) = self.get_transcript_and_proof_seed(b"encryption")?;
342+
let mut transcript = self.transcript(b"encryption")?;
342343
transcript.append_message(b"nonce:", nonce);
343-
let verifier = RlweRelationVerifier::new(proof_seed.as_bytes(), self.ahe.num_coeffs());
344344
for i in 0..num_polynomials {
345345
let statement = RlweRelationProofStatement {
346346
n: self.ahe.num_coeffs(),
@@ -352,7 +352,7 @@ impl EncryptVerify for ShellVahe {
352352
bound_r: 1,
353353
bound_e: 16,
354354
};
355-
verifier.verify(&statement, &proof.0[i], &mut transcript)?;
355+
self.rlwe_zk.verify(&statement, &proof.0[i], &mut transcript)?;
356356
}
357357
Ok(())
358358
}
@@ -375,9 +375,7 @@ impl VerifiablePartialDec for ShellVahe {
375375
));
376376
}
377377

378-
let (mut transcript, proof_seed) =
379-
self.get_transcript_and_proof_seed(b"partial_decryption")?;
380-
let prover = RlweRelationProver::new(proof_seed.as_bytes(), self.ahe.num_coeffs());
378+
let mut transcript = self.transcript(b"partial_decryption")?;
381379
let mut proof = vec![];
382380
for i in 0..num_polynomials {
383381
let rlwe_statement = RlweRelationProofStatement {
@@ -392,7 +390,7 @@ impl VerifiablePartialDec for ShellVahe {
392390
};
393391
let rlwe_witness =
394392
RlweRelationProofWitness { r: &sk.0, e: &errors[i], v: &wraparounds[i] };
395-
proof.push(prover.prove(&rlwe_statement, &rlwe_witness, &mut transcript)?);
393+
proof.push(self.rlwe_zk.prove(&rlwe_statement, &rlwe_witness, &mut transcript)?);
396394
}
397395
Ok((pd, ShellPartialDecProof(proof)))
398396
}
@@ -412,9 +410,7 @@ impl PartialDecVerify for ShellVahe {
412410
));
413411
}
414412

415-
let (mut transcript, proof_seed) =
416-
self.get_transcript_and_proof_seed(b"partial_decryption")?;
417-
let verifier = RlweRelationVerifier::new(proof_seed.as_bytes(), self.ahe.num_coeffs());
413+
let mut transcript = self.transcript(b"partial_decryption")?;
418414
for i in 0..num_polynomials {
419415
let statement = RlweRelationProofStatement {
420416
n: self.ahe.num_coeffs(),
@@ -426,7 +422,7 @@ impl PartialDecVerify for ShellVahe {
426422
bound_r: 1,
427423
bound_e: self.ahe.flood_bound()?,
428424
};
429-
verifier.verify(&statement, &proof.0[i], &mut transcript)?;
425+
self.rlwe_zk.verify(&statement, &proof.0[i], &mut transcript)?;
430426
}
431427
Ok(())
432428
}

willow/src/zk/linear_ip.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub fn inner_product(a: &[Scalar], b: &[Scalar]) -> Scalar {
4747
out
4848
}
4949

50-
fn common_setup(length: usize, parameter_seed: &[u8]) -> LinearInnerProductParameters {
50+
fn generate_params(length: usize, parameter_seed: &[u8]) -> LinearInnerProductParameters {
5151
use sha3::Sha3_512;
5252
LinearInnerProductParameters {
5353
n: length,
@@ -88,13 +88,13 @@ fn validate_and_append_point(
8888
}
8989
}
9090

91-
pub struct LinearInnerProductProver {
91+
pub struct LinearInnerProductProverVerifier {
9292
pub params: LinearInnerProductParameters,
9393
}
9494

95-
impl LinearInnerProductProver {
95+
impl LinearInnerProductProverVerifier {
9696
pub fn new(parameter_seed: &[u8], length: usize) -> Self {
97-
let params = common_setup(length, parameter_seed);
97+
let params = generate_params(length, parameter_seed);
9898
Self { params }
9999
}
100100

@@ -145,7 +145,7 @@ impl
145145
ZeroKnowledgeProver<
146146
LinearInnerProductProofStatement<Scalar>,
147147
LinearInnerProductProofWitness<Scalar>,
148-
> for LinearInnerProductProver
148+
> for LinearInnerProductProverVerifier
149149
{
150150
type Proof = LinearInnerProductProof;
151151

@@ -214,19 +214,8 @@ impl
214214
}
215215
}
216216

217-
pub struct LinearInnerProductVerifier {
218-
pub params: LinearInnerProductParameters,
219-
}
220-
221-
impl LinearInnerProductVerifier {
222-
pub fn new(parameter_seed: &[u8], length: usize) -> Self {
223-
let params = common_setup(length, parameter_seed);
224-
Self { params }
225-
}
226-
}
227-
228217
impl ZeroKnowledgeVerifier<LinearInnerProductProofStatement<Scalar>, LinearInnerProductProof>
229-
for LinearInnerProductVerifier
218+
for LinearInnerProductProverVerifier
230219
{
231220
fn verify(
232221
&self,
@@ -309,14 +298,14 @@ mod tests {
309298
let a: Vec<Scalar> = (1..5).map(|x| Scalar::from(x as u64)).collect();
310299
let mut rng = rand::thread_rng();
311300

312-
let prover = LinearInnerProductProver::new(b"42", a.len());
301+
let prover = LinearInnerProductProverVerifier::new(b"42", a.len());
313302
let delta_a = Scalar::random(&mut rng);
314303
let comm_a = prover.commit(&a, delta_a)?;
315304
let b: Vec<Scalar> = (5..9).map(|x| Scalar::from(x as u64)).collect();
316305
let c: Scalar = Scalar::from(5 + 12 + 21 + 32 as u64);
317306
let mut transcript = MerlinTranscript::new(b"linear_ip_zkp_test");
318307

319-
let verifier = LinearInnerProductVerifier::new(b"42", a.len());
308+
let verifier = LinearInnerProductProverVerifier::new(b"42", a.len());
320309
verify_eq!(prover.params.F, verifier.params.F)?;
321310
verify_eq!(prover.params.F_, verifier.params.F_)?;
322311
verify_eq!(prover.params.G, verifier.params.G)?;
@@ -339,15 +328,15 @@ mod tests {
339328
let r: Vec<_> = (0..a.len()).map(|_| Scalar::random(&mut rng)).collect();
340329
let mut transcript = MerlinTranscript::new(b"linear_ip_zkp_test");
341330

342-
let prover = LinearInnerProductProver::new(b"42", a.len());
331+
let prover = LinearInnerProductProverVerifier::new(b"42", a.len());
343332
let delta_a = Scalar::random(&mut rng);
344333
let comm_a = prover.commit(&a, delta_a)?;
345334
let delta_r = Scalar::random(&mut rng);
346335
let comm_r = prover.commit(&r, delta_r)?;
347336
let b: Vec<Scalar> = (5..9).map(|x| Scalar::from(x as u64)).collect();
348337
let c: Scalar = Scalar::from(5 + 12 + 21 + 32 + 1 as u64);
349338

350-
let verifier = LinearInnerProductVerifier::new(b"42", a.len());
339+
let verifier = LinearInnerProductProverVerifier::new(b"42", a.len());
351340
let statement = LinearInnerProductProofStatement { n: a.len(), b: b, c: c, comm_a: comm_a };
352341
let proof = prover.prove(
353342
&statement,

willow/src/zk/linear_ip_serialization.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ mod tests {
6767
use super::*;
6868
use curve25519_dalek::scalar::Scalar;
6969
use googletest::gtest;
70-
use linear_innerproduct::{LinearInnerProductProver, LinearInnerProductVerifier};
70+
use linear_innerproduct::LinearInnerProductProverVerifier;
7171
use merlin::Transcript as MerlinTranscript;
7272
use rand;
7373
use zk_traits::{
@@ -80,14 +80,14 @@ mod tests {
8080
let a: Vec<Scalar> = (1..5).map(|x| Scalar::from(x as u64)).collect();
8181
let mut rng = rand::thread_rng();
8282

83-
let prover = LinearInnerProductProver::new(b"42", a.len());
83+
let prover = LinearInnerProductProverVerifier::new(b"42", a.len());
8484
let delta_a = Scalar::random(&mut rng);
8585
let comm_a = prover.commit(&a, delta_a)?;
8686
let b: Vec<Scalar> = (5..9).map(|x| Scalar::from(x as u64)).collect();
8787
let c: Scalar = Scalar::from(5 + 12 + 21 + 32 as u64);
8888
let mut transcript = MerlinTranscript::new(b"linear_ip_zkp_test");
8989

90-
let verifier = LinearInnerProductVerifier::new(b"42", a.len());
90+
let verifier = LinearInnerProductProverVerifier::new(b"42", a.len());
9191
let statement = LinearInnerProductProofStatement { n: a.len(), b: b, c: c, comm_a: comm_a };
9292
let proof = prover.prove(
9393
&statement,

willow/src/zk/quadratic_ip.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,12 @@ fn validate_and_append_point(
9191
}
9292
}
9393

94-
pub struct QuadraticInnerProductProver {
94+
/// A single object that can both prove and verify quadratic inner product arguments.
95+
pub struct QuadraticInnerProductProverVerifier {
9596
pub params: QuadraticInnerProductParameters,
9697
}
9798

98-
impl QuadraticInnerProductProver {
99+
impl QuadraticInnerProductProverVerifier {
99100
fn new(parameter_seed: &[u8], length: usize) -> Self {
100101
let params = generate_params(length, parameter_seed);
101102
Self { params }
@@ -135,7 +136,7 @@ impl
135136
ZeroKnowledgeProver<
136137
QuadraticInnerProductProofStatement,
137138
QuadraticInnerProductProofWitness<Scalar>,
138-
> for QuadraticInnerProductProver
139+
> for QuadraticInnerProductProverVerifier
139140
{
140141
type Proof = QuadraticInnerProductProof;
141142

@@ -201,19 +202,8 @@ impl
201202
}
202203
}
203204

204-
pub struct QuadraticInnerProductVerifier {
205-
pub params: QuadraticInnerProductParameters,
206-
}
207-
208-
impl QuadraticInnerProductVerifier {
209-
fn new(parameter_seed: &[u8], length: usize) -> Self {
210-
let params = generate_params(length, parameter_seed);
211-
Self { params }
212-
}
213-
}
214-
215205
impl ZeroKnowledgeVerifier<QuadraticInnerProductProofStatement, QuadraticInnerProductProof>
216-
for QuadraticInnerProductVerifier
206+
for QuadraticInnerProductProverVerifier
217207
{
218208
fn verify(
219209
&self,
@@ -296,8 +286,8 @@ mod tests {
296286
let mut c: Scalar = Scalar::from(5 + 12 + 21 + 32 as u64);
297287
c += Scalar::from(142398865683096878195835365925000457236 as u128);
298288

299-
let prover = QuadraticInnerProductProver::new(b"42", a.len());
300-
let verifier = QuadraticInnerProductVerifier::new(b"42", a.len());
289+
let prover = QuadraticInnerProductProverVerifier::new(b"42", a.len());
290+
let verifier = QuadraticInnerProductProverVerifier::new(b"42", a.len());
301291

302292
let delta: Scalar = Scalar::from(42 as u64);
303293
let C = prover.commit(&a, &b, c, delta)?;
@@ -325,8 +315,8 @@ mod tests {
325315
let mut c: Scalar = Scalar::from(5 + 12 + 21 + 32 + 1 as u64);
326316
c += Scalar::from(142398865683096878195835365925000457236 as u128);
327317

328-
let prover = QuadraticInnerProductProver::new(b"42", a.len());
329-
let verifier = QuadraticInnerProductVerifier::new(b"42", a.len());
318+
let prover = QuadraticInnerProductProverVerifier::new(b"42", a.len());
319+
let verifier = QuadraticInnerProductProverVerifier::new(b"42", a.len());
330320

331321
let delta: Scalar = Scalar::from(42 as u64);
332322
let C = prover.commit(&a, &b, c, delta)?;

0 commit comments

Comments
 (0)