An open API service indexing awesome lists of open source software.

https://github.com/erhant/circomkit-ffi

A Rust-based shared library for alternative prover backends.
https://github.com/erhant/circomkit-ffi

circom ffi rust zero-knowledge

Last synced: 5 months ago
JSON representation

A Rust-based shared library for alternative prover backends.

Awesome Lists containing this project

README

          



Circomkit FFI


Rust-based shared library for alternative provers.



Release


NPM


Workflow: Tests




This repository contains an all-in-one adapter for several backends, mainly to be used by existing Javascript code via FFI. It features prover backends via:

- [Arkworks](https://github.com/arkworks-rs/circom-compat) Circom adapter for **Groth16** over **BN254**.
- [Lambdaworks](https://github.com/lambdaclass/lambdaworks/tree/main/provers/groth16/circom-adapter) Circom adapter for **Groth16** over **BLS12-381**
- [Ingonyama ICICLE](https://github.com/ingonyama-zk/icicle-snark) for **Groth16** over **BN254** (via `icicle` feature).

It also provides [SnarkJS](https://github.com/iden3/snarkjs) exports for both prover backends, to export proof objects and public signals.

> [!NOTE]
>
> ICICLE is feature-gated because it requires a bit harder build process, and is in a very early stage of development.

## Installation

The FFI libraries are exposed through an SDK, which is published on NPM.

```sh
npm install circomkit-ffi
```

The libraries are kept under this repository's releases, and supports the following platforms & architectures:

- Linux amd64
- Linux arm64
- MacOS Intel (amd64)
- MacoS Apple Silicon (arm64)
- Windows x86_64 (amd64)

## Usage

The SDK exposes two types of classes:

- `CircomkitFFIBun` is exported at `/circomkit-ffi/bun` and uses [`bun:ffi`](https://bun.sh/docs/api/ffi) and must be used within a Bun runtime.
- `CircomkitFFINode` uses [`ffi-rs`](https://github.com/zhangyuang/node-ffi-rs/) and can be used by both Bun and Node.

> [!NOTE]
>
> `CircomkitFFINode` has a peer dependency for `ffi-rs` as well:
>
> ```sh
> npm install ffi-rs
> ```

### Downloading the library

First you need to download the library suited to your machine. We provide some utilities for this:

```ts
import { downloadRelease, getLibPath } from "circomkit-ffi";
import { existsSync } from "fs";

// you can point to any directory for the library to be downloaded at:
const libDir = "~/path/to/somewhere";

// you can get the path to library with `getLibPath`, it will attach the machine information to the file,
// e.g.: on MacOS & Apple Silicon it will be:
// ~/path/to/somewhere/libcircomkit_ffi-macOS-arm64.dylib
const libPath = getLibPath(libDir);

// now we can download if needed
if (!existsSync(libPath)) {
console.info("Downloading FFI library.");
await downloadRelease(libDir);
}
```

### Preparing Node SDK

The Node SDK is exported from `/node` path, and requires `ffi-rs` as a peer dependency.

```ts
import { CircomkitFFINode } from "circomkit-ffi/node";
import { open, load, close } from "ffi-rs";

// assume library exists at path `libPath`
const lib = new CircomkitFFINode(libPath, open, close, load);
```

### Preparing Bun SDK

The Bun SDK is exported from `/bun` path, and works only for Bun runtime; trying to import this within Node runtime will cause an error.

```ts
import { CircomkitFFIBun } from "circomkit-ffi/bun";

// assume library exists at path `libPath`
const lib = new CircomkitFFIBun(libPath);
```

### Using the SDK

We are all set! We now have access to all the functions within our shared library. For example, we can call `arkworks_prove` to generate a proof using Arkworks. We just have to provide the necessary paths to R1CS, witness file and the prover key.

We can use a Circomkit instance to get these paths, but they can be manually written as well:

```ts
const { proof, publicSignals } = lib.arkworks_prove(
circomkit.path.ofCircuitWithInput(circuitName, inputName, "wtns"),
circomkit.path.ofCircuit(circuitName, "r1cs"),
circomkit.path.ofCircuit(circuitName, "pkey")
);
```

> [!TIP]
>
> If for any reason you have to know whether you are in Bun or Node, you can use the `isBun` function exported by our SDK.

## Development

Clone the repository:

```sh
git clone https://github.com/erhant/circomkit-ffi
```

### Library

The library called by FFI is written in Rust. You can build the library (for your own machine) using:

```sh
cargo build
```

You can run the tests with:

```sh
cargo test
```

Before running tests:

- you need to have installed [SnarkJS](https://github.com/iden3/snarkjs) globally, to verify that the FFI-generated proof is valid.
- you need generated circuit files, which can be done using the commands below.

```sh
# preparations (do only once)
cd example
bun install

# create circuit (e.g. multiplier_3) artifacts for tests
CIRCUIT=multiplier_3
bunx circomkit witness $CIRCUIT default
bunx circomkit prove $CIRCUIT default
bunx circomkit json wtns $CIRCUIT default
bunx circomkit json r1cs $CIRCUIT
```

> [!TIP]
>
> You can take the library directly from within `/target/debug/libcircomkit_ffi.` and use with the SDK, for easier debugging with the SDK tests.

### SDK

The SDK that provides an interface to the FFI-library is written in TypeScript, and we use Bun for this. Install packages with:

```sh
bun install
```

Run tests with:

```sh
bun test
```

You can build the package using:

```sh
bun run build.ts
```

Note that we only export ESM modules, we do not have CommonJS support.

## Example

See the [`example`](./example/) folder.

## Benchmarks

See the [`bench`](./bench/) folder.

## Acknowledgements

This project is kindly supported by [Soulforge zkBankai](https://soulforge.zkbankai.com/) grant, with the application [here](https://github.com/zk-bankai/soulforge/blob/main/applications/circomkit-bunffi.md).

You can find the presentation [here](./example/presentation.pdf) and its live video [here](https://youtu.be/uJjhsrP15L0).

Some helpful resources for this project on FFI usage were:

-
-
-
-
-

## License

This project is [MIT](./LICENSE) licensed.