Browse Source

fix: omit the client proof when the statement has no content

Michele Orrù 3 weeks ago
parent
commit
8a7d44d201
1 changed files with 58 additions and 46 deletions
  1. 58 46
      cmz-core/src/lib.rs

+ 58 - 46
cmz-core/src/lib.rs

@@ -1345,9 +1345,21 @@ pub fn cmz_core(
         cli_proof_idmap.insert(("".to_string(), paramid.to_string()), scoped_param.clone());
     }
 
-    // The client will create a zero-knowledge proof
+    // The client will create a zero-knowledge proof, unless it has nothing to prove.
     let cli_proof_ident = format_ident!("cli_proof");
-    request_fields.push_bytevec(&cli_proof_ident);
+    let cli_proof_is_empty = cli_proof_statements.is_empty() && proto_spec.statements.is_empty();
+    if !cli_proof_is_empty {
+        request_fields.push_bytevec(&cli_proof_ident);
+    }
+    let cli_sessid_decl = if cli_proof_is_empty {
+        quote! {}
+    } else {
+        quote! {
+            let mut cli_proof_sessid: Vec<u8> = Vec::new();
+            cli_proof_sessid.extend(b"cli_");
+            cli_proof_sessid.extend(session_id);
+        }
+    };
     let cli_dedup_decls = cli_proof_dedup_points
         .iter()
         .map(|(id, peer)| quote! { cind dedup(#peer) #id })
@@ -1356,45 +1368,47 @@ pub fn cmz_core(
         .iter()
         .map(|(id, _)| id.clone())
         .collect::<Vec<_>>();
-    let cli_instance_fields = cli_proof_pub_points
-        .iter()
-        .chain(cli_proof_generator_points.iter())
-        .chain(cli_proof_const_points.iter())
-        .chain(cli_proof_cind_points.iter())
-        .chain(cli_proof_dedup_ids.iter())
-        .chain(cli_proof_pub_scalars.iter());
-    let cli_witness_fields = cli_proof_rand_scalars
-        .iter()
-        .chain(cli_proof_priv_scalars.iter());
-    prepare_code = quote! {
-        #prepare_code
-        let cli_proof_instance = client_proof::Instance {
-            #(#cli_instance_fields,)*
-        };
-        let cli_proof_witness = client_proof::Witness {
-            #(#cli_witness_fields,)*
+    if !cli_proof_is_empty {
+        let cli_instance_fields = cli_proof_pub_points
+            .iter()
+            .chain(cli_proof_generator_points.iter())
+            .chain(cli_proof_const_points.iter())
+            .chain(cli_proof_cind_points.iter())
+            .chain(cli_proof_dedup_ids.iter())
+            .chain(cli_proof_pub_scalars.iter());
+        let cli_witness_fields = cli_proof_rand_scalars
+            .iter()
+            .chain(cli_proof_priv_scalars.iter());
+        prepare_code = quote! {
+            #prepare_code
+            let cli_proof_instance = client_proof::Instance {
+                #(#cli_instance_fields,)*
+            };
+            let cli_proof_witness = client_proof::Witness {
+                #(#cli_witness_fields,)*
+            };
+            // If prove returns Err here, there's an actual bug.
+            let #cli_proof_ident = client_proof::prove(&cli_proof_instance,
+                &cli_proof_witness, &cli_proof_sessid, rng).unwrap();
         };
-        // If prove returns Err here, there's an actual bug.
-        let #cli_proof_ident = client_proof::prove(&cli_proof_instance,
-            &cli_proof_witness, &cli_proof_sessid, rng).unwrap();
-    };
-    let iss_cli_instance_fields = cli_proof_pub_points
-        .iter()
-        .chain(cli_proof_generator_points.iter())
-        .chain(cli_proof_const_points.iter())
-        .chain(cli_proof_cind_points.iter())
-        .chain(cli_proof_dedup_ids.iter())
-        .chain(cli_proof_pub_scalars.iter());
-    handle_code_post_fill = quote! {
-        #handle_code_post_fill
-        let cli_proof_instance = client_proof::Instance {
-            #(#iss_cli_instance_fields,)*
+        let iss_cli_instance_fields = cli_proof_pub_points
+            .iter()
+            .chain(cli_proof_generator_points.iter())
+            .chain(cli_proof_const_points.iter())
+            .chain(cli_proof_cind_points.iter())
+            .chain(cli_proof_dedup_ids.iter())
+            .chain(cli_proof_pub_scalars.iter());
+        handle_code_post_fill = quote! {
+            #handle_code_post_fill
+            let cli_proof_instance = client_proof::Instance {
+                #(#iss_cli_instance_fields,)*
+            };
+            if client_proof::verify(&cli_proof_instance,
+                &request.#cli_proof_ident, &cli_proof_sessid).is_err() {
+                return Err(CMZError::CliProofFailed);
+            }
         };
-        if client_proof::verify(&cli_proof_instance,
-            &request.#cli_proof_ident, &cli_proof_sessid).is_err() {
-            return Err(CMZError::CliProofFailed);
-        }
-    };
+    }
 
     // Build the Params struct, if we have params
     let params_struct = if has_params {
@@ -1594,7 +1608,9 @@ pub fn cmz_core(
         quote! { sigma_compiler_verifier }
     };
 
-    let cli_proof = {
+    let cli_proof = if cli_proof_is_empty {
+        quote! {}
+    } else {
         quote! {
             #cli_sigma_compiler_macro! { client_proof<Point>,
                 (#(rand #cli_proof_rand_scalars,)*
@@ -1666,9 +1682,7 @@ pub fn cmz_core(
                 #(#client_show_args)* #(#client_issue_args)* #client_params_arg)
                     -> Result<(Request, ClientState),CMZError> {
                 let bp = cmz_basepoints::<Point>();
-                let mut cli_proof_sessid: Vec<u8> = Vec::new();
-                cli_proof_sessid.extend(b"cli_");
-                cli_proof_sessid.extend(session_id);
+                #cli_sessid_decl
                 let mut iss_proof_sessid: Vec<u8> = Vec::new();
                 iss_proof_sessid.extend(b"iss_");
                 iss_proof_sessid.extend(session_id);
@@ -1813,9 +1827,7 @@ pub fn cmz_core(
                     Result<(),CMZError>
             {
                 let bp = cmz_basepoints::<Point>();
-                let mut cli_proof_sessid: Vec<u8> = Vec::new();
-                cli_proof_sessid.extend(b"cli_");
-                cli_proof_sessid.extend(session_id);
+                #cli_sessid_decl
                 let mut iss_proof_sessid: Vec<u8> = Vec::new();
                 iss_proof_sessid.extend(b"iss_");
                 iss_proof_sessid.extend(session_id);