Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 49 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Continuous Benchmarking

on:
push:
branches:
- main
pull_request:
branches:
- main

permissions:
contents: write
pull-requests: write

jobs:
benchmark:
name: Run Benchmarks
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Run Full Benchmark Suite (on main)
if: github.event_name == 'push'
run: cargo bench -- --nocapture --output-format bencher > output.txt

- name: Run Lighter Benchmark Suite (on PR)
if: github.event_name == 'pull_request'
env:
CORE_BENCHMARKS: '1'
run: cargo bench --bench zip_benches -- --nocapture --output-format bencher > output.txt

- name: Post Benchmark Results on PR
if: github.event_name == 'pull_request'
uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4
with:
tool: 'cargo'
output-file-path: 'output.txt'
github-token: ${{ secrets.GITHUB_TOKEN }}
comment-on-alert: true

- name: Save Benchmark History
if: github.event_name == 'push'
uses: benchmark-action/github-action-benchmark@d48d326b4ca9ba73ca0cd0d59f108f9e02a381c7 # v1.20.4
with:
tool: 'cargo'
output-file-path: 'output.txt'
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@ itertools = "0.14.0"
num-bigint = "0.4.6"
num-integer = "0.1.46"
num-traits = "0.2.19"
p3-commit = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4", features = [] }
p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-util = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
rand = "0.9.2"
rayon = { version = "1.10.0", optional = true }
serde = { version = "1.0", features = ["derive"] }
sha3 = "0.10.8"
thiserror = "2.0.12"
zeroize = "1.8.1"
p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-commit = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-util = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4" }
p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3.git", rev = "5ebf8e4", features = [] }
transpose = "0.2.3"
serde = { version = "1.0", features = ["derive"] }
uninit = "0.6.2"
zeroize = "1.8.1"

[dev-dependencies]
criterion = "0.7.0"
Expand Down
54 changes: 43 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
# **Zinc**


_Zinc_ is a proof-of-concept implementation of a novel SNARK system engineered by [Nethermind Research](https://www.nethermind.io/nethermind-research), based on [Zinc: Succinct Arguments with Small Arithmetization
_Zinc_ is a proof-of-concept implementation of a novel SNARK system engineered
by [Nethermind Research](https://www.nethermind.io/nethermind-research), based
on [Zinc: Succinct Arguments with Small Arithmetization
Overheads from IOPs of Proximity to the Integers](https://eprint.iacr.org/2025/316) by
Albert Garreta, Hendrik Waldner, Katerina Hristova and Luca Dall'Ava.

The primary goal of _Zinc_ is to address a significant performance bottleneck in modern zero-knowledge proof systems, specifically the high cost of arithmetization.
The primary goal of _Zinc_ is to address a significant performance bottleneck in modern zero-knowledge proof systems,
specifically the high cost of arithmetization.

⚠️ **Disclaimer:** This is a proof-of-concept prototype.
This implementation is provided for research and evaluation purposes. It has not undergone a formal security audit or comprehensive code review and is NOT ready for production use. Use at your own risk.

This implementation is provided for research and evaluation purposes. It has not undergone a formal security audit or
comprehensive code review and is NOT ready for production use. Use at your own risk.

## **Repository Structure**

The Zinc codebase is organized into several distinct modules, each responsible for a core component of the cryptographic system.
The Zinc codebase is organized into several distinct modules, each responsible for a core component of the cryptographic
system.

| Path | Description |
|:--------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Expand All @@ -33,9 +36,9 @@ Follow these instructions to build, test and benchmark the Zinc library.
### **Prerequisites**

Ensure you have the following installed:
- **Rust**: Install Rust using [rustup](https://rustup.rs/).
- **git**: Ensure you have Git installed to clone the repository.

- **Rust**: Install Rust using [rustup](https://rustup.rs/).
- **git**: Ensure you have Git installed to clone the repository.

### **Building the Library**

Expand All @@ -49,7 +52,8 @@ cargo build --release

#### **Building the Library with parallelization enabled**

For improved performance on multicore systems, you can enable parallelization by using the `parallel` feature flag, which uses Rayon for parallel processing.
For improved performance on multicore systems, you can enable parallelization by using the `parallel` feature flag,
which uses Rayon for parallel processing.

```bash
cargo build --release --features "parallel"
Expand All @@ -63,25 +67,53 @@ cargo test --release

### **Running Benchmarks**

The repository includes a suite of benchmarks using Criterion.rs. To run the benchmarks, execute:
The repository includes a suite of benchmarks using Criterion.rs. You can run the full suite or a lighter, core subset (
used in CI for pull requests).

- Full local run (all benches):

```bash
cargo bench
```

- Core subset only (fast):

```bash
CORE_BENCHMARKS=1 cargo bench --bench zip_benches
```

Notes:

- The environment variable `CORE_BENCHMARKS=1` switches zip_benches.rs into a reduced set of cases for faster iteration.
- We pass `--output-format bencher` to produce output compatible with our CI reporting.

#### CI Benchmarking

Our GitHub Actions workflow runs benchmarks automatically:

- On pushes to `main`: the full benchmark suite (`cargo bench -- --nocapture --output-format bencher`), and saves
history via benchmark-action.
- On pull requests: a lighter suite focused on the Zip PCS (
`CORE_BENCHMARKS=1 cargo bench --bench zip_benches -- --nocapture --output-format bencher`), and posts results to the
PR.

Continuous benchmark results can be viewed at [GitHub pages](https://NethermindEth.github.io/zinc/dev/bench)

## **Example**

For usage example you can refer to the example [r1cs.rs](examples/simple_r1cs.rs) file.


## Usage

Import the library:

```toml
[dependencies]
zinc = { git = "https://github.com/NethermindEth/zinc.git" }
```

## License

The crates in this repository are licensed under the following licence.

* MIT license ([LICENSE](./LICENSE))
Expand Down
76 changes: 43 additions & 33 deletions benches/zip_benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,45 +224,55 @@ fn verify<const P: usize>(group: &mut BenchmarkGroup<WallTime>, modulus: &str, s

fn zip_benchmarks(c: &mut Criterion) {
let mut group = c.benchmark_group("Zip");
let core_only = ark_std::env::var("CORE_BENCHMARKS").is_ok();
let modulus = "106319353542452952636349991594949358997917625194731877894581586278529202198383";

encode_rows::<12>(&mut group, 1);
encode_rows::<13>(&mut group, 1);
encode_rows::<14>(&mut group, 1);
encode_rows::<15>(&mut group, 1);
encode_rows::<16>(&mut group, 1);

encode_single_row::<128>(&mut group, 1);
encode_single_row::<256>(&mut group, 1);
encode_single_row::<512>(&mut group, 1);
encode_single_row::<1024>(&mut group, 1);
encode_single_row::<2048>(&mut group, 1);
encode_single_row::<4096>(&mut group, 1);
if core_only {
// Core, fast set
encode_rows::<12>(&mut group, 1);
encode_single_row::<128>(&mut group, 1);
merkle_root::<12>(&mut group, 1);
commit::<12>(&mut group, 1);
verify::<12>(&mut group, modulus, 1);
} else {
// Full suite (your current behavior)
encode_rows::<12>(&mut group, 1);
encode_rows::<13>(&mut group, 1);
encode_rows::<14>(&mut group, 1);
encode_rows::<15>(&mut group, 1);
encode_rows::<16>(&mut group, 1);

merkle_root::<12>(&mut group, 1);
merkle_root::<13>(&mut group, 1);
merkle_root::<14>(&mut group, 1);
merkle_root::<15>(&mut group, 1);
merkle_root::<16>(&mut group, 1);
encode_single_row::<128>(&mut group, 1);
encode_single_row::<256>(&mut group, 1);
encode_single_row::<512>(&mut group, 1);
encode_single_row::<1024>(&mut group, 1);
encode_single_row::<2048>(&mut group, 1);
encode_single_row::<4096>(&mut group, 1);

commit::<12>(&mut group, 1);
commit::<13>(&mut group, 1);
commit::<14>(&mut group, 1);
commit::<15>(&mut group, 1);
commit::<16>(&mut group, 1);
merkle_root::<12>(&mut group, 1);
merkle_root::<13>(&mut group, 1);
merkle_root::<14>(&mut group, 1);
merkle_root::<15>(&mut group, 1);
merkle_root::<16>(&mut group, 1);

let modulus = "106319353542452952636349991594949358997917625194731877894581586278529202198383";
commit::<12>(&mut group, 1);
commit::<13>(&mut group, 1);
commit::<14>(&mut group, 1);
commit::<15>(&mut group, 1);
commit::<16>(&mut group, 1);

open::<12>(&mut group, modulus, 1);
open::<13>(&mut group, modulus, 1);
open::<14>(&mut group, modulus, 1);
open::<15>(&mut group, modulus, 1);
open::<16>(&mut group, modulus, 1);
open::<12>(&mut group, modulus, 1);
open::<13>(&mut group, modulus, 1);
open::<14>(&mut group, modulus, 1);
open::<15>(&mut group, modulus, 1);
open::<16>(&mut group, modulus, 1);

verify::<12>(&mut group, modulus, 1);
verify::<13>(&mut group, modulus, 1);
verify::<14>(&mut group, modulus, 1);
verify::<15>(&mut group, modulus, 1);
verify::<16>(&mut group, modulus, 1);
verify::<12>(&mut group, modulus, 1);
verify::<13>(&mut group, modulus, 1);
verify::<14>(&mut group, modulus, 1);
verify::<15>(&mut group, modulus, 1);
verify::<16>(&mut group, modulus, 1);
}

group.finish();
}
Expand Down