QED-it/zkinterface

zkInterface is a protocol for the interoperability of zero-knowledge frameworks.

C++

128

141 commits

updated Jun 13, 2023

See the code

README

zkInterface, a standard tool for zero-knowledge interoperability

zkInterface is a standard tool for zero-knowledge interoperability between different ZK DSLs, gadget libraries, and proving systems. The zkInterface project was born in the ZKProof community.

See a live demo.

See the specification and the serialization format.

See the Rust implementation: docs

Integration instructions:

Introduction

alt text

zkInterface is specification and associated tools for enabling interoperability between implementations of general-purpose zero-knowledge proof systems. It aims to facilitate interoperability between zero knowledge proof implementations, at the level of the low-constraint systems that represent the statements to be proven. Such constraint systems are generated by frontends (e.g., by compilation from higher-level specifications), and are consumed by cryptographic backends which generate and verify the proofs. The goal is to enable decoupling of frontends from backends, allowing application writers to choose the frontend most convenient for their functional and development needs and combine it with the backend that best matches their performance and security needs.

The standard specifies the protocol for communicating constraint systems, for communicating variable assignments (for production of proofs), and for constructing constraint systems out of smaller building blocks (gadgets). These are specified using language-agnostic calling conventions and formats, to enable interoperability between different authors, frameworks and languages.

A simple special case is monolithic representation of a whole constraint system and its variable assignments. However, there are a need for more richer and more nuanced forms of interoperability:

  • Precisely-specified statement semantics, variable representation and variable mapping
  • Witness reduction, from high-level witnesses to variable assignments
  • Gadgets interoperability, allowing components of constraint systems to be packaged in reusable and interoperable form
  • Procedural interoperability, allowing execution of complex code to facilitate the above

Current Status

Implementations

Frontends:

Circuit TypeExport CircuitsImport Circuits
ZoKratesR1CSYesNo
LibsnarkR1CSYesNo
Mir r1csR1CSYesNo
PySNARKR1CSYesNo
BellmanR1CSYesYes

Backends:

Proving System
BellmanGroth16
DalekBulletproofs
LibsnarkBCTV14a

See also the WebAssembly modules used to build the live demo.

See the ecosystem/ folder for a collection of instructions to install and connect multiple systems.

Repository content

zkInterface.pdfThe interface specification
zkinterface.fbsThe gadget interface definition using FlatBuffers
examples/An example circuit in binary and JSON
rust/Cargo package zkinterface
rust/src/zkinterface_generated.rsGenerated Rust code
rust/src/reading.rsRust helpers to read messages
rust/src/writing.rsRust helpers to write messages
rust/src/cpp_gadget.rsRust helpers to interact with C++
rust/src/examples.rsExample messages for a simple test circuit
rust/src/gadget_call.rsExample gadget call in Rust
cpp/zkinterface_generated.hGenerated C++ code
cpp/gadget_example.cppExample gadget in C++
js/NPM package zkinterface
js/zkinterface_generated.jsGenerated JavaScript code
build.rsGenerate Rust and C++ code from zkinterface.fbs, and compile the C++ example
cpp/libsnark_integration.hppLibsnark support
cpp/libsnark_example.cppLibsnark gadget example

Testing

In the rust directory, run unit tests:

cargo test

The following commands will generate and print a file containing the messages Circuit, R1CSConstraints, and Witness for a toy circuit in rust/src/examples.rs:

cargo run example  > example.zkif
cargo run explain  < example.zkif

Generated code

Generated C++ and Rust code is included.

For other languages, install the FlatBuffers code generator (flatc). One way is to compile it with the following:

git clone https://github.com/google/flatbuffers.git
cd flatbuffers
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
make

Then run: flatc --LANGUAGE zkinterface.fbs

How to contribute

  • In a frontend, implement a feature to export the circuits or gadgets to zkInterface format.
  • In a proving system, support loading circuits from zkInterface buffers or files.

See the implementation guide section in the spec above for more details, and check out the existing implementations below.

Specification

The zkInterface specification document providers further context on the above, and defines the communication protocol and calling convention between frontends and backends:

  • The logical content of messages being exchange.
  • The serialization format of the messages (which is based on FlatBuffers and may be used in-memory, saved or streamed).
  • A protocol for building a constraint system from gadget composition.
  • Technical recommendations for implementation.

Integration examples

Dalek Bulletproofs

Install

git clone https://github.com/QED-it/bulletproofs.git
cd bulletproofs
cargo install --features yoloproofs --path .

Prove

zkif example - | zkif_bulletproofs prove

Verify

zkif example - | zkif_bulletproofs verify

Bellman

Install

git clone https://github.com/QED-it/zkinterface-bellman.git
cd zkinterface-bellman
cargo install --path .

Validate / Print

zkif example - | zkif_bellman print

Prove

zkif example - | zkif_bellman prove

Verify

(not implemented)

libSNARK

Install

export ZKINTERFACE_LIBSNARK_PATH=$PWD/dist
PATH=$PATH:$ZKINTERFACE_LIBSNARK_PATH/bin

git clone https://github.com/QED-it/zkinterface.git
cd zkinterface/cpp

./deps.sh

cmake -DCMAKE_INSTALL_PREFIX=$ZKINTERFACE_LIBSNARK_PATH . && make install

Setup

zkif example - | zkif_snark setup

Prove

zkif example - | zkif_snark prove

Verify

zkif example - | zkif_snark verify

Gadgets in Rust

[dependencies]
    zkinterface = { version = "1.1.3" }
    zkinterface-libsnark = { version = "1.1.3" }

See examples in libsnark-rust/src/test.rs

Gadgets in C / Foreign Function Interface

CFLAGS="-I $ZKINTERFACE_LIBSNARK_PATH/include -L $ZKINTERFACE_LIBSNARK_PATH/lib -l ff -l gmp -l zkif_gadgetlib"

See API in gadgetlib.h

See FFI call in Rust libsnark-rust/src/gadgetlib.rs

Limitations

This first revision focuses on non-interactive proof systems (NIZKs) for general statements (i.e., NP relations) represented in the R1CS/QAP-style constraint system representation. Extension to other forms of constraint systems is planned.

The associated code is experimental.

See the specification document for more information about limitations and scope.

Contributors

daniben31

47 commits

naure

37 commits

tromer

21 commits

Michael-Qedit

16 commits

QED-it/zkinterface

zkInterface is a protocol for the interoperability of zero-knowledge frameworks.

C++

128

141 commits

updated Jun 13, 2023

See the code

README

zkInterface, a standard tool for zero-knowledge interoperability

zkInterface is a standard tool for zero-knowledge interoperability between different ZK DSLs, gadget libraries, and proving systems. The zkInterface project was born in the ZKProof community.

See a live demo.

See the specification and the serialization format.

See the Rust implementation: docs

Integration instructions:

Introduction

alt text

zkInterface is specification and associated tools for enabling interoperability between implementations of general-purpose zero-knowledge proof systems. It aims to facilitate interoperability between zero knowledge proof implementations, at the level of the low-constraint systems that represent the statements to be proven. Such constraint systems are generated by frontends (e.g., by compilation from higher-level specifications), and are consumed by cryptographic backends which generate and verify the proofs. The goal is to enable decoupling of frontends from backends, allowing application writers to choose the frontend most convenient for their functional and development needs and combine it with the backend that best matches their performance and security needs.

The standard specifies the protocol for communicating constraint systems, for communicating variable assignments (for production of proofs), and for constructing constraint systems out of smaller building blocks (gadgets). These are specified using language-agnostic calling conventions and formats, to enable interoperability between different authors, frameworks and languages.

A simple special case is monolithic representation of a whole constraint system and its variable assignments. However, there are a need for more richer and more nuanced forms of interoperability:

  • Precisely-specified statement semantics, variable representation and variable mapping
  • Witness reduction, from high-level witnesses to variable assignments
  • Gadgets interoperability, allowing components of constraint systems to be packaged in reusable and interoperable form
  • Procedural interoperability, allowing execution of complex code to facilitate the above

Current Status

Implementations

Frontends:

Circuit TypeExport CircuitsImport Circuits
ZoKratesR1CSYesNo
LibsnarkR1CSYesNo
Mir r1csR1CSYesNo
PySNARKR1CSYesNo
BellmanR1CSYesYes

Backends:

Proving System
BellmanGroth16
DalekBulletproofs
LibsnarkBCTV14a

See also the WebAssembly modules used to build the live demo.

See the ecosystem/ folder for a collection of instructions to install and connect multiple systems.

Repository content

zkInterface.pdfThe interface specification
zkinterface.fbsThe gadget interface definition using FlatBuffers
examples/An example circuit in binary and JSON
rust/Cargo package zkinterface
rust/src/zkinterface_generated.rsGenerated Rust code
rust/src/reading.rsRust helpers to read messages
rust/src/writing.rsRust helpers to write messages
rust/src/cpp_gadget.rsRust helpers to interact with C++
rust/src/examples.rsExample messages for a simple test circuit
rust/src/gadget_call.rsExample gadget call in Rust
cpp/zkinterface_generated.hGenerated C++ code
cpp/gadget_example.cppExample gadget in C++
js/NPM package zkinterface
js/zkinterface_generated.jsGenerated JavaScript code
build.rsGenerate Rust and C++ code from zkinterface.fbs, and compile the C++ example
cpp/libsnark_integration.hppLibsnark support
cpp/libsnark_example.cppLibsnark gadget example

Testing

In the rust directory, run unit tests:

cargo test

The following commands will generate and print a file containing the messages Circuit, R1CSConstraints, and Witness for a toy circuit in rust/src/examples.rs:

cargo run example  > example.zkif
cargo run explain  < example.zkif

Generated code

Generated C++ and Rust code is included.

For other languages, install the FlatBuffers code generator (flatc). One way is to compile it with the following:

git clone https://github.com/google/flatbuffers.git
cd flatbuffers
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
make

Then run: flatc --LANGUAGE zkinterface.fbs

How to contribute

  • In a frontend, implement a feature to export the circuits or gadgets to zkInterface format.
  • In a proving system, support loading circuits from zkInterface buffers or files.

See the implementation guide section in the spec above for more details, and check out the existing implementations below.

Specification

The zkInterface specification document providers further context on the above, and defines the communication protocol and calling convention between frontends and backends:

  • The logical content of messages being exchange.
  • The serialization format of the messages (which is based on FlatBuffers and may be used in-memory, saved or streamed).
  • A protocol for building a constraint system from gadget composition.
  • Technical recommendations for implementation.

Integration examples

Dalek Bulletproofs

Install

git clone https://github.com/QED-it/bulletproofs.git
cd bulletproofs
cargo install --features yoloproofs --path .

Prove

zkif example - | zkif_bulletproofs prove

Verify

zkif example - | zkif_bulletproofs verify

Bellman

Install

git clone https://github.com/QED-it/zkinterface-bellman.git
cd zkinterface-bellman
cargo install --path .

Validate / Print

zkif example - | zkif_bellman print

Prove

zkif example - | zkif_bellman prove

Verify

(not implemented)

libSNARK

Install

export ZKINTERFACE_LIBSNARK_PATH=$PWD/dist
PATH=$PATH:$ZKINTERFACE_LIBSNARK_PATH/bin

git clone https://github.com/QED-it/zkinterface.git
cd zkinterface/cpp

./deps.sh

cmake -DCMAKE_INSTALL_PREFIX=$ZKINTERFACE_LIBSNARK_PATH . && make install

Setup

zkif example - | zkif_snark setup

Prove

zkif example - | zkif_snark prove

Verify

zkif example - | zkif_snark verify

Gadgets in Rust

[dependencies]
    zkinterface = { version = "1.1.3" }
    zkinterface-libsnark = { version = "1.1.3" }

See examples in libsnark-rust/src/test.rs

Gadgets in C / Foreign Function Interface

CFLAGS="-I $ZKINTERFACE_LIBSNARK_PATH/include -L $ZKINTERFACE_LIBSNARK_PATH/lib -l ff -l gmp -l zkif_gadgetlib"

See API in gadgetlib.h

See FFI call in Rust libsnark-rust/src/gadgetlib.rs

Limitations

This first revision focuses on non-interactive proof systems (NIZKs) for general statements (i.e., NP relations) represented in the R1CS/QAP-style constraint system representation. Extension to other forms of constraint systems is planned.

The associated code is experimental.

See the specification document for more information about limitations and scope.

Contributors

daniben31

47 commits

naure

37 commits

tromer

21 commits

Michael-Qedit

16 commits

Languages

C++

44.5%

Rust

27.7%

TeX

19.3%

JavaScript

7.5%