circom-compat icon indicating copy to clipboard operation
circom-compat copied to clipboard

Verification fails when using generated zkey

Open shekohex opened this issue 2 years ago • 4 comments

Hello, we are facing an issue when we use our generated zkey, the verification process fails, but using a randomly generated proving key from the circom circuit the verification process works without any issues.

I made a simple repo to reproduce that issue here: https://github.com/shekohex/webb-ark-circom-issue

Please follow the instructions in the README file.

shekohex avatar Jan 06 '23 12:01 shekohex

Any updates on this?

ItsFunny avatar Feb 07 '23 14:02 ItsFunny

Use Circom version <= 2.0.6 and it will work.

akileshtangella avatar Feb 28 '23 17:02 akileshtangella

I think you can actually do it with circom > 2.0.6, you just need to use create_random_proof_with_reduction with CircomReduction instead of create_random_proof, which uses LibsnarkReduction.

I used circom 2.1.5 to compile this multiplier circuit, then used snarkjs 0.6.10 to create a zkey.

Then, I tested it with this snippet using ark-circom ab7f9ec3a1202117981eb59854fa1aae2b1e4fee

use ark_circom::{CircomBuilder, CircomConfig, CircomReduction, read_zkey};
use ark_std::rand::thread_rng;
use color_eyre::Result;

use ark_bn254::Bn254;
use ark_groth16::{
  create_random_proof_with_reduction, prepare_verifying_key, verify_proof,
};

#[test]
#[cfg(feature = "circom-2")]
fn circom2_1_5_test() -> Result<()> {
  use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem};

  let cfg = CircomConfig::<Bn254>::new(
      "./test-vectors/multiplier_circom_2.1.5.wasm",
      "./test-vectors/multiplier_circom_2.1.5.r1cs",
  )?;
  let mut builder = CircomBuilder::new(cfg);
  builder.push_input("in1", 2);
  builder.push_input("in2", 2);

  let mut rng = thread_rng();
  let mut key_file = std::fs::File::open("./test-vectors/multiplier.zkey")?;
  let (params, _) = read_zkey(&mut key_file)?;

  let circom = builder.build()?;

  let cs = ConstraintSystem::<ark_bn254::Fr>::new_ref();
  circom.clone().generate_constraints(cs.clone()).unwrap();
  let is_satisfied = cs.is_satisfied().unwrap();
  assert!(is_satisfied);

  let inputs = circom.get_public_inputs().unwrap();

  let proof = create_random_proof_with_reduction::<Bn254, _, _, CircomReduction>(circom, &params, &mut rng)?;

  let pvk = prepare_verifying_key(&params.vk);

  let verified = verify_proof(&pvk, &proof, &inputs)?;

  assert!(verified);

  Ok(())
}

whyamiroot avatar Apr 07 '23 07:04 whyamiroot

Just a heads-up, the solution above works although the code is a bit different. Do what is told above, you can easily fill in the code changes (some functions now belong to Groth16, rather than being imported as a function) but the main trick is:

// using CircomReduction is important
type GrothBn254 = Groth16<Bn254, CircomReduction>;

erhant avatar Jul 21 '23 13:07 erhant