11//xxx example, not zk.
22
3+ use crate :: codec:: ByteSchnorrCodec ;
4+ use crate :: codec:: ShakeDuplexSponge ;
35use crate :: errors:: Error as ProofError ;
46use crate :: errors:: Result as ProofResult ;
7+ use crate :: fiat_shamir:: MultiRoundNizk ;
58use crate :: linear_relation;
69use crate :: serialization:: deserialize_elements;
710use crate :: serialization:: deserialize_scalars;
@@ -80,6 +83,9 @@ enum CompressedProofMessage<G: PrimeGroup> {
8083 IntermediateMessage ( [ G ; 2 ] ) ,
8184}
8285
86+ #[ derive( Clone ) ]
87+ struct CompressedWitness < G : PrimeGroup > ( Vec < G :: Scalar > ) ;
88+
8389impl < G : PrimeGroup > CompressedProofMessage < G > {
8490 fn new_from_intermediate_message ( intermediate_message : [ G ; 2 ] ) -> Self {
8591 Self :: IntermediateMessage ( intermediate_message)
@@ -91,19 +97,19 @@ impl<G: PrimeGroup> CompressedProofMessage<G> {
9197}
9298
9399impl < G : PrimeGroup > InteractiveProof for SquashedLinearRelation < G > {
94- type ProverState = ( Vec < G :: Scalar > , SquashedLinearRelation < G > ) ;
100+ type ProverState = ( CompressedWitness < G > , SquashedLinearRelation < G > ) ;
95101
96102 type ProverMessage = CompressedProofMessage < G > ;
97103
98104 type VerifierState = SquashedLinearRelation < G > ;
99105
100106 type Challenge = G :: Scalar ;
101107
102- type Witness = Vec < G :: Scalar > ;
108+ type Witness = CompressedWitness < G > ;
103109
104110 fn get_initial_prover_state ( & self , witness : & Self :: Witness ) -> Self :: ProverState {
105111 (
106- witness. to_vec ( ) ,
112+ witness. clone ( ) ,
107113 SquashedLinearRelation {
108114 generators : self . generators . clone ( ) ,
109115 image : self . image ,
@@ -124,23 +130,23 @@ impl<G: PrimeGroup> InteractiveProof for SquashedLinearRelation<G> {
124130 challenge : & Self :: Challenge ,
125131 ) -> Result < Self :: ProverMessage , ProofError > {
126132 let ( witness, statement) = state;
127- assert_eq ! ( witness. len( ) , statement. generators. len( ) ) ;
133+ assert_eq ! ( witness. 0 . len( ) , statement. generators. len( ) ) ;
128134 assert_eq ! (
129- G :: msm( & witness, & statement. generators) ,
135+ G :: msm( & witness. 0 , & statement. generators) ,
130136 statement. image,
131137 "Invalid witness"
132138 ) ;
133139 if statement. generators . len ( ) == 1 {
134- let computed = statement. generators [ 0 ] * witness[ 0 ] ;
135- let final_message = witness[ 0 ] ;
140+ let computed = statement. generators [ 0 ] * witness. 0 [ 0 ] ;
141+ let final_message = witness. 0 [ 0 ] ;
136142 assert_eq ! ( statement. image, computed) ;
137143 return Ok ( CompressedProofMessage :: new_from_final_message (
138144 final_message,
139145 ) ) ;
140146 }
141- let n = witness. len ( ) / 2 ;
142- let ( w_left, w_right) = witness. split_at ( n) ;
143- let ( g_left, g_right) = self . generators . split_at ( n) ;
147+ let n = witness. 0 . len ( ) / 2 ;
148+ let ( w_left, w_right) = witness. 0 . split_at ( n) ;
149+ let ( g_left, g_right) = statement . generators . split_at ( n) ;
144150
145151 // round messages
146152 let A = G :: msm_unchecked ( w_left, & g_right) ;
@@ -150,6 +156,7 @@ impl<G: PrimeGroup> InteractiveProof for SquashedLinearRelation<G> {
150156 let new_image = A + statement. image * challenge + B * challenge. square ( ) ;
151157 statement. generators = new_generators;
152158 statement. image = new_image;
159+ witness. 0 = new_witness;
153160
154161 Ok ( CompressedProofMessage :: new_from_intermediate_message ( [
155162 A , B ,
@@ -242,72 +249,6 @@ impl<G: PrimeGroup> InteractiveProof for SquashedLinearRelation<G> {
242249 }
243250}
244251
245- impl < G : PrimeGroup > SquashedLinearRelation < G > {
246- // XXX. We need to define a trait InteractiveProof for working with Fiat-Shamir, or rely on `spongefish`.
247- fn prove ( & self , witness : & [ G :: Scalar ] , xxx_challenges : & [ G :: Scalar ] ) -> ProofResult < Vec < u8 > > {
248- assert_eq ! ( witness. len( ) , self . generators. len( ) ) ;
249- assert_eq ! (
250- G :: msm( & witness, & self . generators) ,
251- self . image,
252- "Invalid witness"
253- ) ;
254-
255- if self . generators . len ( ) == 1 {
256- let computed = self . generators [ 0 ] * witness[ 0 ] ;
257- return Ok ( serialize_scalars :: < G > ( witness) ) ;
258- }
259-
260- let n = witness. len ( ) / 2 ;
261- let ( w_left, w_right) = witness. split_at ( n) ;
262- let ( g_left, g_right) = self . generators . split_at ( n) ;
263-
264- // round messages
265- let A = G :: msm_unchecked ( w_left, & g_right) ;
266- let B = G :: msm_unchecked ( w_right, & g_left) ;
267- let round_message = serialize_elements ( & [ A , B ] ) ;
268-
269- let challenge = xxx_challenges[ 0 ] ;
270- let new_witness = fold_scalars ( w_left, w_right, & G :: Scalar :: ONE , & challenge) ;
271- let new_generators = fold_generators ( g_left, g_right, & challenge, & G :: Scalar :: ONE ) ;
272- let new_image = A + self . image * challenge + B * challenge. square ( ) ;
273- let new_instance = SquashedLinearRelation {
274- generators : new_generators,
275- image : new_image,
276- } ;
277- let narg_string = new_instance. prove ( & new_witness, & xxx_challenges[ 1 ..] ) ?;
278-
279- Ok ( round_message. into_iter ( ) . chain ( narg_string) . collect ( ) )
280- }
281-
282- fn verify ( & self , narg_string : & [ u8 ] , xxx_challenges : & [ G :: Scalar ] ) -> ProofResult < ( ) > {
283- if self . generators . len ( ) == 1 {
284- let witness =
285- deserialize_scalars :: < G > ( narg_string, 1 ) . ok_or ( ProofError :: VerificationFailure ) ?;
286- let computed = self . generators [ 0 ] * witness[ 0 ] ;
287- if computed == self . image {
288- return Ok ( ( ) ) ;
289- } else {
290- return Err ( ProofError :: VerificationFailure ) ;
291- }
292- }
293-
294- let ( round_message, new_narg_string) =
295- read_elements :: < G > ( narg_string, 2 ) . ok_or ( ProofError :: VerificationFailure ) ?;
296- let [ A , B ] = [ round_message[ 0 ] , round_message[ 1 ] ] ;
297- let n = self . generators . len ( ) / 2 ;
298- let ( g_left, g_right) = self . generators . split_at ( n) ;
299- let challenge = xxx_challenges[ 0 ] ;
300-
301- let new_generators = fold_generators ( g_left, g_right, & challenge, & G :: Scalar :: ONE ) ;
302- let new_image = A + self . image * challenge + B * challenge. square ( ) ;
303- let new_instance = SquashedLinearRelation {
304- generators : new_generators,
305- image : new_image,
306- } ;
307- new_instance. verify ( new_narg_string, & xxx_challenges[ 1 ..] )
308- }
309- }
310-
311252#[ test]
312253fn test_compressed_bbs_nyms ( ) {
313254 use curve25519_dalek:: ristretto:: RistrettoPoint as G ;
@@ -370,7 +311,6 @@ fn test_compressed_bbs_nyms() {
370311 ) ;
371312 // the private witness
372313 let witness = [ ms. as_slice ( ) , & [ e] ] . concat ( ) ;
373- let round_challenges = ( 0 ..7 ) . map ( |_| Scalar :: random ( rng) ) . collect :: < Vec < _ > > ( ) ;
374314
375315 assert_eq ! (
376316 statement
@@ -382,12 +322,13 @@ fn test_compressed_bbs_nyms() {
382322 ) ;
383323 // All random challenges now
384324 let squashed_statement = statement. canonical ( ) . unwrap ( ) . squash ( challenge) ;
385-
386325 let witness_check = G :: msm ( & witness, & squashed_statement. generators ) ;
387- let narg_string = squashed_statement
388- . prove ( & witness, & round_challenges)
389- . unwrap ( ) ;
390- assert ! ( squashed_statement
391- . verify( & narg_string, & round_challenges)
392- . is_ok( ) ) ;
326+
327+ let multi_round_nizk: MultiRoundNizk <
328+ SquashedLinearRelation < G > ,
329+ ByteSchnorrCodec < G , ShakeDuplexSponge > ,
330+ > = MultiRoundNizk :: new ( "Pseudonym Proof" . as_bytes ( ) , squashed_statement) ;
331+ let ( prover_messages, _) = multi_round_nizk. prove ( & CompressedWitness ( witness) ) . unwrap ( ) ;
332+ let verification_result = multi_round_nizk. verify ( & prover_messages) ;
333+ assert ! ( verification_result. is_ok( ) ) ;
393334}
0 commit comments