Skip to content

Commit

Permalink
chore: integrate circomspect to catch bugs in circuits
Browse files Browse the repository at this point in the history
re #4
  • Loading branch information
cedoor committed Jul 5, 2024
1 parent 55d2219 commit 0c1f51e
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 74 deletions.
71 changes: 71 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: main

on:
push:
branches: [main]
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
changed-files:
runs-on: ubuntu-latest
outputs:
any_changed: ${{ steps.changed-files.outputs.any_changed }}
modified_files: ${{ steps.changed-files.outputs.modified_files }}
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v44
with:
files: packages/**/*.{circom,json,ts}

style:
if: needs.changed-files.outputs.any_changed == 'true'
needs: [changed-files]
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: yarn

- name: Install dependencies
run: yarn

- name: Analyze circuits
uses: taiki-e/[email protected]
with:
tool: circomspect
run: circomspect packages/*/src -L ./node_modules/circomlib/circuits

test:
if: needs.changed-files.outputs.any_changed == 'true'
needs: [changed-files]
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: yarn

- name: Install dependencies
run: yarn

# https://github.com/iden3/circuits/blob/8fffb6609ecad0b7bcda19bb908bdb544bdb3cf7/.github/workflows/main.yml#L18-L22
# https://stackoverflow.com/a/78377916
- name: Setup Circom
run: |
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update && sudo apt-get install -y nlohmann-json3-dev libgmp-dev nasm build-essential
wget https://github.com/iden3/circom/releases/latest/download/circom-linux-amd64 && sudo mv ./circom-linux-amd64 /usr/bin/circom && sudo chmod +x /usr/bin/circom
- name: Test circuits
run: yarn test
48 changes: 0 additions & 48 deletions .github/workflows/tests.yml

This file was deleted.

11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,16 @@ cd zk-kit.circom && yarn

## 📜 Usage

### Code formatting
### Code quality and formatting

Install and run [Circomspect](https://github.com/trailofbits/circomspect) to analyze the code and catch bugs:

```bash
yarn lint
```

> [!WARNING]
> You need to install Circomspect with `cargo install circomspect` to run this command.
Run [Prettier](https://prettier.io/) to check formatting rules:

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"version:release": "changelogithub",
"format": "prettier -c .",
"format:write": "prettier -w .",
"lint": "circomspect packages/*/src -L ./node_modules/circomlib/circuits",
"remove:stable-version-field": "ts-node scripts/remove-stable-version-field.ts ${0} && yarn format:prettier:write",
"postinstall": "husky && git config --local core.editor cat"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/ecdh/src/ecdh.circom
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pragma circom 2.1.5;

// circomlib imports
include "./bitify.circom";
include "./escalarmulany.circom";
include "bitify.circom";
include "escalarmulany.circom";

// ECDH Is a a template which allows to generate a shared secret
// from a private key and a public key on the baby jubjub curve
Expand Down
34 changes: 17 additions & 17 deletions packages/poseidon-cipher/src/poseidon-cipher.circom
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
// All credits to the original authors
pragma circom 2.1.5;

// we use this file with a different name because
// we use this file with a different name because
// the poseidon_old implementation of circomlib
// imports the new version of constants
// so we'd have a name clash if we used the same name
// for the constants
include "./poseidon-constants-old.circom";
include "poseidon-constants-old.circom";
// we import this for util functions like Ark, Mix, Sigma
include "./poseidon_old.circom";
include "./comparators.circom";
include "poseidon_old.circom";
include "comparators.circom";

// Poseidon decryption circuit
// param length: length of the input
// This will fail to generate a proof if the ciphertext
// or any of the other inputs are invalid
template PoseidonDecrypt(length) {
// the length of the decrypted output
// the length of the decrypted output
// must be a multiple of 3
// e.g. if length == 4, decryptedLength == 6
var decryptedLength = length;
Expand Down Expand Up @@ -55,14 +55,14 @@ template PoseidonDecrypt(length) {
decrypted[decryptedLength - 2] === 0;
}
}
}
}

// Decrypt a ciphertext without checking if the last ciphertext element or
// whether the last 3 - (l mod 3) elements are 0. This is useful in
// applications where you do not want an invalid decryption to prevent the
// generation of a proof.
template PoseidonDecryptWithoutCheck(length) {
// the length of the decrypted output
// the length of the decrypted output
// must be a multiple of 3
// e.g. if length == 4, decryptedLength == 6
var decryptedLength = length;
Expand Down Expand Up @@ -90,7 +90,7 @@ template PoseidonDecryptWithoutCheck(length) {

// Iteratively decrypt a ciphertext
template PoseidonDecryptIterations(length) {
// if calling this template directly we need to
// if calling this template directly we need to
// ensure that the ciphertext length is a multiple of 3
var decryptedLength = length;
while (decryptedLength % 3 != 0) {
Expand All @@ -101,7 +101,7 @@ template PoseidonDecryptIterations(length) {
signal input ciphertext[decryptedLength + 1];
// nonce passed in while encrypting
signal input nonce;
// the decryption key
// the decryption key
signal input key[2];

signal output decrypted[decryptedLength];
Expand All @@ -115,7 +115,7 @@ template PoseidonDecryptIterations(length) {
lt.in[1] <== two128;
lt.out === 1;

// calculate the number of iterations
// calculate the number of iterations
// needed for the decryption
// process
// \ is integer division
Expand All @@ -126,15 +126,15 @@ template PoseidonDecryptIterations(length) {
// iterate poseidon on the initial state
strategies[0] = PoseidonPerm(4);

// we need to set the initial state to
// we need to set the initial state to
// [0, key[0], key[1], nonce + (length * 2^128)]
// so we create one extra component
// so we create one extra component
// and run a permutation so we can set the state
strategies[0].inputs[0] <== 0;
strategies[0].inputs[1] <== key[0];
strategies[0].inputs[2] <== key[1];
strategies[0].inputs[3] <== nonce + (length * two128);

// loop for n iterations
for (var i = 0; i < n; i++) {
// release three elements of the message
Expand All @@ -143,18 +143,18 @@ template PoseidonDecryptIterations(length) {
}

// create a new PoseidonPerm component
// at the next index
// because we already passed all values to the
// at the next index
// because we already passed all values to the
// first component
strategies[i + 1] = PoseidonPerm(4);
strategies[i + 1].inputs[0] <== strategies[i].out[0];

// set the inputs from the ciphertext
// set the inputs from the ciphertext
for (var j = 0; j < 3; j++) {
strategies[i + 1].inputs[j + 1] <== ciphertext[i * 3 + j];
}
}

// pass in the last
decryptedLast <== strategies[n].out[1];
}
Expand Down
6 changes: 3 additions & 3 deletions packages/utils/src/float.circom
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pragma circom 2.1.5;

include "./bitify.circom";
include "./comparators.circom";
include "./mux1.circom";
include "bitify.circom";
include "comparators.circom";
include "mux1.circom";

// Template to determine the most significant bit (MSB) of an input number.
template MSB(n) {
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/safe-comparators.circom
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma circom 2.0.0;

include "./bitify.circom";
include "bitify.circom";

// Template for safely comparing if one input is less than another,
// ensuring inputs are within a specified bit-length.
Expand Down
4 changes: 2 additions & 2 deletions packages/utils/src/unpack-element.circom
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma circom 2.1.5;

include "./bitify.circom";
include "bitify.circom";

// Template to convert a single field element into multiple 50-bit elements.
template UnpackElement(n) {
Expand All @@ -13,7 +13,7 @@ template UnpackElement(n) {
assert(n > 1 && n <= 5);

// Convert the input signal to its bit representation.
var bits[254];
var bits[254];
bits = Num2Bits_strict()(in);

for (var i = 0; i < n; i++) {
Expand Down

0 comments on commit 0c1f51e

Please sign in to comment.