A Rust-based framework for creating and verifying zero-knowledge proofs using Groth16 zk-SNARKs. This framework allows you to define arithmetic circuits and generate/verify zero-knowledge proofs for them.
This project was created as a learning exercise to:
- Practice and improve my Rust programming skills
- Explore the fascinating world of cryptography and zero-knowledge proofs
- Understand the practical implementation of zk-SNARKs
- Learn about circuit-based computation and constraint systems
While the implementation may not be production-ready, it serves as a good starting point for understanding zero-knowledge proofs and their implementation in Rust. Feel free to use this as a reference or learning resource!
The codebase contains some legacy code and terminology from its initial development as an asset transfer system. You may notice:
- References to "transfer", "sender", "receiver" in variable names and comments
- Functions related to balance checking and transfers
- Some unused fields in structs
These are remnants of the original implementation and are not used in the current circuit-based functionality. They can be safely ignored or removed in future refactoring.
- Circuit definition using a simple text-based format
- Support for basic arithmetic operations (add, subtract, multiply)
- Support for boolean operations (XOR)
- Support for equality checks
- Support for constant values
- Groth16 zk-SNARK proof generation and verification
- R1CS (Rank-1 Constraint System) conversion
- Witness computation
Circuits are defined in a simple text format. Here's an example:
name simple_arithmetic
input x 5
input y 3
input transfer_amount_public 5
output result 16
output check 1
const one 1
const two 2
const sixteen 16
add x y sum
add sum two result
sub result sixteen diff
mul diff diff check
input <name> <value>
- Define an input variableoutput <name> <value>
- Define an expected outputconst <name> <value>
- Define a constantadd <a> <b> <result>
- Addition: result = a + bsub <a> <b> <result>
- Subtraction: result = a - bmul <a> <b> <result>
- Multiplication: result = a * bxor <a> <b> <result>
- XOR operation (inputs must be 0 or 1)eq <a> <b> <result>
- Equality check: result = 1 if a == b, 0 otherwise
- Create a circuit file (e.g.,
circuit.txt
) using the format described above - Run the program:
cargo run -- circuit.txt
The program will:
- Parse the circuit
- Convert it to an R1CS system
- Generate Groth16 proving and verifying keys
- Compute the witness
- Generate a zero-knowledge proof
- Verify the proof
Parsing circuit from: circuit.txt
Parsed Circuit: "simple_arithmetic"
Converting circuit to R1CS system...
Circuit parsed: simple_arithmetic (4 constraints, 6 variables)
Public input names (excluding implicit '1'): ["x", "y", "transfer_amount_public"]
Generating Groth16 proving and verifying keys (setup)...
Keys generated successfully.
Computing witness for the circuit instance...
Witness computed with 6 assignments.
Generating Groth16 proof...
Proof generated.
Verifying proof with public inputs: [...]
Verification Result: true
Proof is VALID!
- ark-bls12-381
- ark-groth16
- ark-ff
- ark-ec
- ark-relations
- ark-std
- ark-crypto-primitives
- ark-serialize
src/main.rs
- Main program entry pointsrc/lib.rs
- Core library functionalitysrc/parser.rs
- Circuit file parsingcircuit.txt
- Example valid circuitinvalid_circuit.txt
- Example invalid circuit
cargo build
cargo test
This project implements a zero-knowledge proof system using zk-SNARKs (Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge). It allows users to define arithmetic circuits and generate proofs that verify the correctness of computations without revealing the inputs.
The framework is built on top of ArkWorks, a Rust library for zero-knowledge proof systems, specifically using the Groth16 protocol.
- Rust (latest stable version)
- Cargo (Rust's package manager)
- Clone the repository:
git clone https://github.com/Arxane/Basic-zk-SNARK-framework-using-arkWorks.git
cd Basic-zk-SNARK-framework-using-arkWorks
- Build the project:
cargo build
-
Circuit Parsing: The framework parses the circuit definition file into an internal representation.
-
R1CS Conversion: The circuit is converted into a Rank-1 Constraint System (R1CS), which is the format required for zk-SNARKs.
-
Witness Computation: The framework computes a witness that satisfies all constraints in the circuit.
-
Proof Generation: Using the Groth16 protocol, a zero-knowledge proof is generated.
-
Verification: The proof is verified against the public inputs and constraints.
The framework uses:
- ArkWorks' Groth16 implementation for proof generation and verification
- BLS12-381 curve for cryptographic operations
- R1CS (Rank-1 Constraint System) for circuit representation
If you use this project in your research, please cite:
-
Groth, J. (2016). "On the Size of Pairing-based Non-interactive Arguments". In: Fischlin, M., Coron, JS. (eds) Advances in Cryptology – EUROCRYPT 2016. EUROCRYPT 2016. Lecture Notes in Computer Science, vol 9666. Springer, Berlin, Heidelberg.
-
Ben-Sasson, E., et al. (2014). "Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture". In: USENIX Security Symposium.
-
ArkWorks Team. (2023). "ArkWorks: A Rust Library for Zero-Knowledge Proof Systems". GitHub Repository.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- The ArkWorks team for their excellent zero-knowledge proof library
- The zk-SNARK research community for their foundational work