Home

Awesome

circom-ecdsa

Implementation of ECDSA operations in circom.

Project overview

This repository provides proof-of-concept implementations of ECDSA operations in circom. These implementations are for demonstration purposes only. These circuits are not audited, and this is not intended to be used as a library for production-grade applications.

Circuits can be found in circuits. scripts contains various utility scripts (most importantly, scripts for building a few example zkSNARKs using the ECDSA circuit primitives). test contains some unit tests for the circuits, mostly for witness generation.

Install dependencies

Building keys and witness generation files

We provide examples of four circuits using the ECDSA primitives implemented here:

Run yarn build:pubkeygen, yarn build:eth_addr, yarn build:groupsig, yarn build:verify at the top level to compile each respective circuit and keys.

Each of these will create a subdirectory inside a build directory at the top level (which will be created if it doesn't already exist). Inside this directory, the build process will create r1cs and wasm files for witness generation, as well as a zkey file (proving and verifying keys). Note that this process will take several minutes (see full benchmarks below). Building verify requires 56G of RAM.

This process will also generate and verify a proof for a dummy input in the respective scripts/[circuit_name] subdirectory, as a smoke test.

Circuits Description

The following circuits are implemented and can be found in circuits/ecdsa.circom.

The 256-bits input and output are chunked and represented as k n-bits values where k is 4 and n is 64. Please see above examples for concrete usages.

WARNING: Beware that the input to the above circuits should be properly checked and guarded (Lies on the curve, not equal to zero, etc). The purpose of the above circuits is to serve as building blocks but not as stand alone circuits to deploy.

Benchmarks

All benchmarks were run on a 16-core 3.0GHz, 32G RAM machine (AWS c5.4xlarge instance).

pubkeygeneth_addrgroupsigverify
Constraints954442473802509381508136
Circuit compilation21s47s48s72s
Witness generation11s11s12s175s
Trusted setup phase 2 key generation71s94s98s841s
Trusted setup phase 2 contribution9s20s19s149s
Proving key size62M132M134M934M
Proving key verification61s81s80s738s
Proving time3s7s6s45s
Proof verification time1s<1s1s1s

Testing

Run yarn test at the top level to run tests. Note that these tests only test correctness of witness generation. They do not check that circuits are properly constrained, i.e. that only valid witnesses satisfy the constraints. This is a much harder problem that we're currently working on!

Circuit unit tests are written in typescript, in the test directory using chai, mocha, and circom_tester. Running all tests takes about 1 hour on our 3.3GHz, 64G RAM test machine. To run a subset of the tests, use yarn test --grep [test_str] to run all tests whose description matches [test_str].

Groupsig CLI Demo

You can run a CLI demo of a zkSNARK-enabled group signature generator once you've built the groupsig keys. Simply run yarn groupsig-demo at the top level and follow the instructions in your terminal.

Acknowledgments

This project was built during 0xPARC's Applied ZK Learning Group #1.

We use a circom implementation of keccak from Vocdoni. We also use some circom utilities for converting an ECDSA public key to an Ethereum address implemented by lsankar4033, jefflau, and veronicaz41 for another ZK Learning Group project in the same cohort. We use an optimization for big integer multiplication from xJsnark.