Home

Awesome

Ecne (R1CSConstraintSolver.jl)

Introduction

zk-SNARKs are a method for generating zero-knowledge proofs of arbitrary functions, as long as these functions can be expressed as the result of a R1CS (a rank-one constraint system). However, one still needs to convert functions into R1CS form. As this is a laborious process (though still far easier than starting from scratch), Ecne, named after the Celtic god of wisdom, is a tool that can be used to translate functions into R1CS form, in its current form, by verifying that R1CS equations uniquely determine outputs given inputs (i.e. that the constraints are sound).

What is Ecne?

The goal of Ecne is to make it easier to convert functions into R1CS form. As of right now, Ecne is used to verify that certain sets of R1CS constraints uniquely identify functions. Ecne also supports adding certain functions to a trusted codebase, so that they do not need to be re-verified after they've been verified once. Eventually, we hope to have Ecne not only show that R1CS constraints have unique solutions, but also show that they correspond to formally specified mathematical functions as well.

API

The primary user facing function is solveWithTrustedFunctions. The function takes in the R1CS file of the equation you want (which specifies functions you want) and the r1cs files of Trusted functions with their names. It returns true when able to verify the soundness of the constraints, and false otherwise. Note that false does not mean that the constraints aren't sound, it just means that Ecne is unable to prove that the constraints are sound.

Algorithm Details

See here for algorithmic details.

Setup

First, clone the repository:

git clone https://github.com/franklynwang/EcneProject

Then, clone the circomlib library in Circom_Functions/

git clone https://github.com/iden3/circomlib

The following requirements must be present in your environment.

Then, run the following command to instantiate the Julia package environment.

just install

To run the interactive Julia REPL or open a Pluto notebook server, use the following commands:

just repl      # open Julia REPL (can add packages here)
just notebook  # start server (try opening hard_solve.jl)

If you make edits and would like to check that all tests still pass, please use

just test

Verifications

To verify the correctness of the ECDSA privToPub circuit given the correctness of the SECP circuit, first, we will need to obtain the R1CS file for the ECDSA circuit, which is unfortunately too large to include in this repository. To generate it, you need the Circom Library, after which you run the following command in Circom_Functions:

circom ecdsa.circom --r1cs --O0

Note the O0 compilation is needed to make abstraction possible. Note that this means using optimized constraints in production assumes the correctness of the Circom Compiler, and that the optimized constraints are equivalent to the non-optimized ones.

Finally, simply run julia --project=. examples/ecdsa_secp_abstraction.jl to show that ECDSA has sound constraints given if we trust the Secp256k1AddUnequal command

To verify the correctness of the SECP circuit given BigMultModP and BigLessThan, simply run julia --project=. examples/secpk1_abstraction.jl

To see benchmarks on several circuits, run just bench.

Command line client and REST API

The src/ directory contains a Julia script that can be used to invoke Ecne from the command line:

$ julia --project=. src/Ecne.jl --help

usage: Ecne.jl --r1cs R1CS --name NAME --sym SYM [--trusted TRUSTED]
               [-h]

Ecne command-line helper

optional arguments:
  --r1cs R1CS        de-optimized R1CS file to verify
  --name NAME        Circuit name
  --sym SYM          symbol file with labels
  --trusted TRUSTED  Optional trusted R1CS file
  -h, --help         show this help message and exit

With a R1CS file that has been de-optimizedi and its symbol file, Ecne can be invoked via:

$ julia --project=. src/Ecne.jl --r1cs target/division.r1cs --name division --sym target/division.sym

[...]

constraint #2
(-1 * main.y2) * (1 * main.x3) = (-1 * main.y1)
constraint #3
0 * 0 = (-1 * main.x4 + -1 * main.out + 1 * main.y2)
("R1CS function division has potentially unsound constraints",)

Moreover, external tools can trigger verifications via the REST API defined at src/Server.jl. You can find an example at scripts/launch_post.sh:

curl -X POST http://127.0.0.1:8000/verify -H 'Content-Type: application/json' -d '{"r1cs":"target/division.r1cs","sym":"target/division.sym", "id":"division"}'

Authorship

Made by Franklyn Wang