Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.5 #68

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
97e8ee3
move to 0.5 alpha release
mmagician Jun 21, 2024
05b77f0
update mycircuit circom file and its r1cs output
mmagician Jul 13, 2024
284e60f
gitignore ptau files
mmagician Jul 13, 2024
021c269
deprecate circom1
mmagician Jul 13, 2024
44eae79
update safe circuit (circuit2) code
mmagician Jul 13, 2024
4861072
remove the test case as we no longer have circom to reproduce it
mmagician Jul 13, 2024
6e982e3
remove n_vars, no longer used as its implicit
mmagician Jul 13, 2024
79a070f
fix groth16 tests
mmagician Jul 13, 2024
94faeaf
provide full paths to wasm location
mmagician Jul 13, 2024
1c2e578
edit msg
mmagician Jul 13, 2024
bc2c1a5
remove unused files
mmagician Jul 17, 2024
0a8d371
removed unused `version` key from `rust-toolchain.toml`, use latest s…
mmagician Jul 17, 2024
7045748
use stable rust in CI
mmagician Jul 17, 2024
ad2a672
inline code
mmagician Jul 17, 2024
a6cde19
cargo update to catch the latest groth16 release
mmagician Jul 17, 2024
04d75b0
remove deprecated feature flag from CI
mmagician Jul 17, 2024
d8d18f8
Rust limitation no longer applies; warning about circom/arkworks diff
mmagician Jul 18, 2024
e3bfb81
release numbering consistency across arkworks
mmagician Jul 18, 2024
cdecd2f
add homepage & repo manifest fields
mmagician Jul 18, 2024
c54c0bc
Merge branch 'master' into release-0.5
mmagician Jul 19, 2024
83b3061
fix: Wasm compilation for wasm32-wasi target (#74)
CPerezz Aug 23, 2024
7fc7ff3
ignore cargo.lock
mmagician Sep 11, 2024
705dd7c
update wasix version
mmagician Sep 11, 2024
2e8051d
add a wasm compilation CI check
mmagician Sep 11, 2024
8fa65f0
Merge branch 'master' into release-0.5
mmagician Oct 28, 2024
b83b505
bump versions
mmagician Oct 28, 2024
4e86233
update crate reference in the README
mmagician Oct 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.75.0
toolchain: stable
override: true

# Install for Anvil
Expand All @@ -34,11 +34,6 @@ jobs:
export PATH=$HOME/bin:$PATH
cargo test

- name: cargo test circom 2 feature flag
run: |
export PATH=$HOME/bin:$PATH
cargo test --features circom-2

lint:
runs-on: ubuntu-latest
steps:
Expand All @@ -48,10 +43,25 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.75.0
toolchain: stable
override: true
components: rustfmt, clippy
- name: cargo fmt
run: cargo fmt --all -- --check
- name: cargo clippy
run: cargo clippy -- -D warnings

wasm32-wasip1-check:
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
target: wasm32-wasip1
- name: Check wasm32-wasip compilation
run: cargo check --target wasm32-wasip1 --no-default-features --features="wasm"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
Cargo.lock
*.ptau
32 changes: 17 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
[package]
name = "ark-circom"
version = "0.1.0"
version = "0.5.0"
edition = "2021"
description = "Arkworks bindings to Circom's R1CS, for Groth16 Proof and Witness generation in Rust"
homepage = "https://arkworks.rs"
repository = "https://github.com/arkworks-rs/circom-compat"
license = "MIT OR Apache-2.0"
resolver = "2"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
# WASM operations
wasmer = "4.4.0"
wasmer-wasix = { version = "0.28.0" }
wasmer = { version = "4.4.0", default-features = false }
wasmer-wasix = { version = "0.28.0", default-features = false }
fnv = { version = "1.0.7", default-features = false }
num = { version = "0.4.3" }
num-traits = { version = "0.2.16", default-features = false }
num-bigint = { version = "0.4.3", default-features = false, features = ["rand"] }

# ZKP Generation
ark-crypto-primitives = { version = "0.4.0" }
ark-ec = { version = "0.4.2", default-features = false, features = ["parallel"] }
ark-ff = { version = "0.4.2", default-features = false, features = ["parallel", "asm"] }
ark-std = { version = "0.4.0", default-features = false, features = ["parallel"] }
ark-bn254 = { version = "0.4.0" }
ark-groth16 = { version = "0.4.0", default-features = false, features = ["parallel"] }
ark-poly = { version = "0.4.2", default-features = false, features = ["parallel"] }
ark-relations = { version = "0.4.0", default-features = false }
ark-serialize = { version = "0.4.2", default-features = false }
ark-crypto-primitives = { version = "0.5.0" }
ark-ff = { version = "0.5.0", default-features = false, features = ["parallel", "asm"] }
ark-ec = { version = "0.5.0", default-features = false, features = ["parallel"] }
ark-std = { version = "0.5.0", default-features = false, features = ["parallel"] }
ark-bn254 = { version = "0.5.0" }
ark-groth16 = { version = "0.5.0", default-features = false, features = ["parallel"] }
ark-poly = { version = "0.5.0", default-features = false, features = ["parallel"] }
ark-relations = { version = "0.5.0", default-features = false }
ark-serialize = { version = "0.5.0", default-features = false }


# decoding of data
Expand Down Expand Up @@ -54,8 +57,7 @@ name = "groth16"
harness = false

[features]
default = ["wasmer/default", "circom-2", "ethereum"]
wasm = ["wasmer/js-default"]
default = ["wasmer/default", "ethereum", "wasmer-wasix/default"]
wasm = ["wasmer/js-default", "wasmer-wasix/js"]
bench-complex-all = []
circom-2 = []
ethereum = ["ethers-core"]
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Clone the repository and run `cd ark-circom/ && cargo doc --open`
```toml
[dependencies]

ark-circom = { git = "https://github.com/gakonst/ark-circom.git" }
ark-circom = "0.5.0"
```

## Example
Expand Down Expand Up @@ -66,6 +66,13 @@ Tests require the following installed:
- [x] Proof generations and verification using Arkworks
- [ ] CLI for common operations

## Notes

The prover key generated by circom differs from the one generated by arkworks' groth16 library. While the format is the same, it represents different values.
Circom 'prepares' the powers of tau by converting them to Lagrange base, i.e. from `s^i.G` -> `L_i(s).G`. This affects the witness generation process, and the caller needs to ensure the correct `R1CSToQAP` implementer is used:
- use [`CircomReduction`](https://github.com/arkworks-rs/circom-compat/blob/b892c62597687c23341cda1e8e89d58bb6428f36/src/circom/qap.rs#L12) for working with circom-generated files,
- use [`LibsnarkReduction`](https://github.com/arkworks-rs/groth16/blob/5272c935bda290a24cd18d0a3f994b0af70d5f27/src/r1cs_to_qap.rs#L101) for setup produced using the arkworks backend.

## Acknowledgements

This library would not have been possibly without the great work done in:
Expand Down
3 changes: 1 addition & 2 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
[toolchain]
channel = "stable"
version = "1.75.0"
channel = "stable"
2 changes: 1 addition & 1 deletion src/circom/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ mod tests {
#[tokio::test]
async fn satisfied() {
let cfg = CircomConfig::<Fr>::new(
"./test-vectors/mycircuit.wasm",
"./test-vectors/mycircuit_js/mycircuit.wasm",
"./test-vectors/mycircuit.r1cs",
)
.unwrap();
Expand Down
137 changes: 15 additions & 122 deletions src/witness/circom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,164 +7,57 @@ pub struct Wasm {
pub memory: Memory,
}

pub trait CircomBase {
fn init(&self, store: &mut Store, sanity_check: bool) -> Result<()>;
fn func(&self, name: &str) -> &Function;
fn get_n_vars(&self, store: &mut Store) -> Result<u32>;
fn get_u32(&self, store: &mut Store, name: &str) -> Result<u32>;
// Only exists natively in Circom2, hardcoded for Circom
fn get_version(&self, store: &mut Store) -> Result<u32>;
}

pub trait Circom1 {
fn get_ptr_witness(&self, store: &mut Store, w: u32) -> Result<u32>;
fn get_fr_len(&self, store: &mut Store) -> Result<u32>;
fn get_signal_offset32(
&self,
store: &mut Store,
p_sig_offset: u32,
component: u32,
hash_msb: u32,
hash_lsb: u32,
) -> Result<()>;
fn set_signal(
&self,
store: &mut Store,
c_idx: u32,
component: u32,
signal: u32,
p_val: u32,
) -> Result<()>;
fn get_ptr_raw_prime(&self, store: &mut Store) -> Result<u32>;
}

pub trait Circom2 {
fn get_field_num_len32(&self, store: &mut Store) -> Result<u32>;
fn get_raw_prime(&self, store: &mut Store) -> Result<()>;
fn read_shared_rw_memory(&self, store: &mut Store, i: u32) -> Result<u32>;
fn write_shared_rw_memory(&self, store: &mut Store, i: u32, v: u32) -> Result<()>;
fn set_input_signal(&self, store: &mut Store, hmsb: u32, hlsb: u32, pos: u32) -> Result<()>;
fn get_witness(&self, store: &mut Store, i: u32) -> Result<()>;
fn get_witness_size(&self, store: &mut Store) -> Result<u32>;
}

impl Circom1 for Wasm {
fn get_fr_len(&self, store: &mut Store) -> Result<u32> {
self.get_u32(store, "getFrLen")
}

fn get_ptr_raw_prime(&self, store: &mut Store) -> Result<u32> {
self.get_u32(store, "getPRawPrime")
}

fn get_ptr_witness(&self, store: &mut Store, w: u32) -> Result<u32> {
let func = self.func("getPWitness");

let res = func.call(store, &[w.into()])?;

Ok(res[0].unwrap_i32() as u32)
}

fn get_signal_offset32(
&self,
store: &mut Store,
p_sig_offset: u32,
component: u32,
hash_msb: u32,
hash_lsb: u32,
) -> Result<()> {
let func = self.func("getSignalOffset32");
func.call(
store,
&[
p_sig_offset.into(),
component.into(),
hash_msb.into(),
hash_lsb.into(),
],
)?;

Ok(())
}

fn set_signal(
&self,
store: &mut Store,
c_idx: u32,
component: u32,
signal: u32,
p_val: u32,
) -> Result<()> {
let func = self.func("setSignal");
func.call(
store,
&[c_idx.into(), component.into(), signal.into(), p_val.into()],
)?;

Ok(())
}
}

#[cfg(feature = "circom-2")]
impl Circom2 for Wasm {
fn get_field_num_len32(&self, store: &mut Store) -> Result<u32> {
impl Wasm {
pub(crate) fn get_field_num_len32(&self, store: &mut Store) -> Result<u32> {
self.get_u32(store, "getFieldNumLen32")
}

fn get_raw_prime(&self, store: &mut Store) -> Result<()> {
pub(crate) fn get_raw_prime(&self, store: &mut Store) -> Result<()> {
let func = self.func("getRawPrime");
func.call(store, &[])?;
Ok(())
}

fn read_shared_rw_memory(&self, store: &mut Store, i: u32) -> Result<u32> {
pub(crate) fn read_shared_rw_memory(&self, store: &mut Store, i: u32) -> Result<u32> {
let func = self.func("readSharedRWMemory");
let result = func.call(store, &[i.into()])?;
Ok(result[0].unwrap_i32() as u32)
}

fn write_shared_rw_memory(&self, store: &mut Store, i: u32, v: u32) -> Result<()> {
pub(crate) fn write_shared_rw_memory(&self, store: &mut Store, i: u32, v: u32) -> Result<()> {
let func = self.func("writeSharedRWMemory");
func.call(store, &[i.into(), v.into()])?;
Ok(())
}

fn set_input_signal(&self, store: &mut Store, hmsb: u32, hlsb: u32, pos: u32) -> Result<()> {
pub(crate) fn set_input_signal(
&self,
store: &mut Store,
hmsb: u32,
hlsb: u32,
pos: u32,
) -> Result<()> {
let func = self.func("setInputSignal");
func.call(store, &[hmsb.into(), hlsb.into(), pos.into()])?;
Ok(())
}

fn get_witness(&self, store: &mut Store, i: u32) -> Result<()> {
pub(crate) fn get_witness(&self, store: &mut Store, i: u32) -> Result<()> {
let func = self.func("getWitness");
func.call(store, &[i.into()])?;
Ok(())
}

fn get_witness_size(&self, store: &mut Store) -> Result<u32> {
pub(crate) fn get_witness_size(&self, store: &mut Store) -> Result<u32> {
self.get_u32(store, "getWitnessSize")
}
}

impl CircomBase for Wasm {
fn init(&self, store: &mut Store, sanity_check: bool) -> Result<()> {
pub(crate) fn init(&self, store: &mut Store, sanity_check: bool) -> Result<()> {
let func = self.func("init");
func.call(store, &[Value::I32(sanity_check as i32)])?;
Ok(())
}

fn get_n_vars(&self, store: &mut Store) -> Result<u32> {
self.get_u32(store, "getNVars")
}

// Default to version 1 if it isn't explicitly defined
fn get_version(&self, store: &mut Store) -> Result<u32> {
match self.exports.get_function("getVersion") {
Ok(func) => Ok(func.call(store, &[])?[0].unwrap_i32() as u32),
Err(_) => Ok(1),
}
}

fn get_u32(&self, store: &mut Store, name: &str) -> Result<u32> {
let func = &self.func(name);
let result = func.call(store, &[])?;
Expand Down
6 changes: 0 additions & 6 deletions src/witness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,8 @@ mod memory;
pub(super) use memory::SafeMemory;

mod circom;
pub(super) use circom::CircomBase;
pub use circom::Wasm;

#[cfg(feature = "circom-2")]
pub(super) use circom::Circom2;

pub(super) use circom::Circom1;

use fnv::FnvHasher;
use std::hash::Hasher;

Expand Down
Loading
Loading