You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.6 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. use ark_circom::{
  2. ethereum::{Inputs, Proof, VerifyingKey},
  3. CircomBuilder, CircomConfig,
  4. };
  5. use ark_std::rand::thread_rng;
  6. use color_eyre::Result;
  7. use ark_bn254::Bn254;
  8. use ark_groth16::{create_random_proof as prove, generate_random_parameters};
  9. use ethers::{
  10. contract::{abigen, ContractError, ContractFactory},
  11. providers::{Http, Middleware, Provider},
  12. utils::{compile_and_launch_ganache, Ganache, Solc},
  13. };
  14. use std::{convert::TryFrom, sync::Arc};
  15. #[tokio::test]
  16. async fn solidity_verifier() -> Result<()> {
  17. let cfg = CircomConfig::<Bn254>::new(
  18. "./test-vectors/mycircuit.wasm",
  19. "./test-vectors/mycircuit.r1cs",
  20. )?;
  21. let mut builder = CircomBuilder::new(cfg);
  22. builder.push_input("a", 3);
  23. builder.push_input("b", 11);
  24. // create an empty instance for setting it up
  25. let circom = builder.setup();
  26. let mut rng = thread_rng();
  27. let params = generate_random_parameters::<Bn254, _, _>(circom, &mut rng)?;
  28. let circom = builder.build()?;
  29. let inputs = circom.get_public_inputs().unwrap();
  30. let proof = prove(circom, &params, &mut rng)?;
  31. // launch the network & compile the verifier
  32. let (compiled, ganache) =
  33. compile_and_launch_ganache(Solc::new("./tests/verifier.sol"), Ganache::new()).await?;
  34. let acc = ganache.addresses()[0];
  35. let provider = Provider::<Http>::try_from(ganache.endpoint())?;
  36. let provider = provider.with_sender(acc);
  37. let provider = Arc::new(provider);
  38. // deploy the verifier
  39. let contract = {
  40. let contract = compiled
  41. .get("TestVerifier")
  42. .expect("could not find contract");
  43. let factory = ContractFactory::new(
  44. contract.abi.clone(),
  45. contract.bytecode.clone(),
  46. provider.clone(),
  47. );
  48. let contract = factory.deploy(())?.send().await?;
  49. let addr = contract.address();
  50. Groth16Verifier::new(addr, provider)
  51. };
  52. // check the proof
  53. let verified = contract
  54. .check_proof(proof, params.vk, inputs.as_slice())
  55. .await?;
  56. assert!(verified);
  57. Ok(())
  58. }
  59. abigen!(Groth16Verifier, "./tests/verifier_abi.json");
  60. impl<M: Middleware> Groth16Verifier<M> {
  61. async fn check_proof<I: Into<Inputs>, P: Into<Proof>, VK: Into<VerifyingKey>>(
  62. &self,
  63. proof: P,
  64. vk: VK,
  65. inputs: I,
  66. ) -> Result<bool, ContractError<M>> {
  67. // convert into the expected format by the contract
  68. let proof = proof.into().as_tuple();
  69. let vk = vk.into().as_tuple();
  70. let inputs = inputs.into().0;
  71. // query the contract
  72. let res = self.verify(inputs, proof, vk).call().await?;
  73. Ok(res)
  74. }
  75. }