Browse Source

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

Michele Orrù 3 weeks ago
parent
commit
0d8eecf2e7
1 changed files with 54 additions and 42 deletions
  1. 54 42
      cmz-core/src/lib.rs

+ 54 - 42
cmz-core/src/lib.rs

@@ -1314,44 +1314,58 @@ 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_instance_fields = cli_proof_pub_points
-        .iter()
-        .chain(cli_proof_const_points.iter())
-        .chain(cli_proof_cind_points.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();
-    };
-    let iss_cli_instance_fields = cli_proof_pub_points
-        .iter()
-        .chain(cli_proof_const_points.iter())
-        .chain(cli_proof_cind_points.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);
+    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);
         }
     };
+    if !cli_proof_is_empty {
+        let cli_instance_fields = cli_proof_pub_points
+            .iter()
+            .chain(cli_proof_const_points.iter())
+            .chain(cli_proof_cind_points.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();
+        };
+        let iss_cli_instance_fields = cli_proof_pub_points
+            .iter()
+            .chain(cli_proof_const_points.iter())
+            .chain(cli_proof_cind_points.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);
+            }
+        };
+    }
 
     // Build the Params struct, if we have params
     let params_struct = if has_params {
@@ -1551,7 +1565,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,)*
@@ -1620,9 +1636,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);
@@ -1767,9 +1781,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);