Browse Source

Use `PrimeField` as generic bound across the codebase (#67)

Co-authored-by: Cesar Descalzo <cesar.descalzo2@gmail.com>
Co-authored-by: Antonio Mejías Gil <anmegi.95@gmail.com>
pull/4/head
Marti 4 months ago
committed by GitHub
parent
commit
a573c15b32
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
10 changed files with 131 additions and 137 deletions
  1. +64
    -64
      Cargo.lock
  2. +2
    -2
      benches/groth16.rs
  3. +13
    -12
      src/circom/builder.rs
  4. +16
    -20
      src/circom/circuit.rs
  5. +2
    -4
      src/circom/mod.rs
  6. +20
    -20
      src/circom/r1cs_reader.rs
  7. +5
    -5
      src/witness/witness_calculator.rs
  8. +2
    -2
      src/zkey.rs
  9. +5
    -5
      tests/groth16.rs
  10. +2
    -3
      tests/solidity.rs

+ 64
- 64
Cargo.lock

@ -317,13 +317,13 @@ dependencies = [
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.80"
version = "0.1.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -365,7 +365,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -478,9 +478,9 @@ dependencies = [
[[package]] [[package]]
name = "blake3" name = "blake3"
version = "1.5.1"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52"
checksum = "3d08263faac5cde2a4d52b513dadb80846023aade56fcd8fc99ba73ba8050e92"
dependencies = [ dependencies = [
"arrayref", "arrayref",
"arrayvec", "arrayvec",
@ -637,9 +637,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.104"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490"
checksum = "47de7e88bbbd467951ae7f5a6f34f70d1b4d9cfce53d5fd70f74ebe118b3db56"
dependencies = [ dependencies = [
"jobserver", "jobserver",
"libc", "libc",
@ -1070,12 +1070,12 @@ dependencies = [
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.20.9"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
dependencies = [ dependencies = [
"darling_core 0.20.9",
"darling_macro 0.20.9",
"darling_core 0.20.10",
"darling_macro 0.20.10",
] ]
[[package]] [[package]]
@ -1094,15 +1094,15 @@ dependencies = [
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.20.9"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
dependencies = [ dependencies = [
"fnv", "fnv",
"ident_case", "ident_case",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -1118,13 +1118,13 @@ dependencies = [
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.20.9"
version = "0.20.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [ dependencies = [
"darling_core 0.20.9",
"darling_core 0.20.10",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -1215,7 +1215,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -1259,9 +1259,9 @@ dependencies = [
[[package]] [[package]]
name = "document-features" name = "document-features"
version = "0.2.8"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95"
checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0"
dependencies = [ dependencies = [
"litrs", "litrs",
] ]
@ -1388,10 +1388,10 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"
dependencies = [ dependencies = [
"darling 0.20.9",
"darling 0.20.10",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -1546,7 +1546,7 @@ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"syn 2.0.68",
"syn 2.0.71",
"toml 0.7.8", "toml 0.7.8",
"walkdir", "walkdir",
] ]
@ -1564,7 +1564,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde_json", "serde_json",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -1590,7 +1590,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"strum", "strum",
"syn 2.0.68",
"syn 2.0.71",
"tempfile", "tempfile",
"thiserror", "thiserror",
"tiny-keccak", "tiny-keccak",
@ -1915,7 +1915,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -2239,9 +2239,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.29"
version = "0.14.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33"
checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -2854,7 +2854,7 @@ dependencies = [
"proc-macro-crate 1.3.1", "proc-macro-crate 1.3.1",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -2874,9 +2874,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]] [[package]]
name = "oorandom" name = "oorandom"
version = "11.1.3"
version = "11.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9"
[[package]] [[package]]
name = "open-fastrlp" name = "open-fastrlp"
@ -2926,7 +2926,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -3109,7 +3109,7 @@ dependencies = [
"phf_shared 0.11.2", "phf_shared 0.11.2",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -3147,7 +3147,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -3231,7 +3231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -3617,7 +3617,7 @@ dependencies = [
"rkyv_derive", "rkyv_derive",
"seahash", "seahash",
"tinyvec", "tinyvec",
"uuid 1.9.1",
"uuid 1.10.0",
] ]
[[package]] [[package]]
@ -3826,7 +3826,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde_derive_internals", "serde_derive_internals",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -3929,9 +3929,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.203"
version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -3959,13 +3959,13 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.203"
version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -3976,7 +3976,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -4289,9 +4289,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.68"
version = "2.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -4344,9 +4344,9 @@ dependencies = [
[[package]] [[package]]
name = "target-lexicon" name = "target-lexicon"
version = "0.12.14"
version = "0.12.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
@ -4481,9 +4481,9 @@ dependencies = [
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.1"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82"
checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
dependencies = [ dependencies = [
"tinyvec_macros", "tinyvec_macros",
] ]
@ -4521,7 +4521,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -4617,7 +4617,7 @@ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_edit 0.22.14",
"toml_edit 0.22.15",
] ]
[[package]] [[package]]
@ -4655,9 +4655,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.14"
version = "0.22.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1"
dependencies = [ dependencies = [
"indexmap 2.2.6", "indexmap 2.2.6",
"serde", "serde",
@ -4692,7 +4692,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -4902,9 +4902,9 @@ dependencies = [
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.9.1"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
[[package]] [[package]]
name = "valuable" name = "valuable"
@ -5113,7 +5113,7 @@ dependencies = [
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -5147,7 +5147,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -5874,7 +5874,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -5894,7 +5894,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.68",
"syn 2.0.71",
] ]
[[package]] [[package]]
@ -5938,9 +5938,9 @@ dependencies = [
[[package]] [[package]]
name = "zstd-sys" name = "zstd-sys"
version = "2.0.11+zstd.1.5.6"
version = "2.0.12+zstd.1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75652c55c0b6f3e6f12eb786fe1bc960396bf05a1eb3bf1f3691c3610ac2e6d4"
checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13"
dependencies = [ dependencies = [
"cc", "cc",
"pkg-config", "pkg-config",

+ 2
- 2
benches/groth16.rs

@ -4,7 +4,7 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion};
use ark_circom::{read_zkey, CircomReduction, WitnessCalculator}; use ark_circom::{read_zkey, CircomReduction, WitnessCalculator};
use ark_std::rand::thread_rng; use ark_std::rand::thread_rng;
use ark_bn254::Bn254;
use ark_bn254::{Bn254, Fr};
use ark_groth16::Groth16; use ark_groth16::Groth16;
use wasmer::Store; use wasmer::Store;
@ -39,7 +39,7 @@ fn bench_groth(c: &mut Criterion, num_validators: u32, num_constraints: u32) {
) )
.unwrap(); .unwrap();
let full_assignment = wtns let full_assignment = wtns
.calculate_witness_element::<Bn254, _>(&mut store, inputs, false)
.calculate_witness_element::<Fr, _>(&mut store, inputs, false)
.unwrap(); .unwrap();
let mut rng = thread_rng(); let mut rng = thread_rng();

+ 13
- 12
src/circom/builder.rs

@ -1,7 +1,8 @@
use ark_ec::pairing::Pairing;
use std::{fs::File, path::Path}; use std::{fs::File, path::Path};
use wasmer::Store; use wasmer::Store;
use ark_ff::PrimeField;
use super::{CircomCircuit, R1CS}; use super::{CircomCircuit, R1CS};
use num_bigint::BigInt; use num_bigint::BigInt;
@ -14,21 +15,21 @@ use crate::{
use color_eyre::Result; use color_eyre::Result;
#[derive(Debug)] #[derive(Debug)]
pub struct CircomBuilder<E: Pairing> {
pub cfg: CircomConfig<E>,
pub struct CircomBuilder<F: PrimeField> {
pub cfg: CircomConfig<F>,
pub inputs: HashMap<String, Vec<BigInt>>, pub inputs: HashMap<String, Vec<BigInt>>,
} }
// Add utils for creating this from files / directly from bytes // Add utils for creating this from files / directly from bytes
#[derive(Debug)] #[derive(Debug)]
pub struct CircomConfig<E: Pairing> {
pub r1cs: R1CS<E>,
pub struct CircomConfig<F: PrimeField> {
pub r1cs: R1CS<F>,
pub wtns: WitnessCalculator, pub wtns: WitnessCalculator,
pub store: Store, pub store: Store,
pub sanity_check: bool, pub sanity_check: bool,
} }
impl<E: Pairing> CircomConfig<E> {
impl<F: PrimeField> CircomConfig<F> {
pub fn new(wtns: impl AsRef<Path>, r1cs: impl AsRef<Path>) -> Result<Self> { pub fn new(wtns: impl AsRef<Path>, r1cs: impl AsRef<Path>) -> Result<Self> {
let mut store = Store::default(); let mut store = Store::default();
let wtns = WitnessCalculator::new(&mut store, wtns).unwrap(); let wtns = WitnessCalculator::new(&mut store, wtns).unwrap();
@ -56,10 +57,10 @@ impl CircomConfig {
} }
} }
impl<E: Pairing> CircomBuilder<E> {
impl<F: PrimeField> CircomBuilder<F> {
/// Instantiates a new builder using the provided WitnessGenerator and R1CS files /// Instantiates a new builder using the provided WitnessGenerator and R1CS files
/// for your circuit /// for your circuit
pub fn new(cfg: CircomConfig<E>) -> Self {
pub fn new(cfg: CircomConfig<F>) -> Self {
Self { Self {
cfg, cfg,
inputs: HashMap::new(), inputs: HashMap::new(),
@ -74,7 +75,7 @@ impl CircomBuilder {
/// Generates an empty circom circuit with no witness set, to be used for /// Generates an empty circom circuit with no witness set, to be used for
/// generation of the trusted setup parameters /// generation of the trusted setup parameters
pub fn setup(&self) -> CircomCircuit<E> {
pub fn setup(&self) -> CircomCircuit<F> {
let mut circom = CircomCircuit { let mut circom = CircomCircuit {
r1cs: self.cfg.r1cs.clone(), r1cs: self.cfg.r1cs.clone(),
witness: None, witness: None,
@ -88,11 +89,11 @@ impl CircomBuilder {
/// Creates the circuit populated with the witness corresponding to the previously /// Creates the circuit populated with the witness corresponding to the previously
/// provided inputs /// provided inputs
pub fn build(mut self) -> Result<CircomCircuit<E>> {
pub fn build(mut self) -> Result<CircomCircuit<F>> {
let mut circom = self.setup(); let mut circom = self.setup();
// calculate the witness // calculate the witness
let witness = self.cfg.wtns.calculate_witness_element::<E, _>(
let witness = self.cfg.wtns.calculate_witness_element::<F, _>(
&mut self.cfg.store, &mut self.cfg.store,
self.inputs, self.inputs,
self.cfg.sanity_check, self.cfg.sanity_check,
@ -102,7 +103,7 @@ impl CircomBuilder {
// sanity check // sanity check
debug_assert!({ debug_assert!({
use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem};
let cs = ConstraintSystem::<E::ScalarField>::new_ref();
let cs = ConstraintSystem::<F>::new_ref();
circom.clone().generate_constraints(cs.clone()).unwrap(); circom.clone().generate_constraints(cs.clone()).unwrap();
let is_satisfied = cs.is_satisfied().unwrap(); let is_satisfied = cs.is_satisfied().unwrap();
if !is_satisfied { if !is_satisfied {

+ 16
- 20
src/circom/circuit.rs

@ -1,20 +1,21 @@
use ark_ec::pairing::Pairing;
use ark_relations::r1cs::{ use ark_relations::r1cs::{
ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, SynthesisError, Variable, ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, SynthesisError, Variable,
}; };
use ark_ff::PrimeField;
use super::R1CS; use super::R1CS;
use color_eyre::Result; use color_eyre::Result;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CircomCircuit<E: Pairing> {
pub r1cs: R1CS<E>,
pub witness: Option<Vec<E::ScalarField>>,
pub struct CircomCircuit<F: PrimeField> {
pub r1cs: R1CS<F>,
pub witness: Option<Vec<F>>,
} }
impl<E: Pairing> CircomCircuit<E> {
pub fn get_public_inputs(&self) -> Option<Vec<E::ScalarField>> {
impl<F: PrimeField> CircomCircuit<F> {
pub fn get_public_inputs(&self) -> Option<Vec<F>> {
match &self.witness { match &self.witness {
None => None, None => None,
Some(w) => match &self.r1cs.wire_mapping { Some(w) => match &self.r1cs.wire_mapping {
@ -25,11 +26,8 @@ impl CircomCircuit {
} }
} }
impl<E: Pairing> ConstraintSynthesizer<E::ScalarField> for CircomCircuit<E> {
fn generate_constraints(
self,
cs: ConstraintSystemRef<E::ScalarField>,
) -> Result<(), SynthesisError> {
impl<F: PrimeField> ConstraintSynthesizer<F> for CircomCircuit<F> {
fn generate_constraints(self, cs: ConstraintSystemRef<F>) -> Result<(), SynthesisError> {
let witness = &self.witness; let witness = &self.witness;
let wire_mapping = &self.r1cs.wire_mapping; let wire_mapping = &self.r1cs.wire_mapping;
@ -37,7 +35,7 @@ impl ConstraintSynthesizer for CircomCircuit {
for i in 1..self.r1cs.num_inputs { for i in 1..self.r1cs.num_inputs {
cs.new_input_variable(|| { cs.new_input_variable(|| {
Ok(match witness { Ok(match witness {
None => E::ScalarField::from(1u32),
None => F::from(1u32),
Some(w) => match wire_mapping { Some(w) => match wire_mapping {
Some(m) => w[m[i]], Some(m) => w[m[i]],
None => w[i], None => w[i],
@ -49,7 +47,7 @@ impl ConstraintSynthesizer for CircomCircuit {
for i in 0..self.r1cs.num_aux { for i in 0..self.r1cs.num_aux {
cs.new_witness_variable(|| { cs.new_witness_variable(|| {
Ok(match witness { Ok(match witness {
None => E::ScalarField::from(1u32),
None => F::from(1u32),
Some(w) => match wire_mapping { Some(w) => match wire_mapping {
Some(m) => w[m[i + self.r1cs.num_inputs]], Some(m) => w[m[i + self.r1cs.num_inputs]],
None => w[i + self.r1cs.num_inputs], None => w[i + self.r1cs.num_inputs],
@ -65,12 +63,10 @@ impl ConstraintSynthesizer for CircomCircuit {
Variable::Witness(index - self.r1cs.num_inputs) Variable::Witness(index - self.r1cs.num_inputs)
} }
}; };
let make_lc = |lc_data: &[(usize, E::ScalarField)]| {
let make_lc = |lc_data: &[(usize, F)]| {
lc_data.iter().fold( lc_data.iter().fold(
LinearCombination::<E::ScalarField>::zero(),
|lc: LinearCombination<E::ScalarField>, (index, coeff)| {
lc + (*coeff, make_index(*index))
},
LinearCombination::<F>::zero(),
|lc: LinearCombination<F>, (index, coeff)| lc + (*coeff, make_index(*index)),
) )
}; };
@ -90,12 +86,12 @@ impl ConstraintSynthesizer for CircomCircuit {
mod tests { mod tests {
use super::*; use super::*;
use crate::{CircomBuilder, CircomConfig}; use crate::{CircomBuilder, CircomConfig};
use ark_bn254::{Bn254, Fr};
use ark_bn254::Fr;
use ark_relations::r1cs::ConstraintSystem; use ark_relations::r1cs::ConstraintSystem;
#[tokio::test] #[tokio::test]
async fn satisfied() { async fn satisfied() {
let cfg = CircomConfig::<Bn254>::new(
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/mycircuit.wasm", "./test-vectors/mycircuit.wasm",
"./test-vectors/mycircuit.r1cs", "./test-vectors/mycircuit.r1cs",
) )

+ 2
- 4
src/circom/mod.rs

@ -1,5 +1,3 @@
use ark_ec::pairing::Pairing;
pub mod r1cs_reader; pub mod r1cs_reader;
pub use r1cs_reader::{R1CSFile, R1CS}; pub use r1cs_reader::{R1CSFile, R1CS};
@ -12,5 +10,5 @@ pub use builder::{CircomBuilder, CircomConfig};
mod qap; mod qap;
pub use qap::CircomReduction; pub use qap::CircomReduction;
pub type Constraints<E> = (ConstraintVec<E>, ConstraintVec<E>, ConstraintVec<E>);
pub type ConstraintVec<E> = Vec<(usize, <E as Pairing>::ScalarField)>;
pub type Constraints<F> = (ConstraintVec<F>, ConstraintVec<F>, ConstraintVec<F>);
pub type ConstraintVec<F> = Vec<(usize, F)>;

+ 20
- 20
src/circom/r1cs_reader.rs

@ -1,11 +1,11 @@
//! R1CS circom file reader //! R1CS circom file reader
//! Copied from <https://github.com/poma/zkutil> //! Copied from <https://github.com/poma/zkutil>
//! Spec: <https://github.com/iden3/r1csfile/blob/master/doc/r1cs_bin_format.md> //! Spec: <https://github.com/iden3/r1csfile/blob/master/doc/r1cs_bin_format.md>
use ark_ff::PrimeField;
use byteorder::{LittleEndian, ReadBytesExt}; use byteorder::{LittleEndian, ReadBytesExt};
use std::io::{Error, ErrorKind}; use std::io::{Error, ErrorKind};
use ark_ec::pairing::Pairing;
use ark_serialize::{CanonicalDeserialize, SerializationError, SerializationError::IoError};
use ark_serialize::{SerializationError, SerializationError::IoError};
use ark_std::io::{Read, Seek, SeekFrom}; use ark_std::io::{Read, Seek, SeekFrom};
use std::collections::HashMap; use std::collections::HashMap;
@ -15,16 +15,16 @@ type IoResult = Result;
use super::{ConstraintVec, Constraints}; use super::{ConstraintVec, Constraints};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct R1CS<E: Pairing> {
pub struct R1CS<F> {
pub num_inputs: usize, pub num_inputs: usize,
pub num_aux: usize, pub num_aux: usize,
pub num_variables: usize, pub num_variables: usize,
pub constraints: Vec<Constraints<E>>,
pub constraints: Vec<Constraints<F>>,
pub wire_mapping: Option<Vec<usize>>, pub wire_mapping: Option<Vec<usize>>,
} }
impl<E: Pairing> From<R1CSFile<E>> for R1CS<E> {
fn from(file: R1CSFile<E>) -> Self {
impl<F: PrimeField> From<R1CSFile<F>> for R1CS<F> {
fn from(file: R1CSFile<F>) -> Self {
let num_inputs = (1 + file.header.n_pub_in + file.header.n_pub_out) as usize; let num_inputs = (1 + file.header.n_pub_in + file.header.n_pub_out) as usize;
let num_variables = file.header.n_wires as usize; let num_variables = file.header.n_wires as usize;
let num_aux = num_variables - num_inputs; let num_aux = num_variables - num_inputs;
@ -38,20 +38,20 @@ impl From> for R1CS {
} }
} }
pub struct R1CSFile<E: Pairing> {
pub struct R1CSFile<F: PrimeField> {
pub version: u32, pub version: u32,
pub header: Header, pub header: Header,
pub constraints: Vec<Constraints<E>>,
pub constraints: Vec<Constraints<F>>,
pub wire_mapping: Vec<u64>, pub wire_mapping: Vec<u64>,
} }
impl<E: Pairing> R1CSFile<E> {
impl<F: PrimeField> R1CSFile<F> {
/// reader must implement the Seek trait, for example with a Cursor /// reader must implement the Seek trait, for example with a Cursor
/// ///
/// ```rust,ignore /// ```rust,ignore
/// let reader = BufReader::new(Cursor::new(&data[..])); /// let reader = BufReader::new(Cursor::new(&data[..]));
/// ``` /// ```
pub fn new<R: Read + Seek>(mut reader: R) -> IoResult<R1CSFile<E>> {
pub fn new<R: Read + Seek>(mut reader: R) -> IoResult<R1CSFile<F>> {
let mut magic = [0u8; 4]; let mut magic = [0u8; 4];
reader.read_exact(&mut magic)?; reader.read_exact(&mut magic)?;
if magic != [0x72, 0x31, 0x63, 0x73] { if magic != [0x72, 0x31, 0x63, 0x73] {
@ -117,7 +117,7 @@ impl R1CSFile {
reader.seek(SeekFrom::Start(*constraint_offset?))?; reader.seek(SeekFrom::Start(*constraint_offset?))?;
let constraints = read_constraints::<&mut R, E>(&mut reader, &header)?;
let constraints = read_constraints::<&mut R, F>(&mut reader, &header)?;
let wire2label_offset = sec_offsets.get(&wire2label_type).ok_or_else(|| { let wire2label_offset = sec_offsets.get(&wire2label_type).ok_or_else(|| {
Error::new( Error::new(
@ -200,29 +200,29 @@ impl Header {
} }
} }
fn read_constraint_vec<R: Read, E: Pairing>(mut reader: R) -> IoResult<ConstraintVec<E>> {
fn read_constraint_vec<R: Read, F: PrimeField>(mut reader: R) -> IoResult<ConstraintVec<F>> {
let n_vec = reader.read_u32::<LittleEndian>()? as usize; let n_vec = reader.read_u32::<LittleEndian>()? as usize;
let mut vec = Vec::with_capacity(n_vec); let mut vec = Vec::with_capacity(n_vec);
for _ in 0..n_vec { for _ in 0..n_vec {
vec.push(( vec.push((
reader.read_u32::<LittleEndian>()? as usize, reader.read_u32::<LittleEndian>()? as usize,
E::ScalarField::deserialize_uncompressed(&mut reader)?,
F::deserialize_uncompressed(&mut reader)?,
)); ));
} }
Ok(vec) Ok(vec)
} }
fn read_constraints<R: Read, E: Pairing>(
fn read_constraints<R: Read, F: PrimeField>(
mut reader: R, mut reader: R,
header: &Header, header: &Header,
) -> IoResult<Vec<Constraints<E>>> {
) -> IoResult<Vec<Constraints<F>>> {
// todo check section size // todo check section size
let mut vec = Vec::with_capacity(header.n_constraints as usize); let mut vec = Vec::with_capacity(header.n_constraints as usize);
for _ in 0..header.n_constraints { for _ in 0..header.n_constraints {
vec.push(( vec.push((
read_constraint_vec::<&mut R, E>(&mut reader)?,
read_constraint_vec::<&mut R, E>(&mut reader)?,
read_constraint_vec::<&mut R, E>(&mut reader)?,
read_constraint_vec::<&mut R, F>(&mut reader)?,
read_constraint_vec::<&mut R, F>(&mut reader)?,
read_constraint_vec::<&mut R, F>(&mut reader)?,
)); ));
} }
Ok(vec) Ok(vec)
@ -251,7 +251,7 @@ fn read_map(mut reader: R, size: u64, header: &Header) -> IoResult
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use ark_bn254::{Bn254, Fr};
use ark_bn254::Fr;
use ark_std::io::{BufReader, Cursor}; use ark_std::io::{BufReader, Cursor};
#[test] #[test]
@ -309,7 +309,7 @@ mod tests {
); );
let reader = BufReader::new(Cursor::new(&data[..])); let reader = BufReader::new(Cursor::new(&data[..]));
let file = R1CSFile::<Bn254>::new(reader).unwrap();
let file = R1CSFile::<Fr>::new(reader).unwrap();
assert_eq!(file.version, 1); assert_eq!(file.version, 1);
assert_eq!(file.header.field_size, 32); assert_eq!(file.header.field_size, 32);

+ 5
- 5
src/witness/witness_calculator.rs

@ -1,4 +1,5 @@
use super::{fnv, CircomBase, SafeMemory, Wasm}; use super::{fnv, CircomBase, SafeMemory, Wasm};
use ark_ff::PrimeField;
use color_eyre::Result; use color_eyre::Result;
use num_bigint::BigInt; use num_bigint::BigInt;
use num_traits::Zero; use num_traits::Zero;
@ -284,17 +285,16 @@ impl WitnessCalculator {
} }
pub fn calculate_witness_element< pub fn calculate_witness_element<
E: ark_ec::pairing::Pairing,
F: PrimeField,
I: IntoIterator<Item = (String, Vec<BigInt>)>, I: IntoIterator<Item = (String, Vec<BigInt>)>,
>( >(
&mut self, &mut self,
store: &mut Store, store: &mut Store,
inputs: I, inputs: I,
sanity_check: bool, sanity_check: bool,
) -> Result<Vec<E::ScalarField>> {
use ark_ff::PrimeField;
) -> Result<Vec<F>> {
let modulus = F::MODULUS;
let witness = self.calculate_witness(store, inputs, sanity_check)?; let witness = self.calculate_witness(store, inputs, sanity_check)?;
let modulus = <E::ScalarField as PrimeField>::MODULUS;
// convert it to field elements // convert it to field elements
use num_traits::Signed; use num_traits::Signed;
@ -307,7 +307,7 @@ impl WitnessCalculator {
} else { } else {
w.to_biguint().unwrap() w.to_biguint().unwrap()
}; };
E::ScalarField::from(w)
F::from(w)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

+ 2
- 2
src/zkey.rs

@ -849,7 +849,7 @@ mod tests {
let mut file = File::open(path).unwrap(); let mut file = File::open(path).unwrap();
let (params, _matrices) = read_zkey(&mut file).unwrap(); // binfile.proving_key().unwrap(); let (params, _matrices) = read_zkey(&mut file).unwrap(); // binfile.proving_key().unwrap();
let cfg = CircomConfig::<Bn254>::new(
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/mycircuit.wasm", "./test-vectors/mycircuit.wasm",
"./test-vectors/mycircuit.r1cs", "./test-vectors/mycircuit.r1cs",
) )
@ -896,7 +896,7 @@ mod tests {
let s = ark_bn254::Fr::rand(rng); let s = ark_bn254::Fr::rand(rng);
let full_assignment = wtns let full_assignment = wtns
.calculate_witness_element::<Bn254, _>(&mut store, inputs, false)
.calculate_witness_element::<Fr, _>(&mut store, inputs, false)
.unwrap(); .unwrap();
let proof = Groth16::<Bn254, CircomReduction>::create_proof_with_reduction_and_matrices( let proof = Groth16::<Bn254, CircomReduction>::create_proof_with_reduction_and_matrices(
&params, &params,

+ 5
- 5
tests/groth16.rs

@ -2,7 +2,7 @@ use ark_circom::{CircomBuilder, CircomConfig};
use ark_std::rand::thread_rng; use ark_std::rand::thread_rng;
use color_eyre::Result; use color_eyre::Result;
use ark_bn254::Bn254;
use ark_bn254::{Bn254, Fr};
use ark_crypto_primitives::snark::SNARK; use ark_crypto_primitives::snark::SNARK;
use ark_groth16::Groth16; use ark_groth16::Groth16;
@ -10,7 +10,7 @@ type GrothBn = Groth16;
#[tokio::test] #[tokio::test]
async fn groth16_proof() -> Result<()> { async fn groth16_proof() -> Result<()> {
let cfg = CircomConfig::<Bn254>::new(
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/mycircuit.wasm", "./test-vectors/mycircuit.wasm",
"./test-vectors/mycircuit.r1cs", "./test-vectors/mycircuit.r1cs",
)?; )?;
@ -41,7 +41,7 @@ async fn groth16_proof() -> Result<()> {
#[tokio::test] #[tokio::test]
async fn groth16_proof_wrong_input() { async fn groth16_proof_wrong_input() {
let cfg = CircomConfig::<Bn254>::new(
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/mycircuit.wasm", "./test-vectors/mycircuit.wasm",
"./test-vectors/mycircuit.r1cs", "./test-vectors/mycircuit.r1cs",
) )
@ -63,7 +63,7 @@ async fn groth16_proof_wrong_input() {
#[tokio::test] #[tokio::test]
#[cfg(feature = "circom-2")] #[cfg(feature = "circom-2")]
async fn groth16_proof_circom2() -> Result<()> { async fn groth16_proof_circom2() -> Result<()> {
let cfg = CircomConfig::<Bn254>::new(
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/circom2_multiplier2.wasm", "./test-vectors/circom2_multiplier2.wasm",
"./test-vectors/circom2_multiplier2.r1cs", "./test-vectors/circom2_multiplier2.r1cs",
)?; )?;
@ -95,7 +95,7 @@ async fn groth16_proof_circom2() -> Result<()> {
#[tokio::test] #[tokio::test]
#[cfg(feature = "circom-2")] #[cfg(feature = "circom-2")]
async fn witness_generation_circom2() -> Result<()> { async fn witness_generation_circom2() -> Result<()> {
let cfg = CircomConfig::<Bn254>::new(
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/circom2_multiplier2.wasm", "./test-vectors/circom2_multiplier2.wasm",
"./test-vectors/circom2_multiplier2.r1cs", "./test-vectors/circom2_multiplier2.r1cs",
)?; )?;

+ 2
- 3
tests/solidity.rs

@ -2,7 +2,7 @@ use ark_circom::{ethereum, CircomBuilder, CircomConfig};
use ark_std::rand::thread_rng; use ark_std::rand::thread_rng;
use color_eyre::Result; use color_eyre::Result;
use ark_bn254::Bn254;
use ark_bn254::{Bn254, Fr};
use ark_crypto_primitives::snark::SNARK; use ark_crypto_primitives::snark::SNARK;
use ark_groth16::Groth16; use ark_groth16::Groth16;
@ -16,7 +16,7 @@ use std::{convert::TryFrom, sync::Arc};
#[tokio::test] #[tokio::test]
async fn solidity_verifier() -> Result<()> { async fn solidity_verifier() -> Result<()> {
let cfg = CircomConfig::<Bn254>::new(
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/mycircuit.wasm", "./test-vectors/mycircuit.wasm",
"./test-vectors/mycircuit.r1cs", "./test-vectors/mycircuit.r1cs",
)?; )?;
@ -61,7 +61,6 @@ async fn solidity_verifier() -> Result<()> {
// the ones expected by the abigen'd types. Could we maybe provide a convenience // the ones expected by the abigen'd types. Could we maybe provide a convenience
// macro for these, given that there's room for implementation error? // macro for these, given that there's room for implementation error?
abigen!(Groth16Verifier, "./tests/verifier_artifact.json"); abigen!(Groth16Verifier, "./tests/verifier_artifact.json");
use groth_16_verifier::{G1Point, G2Point, Proof, VerifyingKey};
impl From<ethereum::G1> for G1Point { impl From<ethereum::G1> for G1Point {
fn from(src: ethereum::G1) -> Self { fn from(src: ethereum::G1) -> Self {
Self { x: src.x, y: src.y } Self { x: src.x, y: src.y }

Loading…
Cancel
Save