This commit is contained in:
Erhan Tezcan
2023-03-27 22:17:29 +03:00
parent cc17763aa5
commit 0ff445fef3
10 changed files with 45 additions and 64 deletions

View File

@@ -1,7 +1,7 @@
# compiler args
CLIENV_COMPILER_ARGS="-l ./node_modules"
# colors for swap
TITLE_COLOR='\033[0;34m' # blue color
LOG_COLOR='\033[2;37m' # gray color
RESET='\033[0m' # reset color settings
# colors for swag
CLIENV_COLOR_TITLE='\033[0;34m' # blue color
CLIENV_COLOR_LOG='\033[2;37m' # gray color
CLIENV_COLOR_RESET='\033[0m' # reset color settings

View File

@@ -1,6 +1,6 @@
# Circom Starter
A template repository to write arithmetic circuits.
> A template repository to write arithmetic circuits.
## Usage
@@ -47,47 +47,28 @@ Write your circuits under `circuits` folder. The circuit code itself should be t
Use the [CLI](./scripts/cli.sh), or its wrapper scripts in [package.json](./package.json) to do stuff with your circuits.
```bash
# yarn cli:function ==> ./scripts/cli.sh -f function
yarn cli:compile -c circuit-name
yarn cli:clean -c circuit-name
yarn cli:ptau -c circuit-name -n num-contribs -p phase1-ptau-path
yarn cli:prove -c circuit-name -i input-name
yarn cli:verify -c circuit-name -i input-name
yarn compile -c circuit-name
yarn clean -c circuit-name
yarn type -c circuit-name
yarn ptau -c circuit-name -n num-contribs -p phase1-ptau-path
yarn prove -c circuit-name -i input-name
yarn verify -c circuit-name -i input-name
```
There are some environment variables that the CLI can make use of, they are written under [.cli.env](./.cli.env) file.
## Testing
Just `yarn test`. Each test is named w.r.t the circuit that they are testing, so you can test a specific circuit via `--grep <circuit-name>` option. Within each test, there are two sub-tests:
To run tests:
- **Functionality** will test whether witness computations are matching the expectations. It uses `circom_tester`.
- **Validation** will test whether verification works correctly. This requires the **WASM file**, **prover key**, and **verification key** to be calculated beforehand.
```bash
# run all tests
yarn test
# run a specific test
yarn --grep "circuit name"
```
## File Structure
Within each test, there are two sub-tests:
- **circuits**: Circom circuits are stored here.
- **inputs**: JSON file(s) for each circuit, used for witness generation.
- **scripts**: Generic shell scripts for compiling, proving, verifying, witnessing, and powers-of-tau ceremonies. This is mostly for local development usage.
- **test**: Mocha tests for circuits.
It is worth mentioning the internal file structure respected by all scripts here. Suppose you have a circuit called `foobar` and you have an input called `default`.
- Your circuit should be located at `circuits/foobar.circom`.
- Your input should be located at `inputs/foobar/default.json`.
When you do the entire workflow described above (or simply call `scripts/test.sh foobar default`) then you should expect the following:
- A directory called `build/foobar` will be created.
- `build/foobar/foobar_js` will have the witness generation codes and the WASM circuit.
- `build/foobar/prover_key.zkey` is the prover key.
- `build/foobar/verification_key.json` is the verification key.
- `build/foobar/foobar.r1cs` is the Rank-1 Constraint System output for this circuit.
- For each input, there will be a proof, public signals, and a witness. Following the example of an input called `default`, these are stored as follows:
- `build/foobar/default/proof.json` has the proof.
- `build/foobar/default/public.json` has the public signals. This is used by the verifier script, if you change the public signals to be wrong, the verification will fail.
- `build/foobar/default/witness.wtns` has the witness.
## Resources
- Many Circom test codes I have seen were rather clunky, but this one seems to be the most clear: <https://github.com/0xPARC/circom-starter>.
- <https://github.com/vocdoni/zk-franchise-proof-circuit/blob/master/test/lib.test.ts> has some Poseidon action.
- <https://github.com/rdi-berkeley/zkp-course-lecture3-code/blob/main/circom/Makefile> has a neat Makefile to make the entire thing done with a single `make`. Will refactor this a bit.
- **Witness Computation** will test whether witness computations are matching the expectations & the constraints hold.
- **Proof Validation** will test whether proof generation & verification works correctly. This requires the **WASM file**, **prover key**, and **verification key** to be calculated beforehand.

View File

@@ -4,14 +4,14 @@
"description": "A Circom development environment",
"license": "MIT",
"scripts": {
"compile": "tsc",
"test": "npx mocha",
"cli:compile": "./scripts/cli.sh -f compile",
"cli:clean": "./scripts/cli.sh -f clean",
"cli:ptau": "./scripts/cli.sh -f ptau",
"cli:prove": "./scripts/cli.sh -f prove",
"cli:verify": "./scripts/cli.sh -f verify",
"cli:help": "./scripts/cli.sh -f help"
"type": "./scripts/cli.sh -f type",
"compile": "./scripts/cli.sh -f compile",
"clean": "./scripts/cli.sh -f clean",
"ptau": "./scripts/cli.sh -f ptau",
"prove": "./scripts/cli.sh -f prove",
"verify": "./scripts/cli.sh -f verify",
"_help": "./scripts/cli.sh -f help"
},
"author": "erhant",
"devDependencies": {

View File

@@ -1,10 +1,10 @@
## Clean build files
clean() {
echo -e "\n${TITLE_COLOR}=== Cleaning artifacts ===${RESET}"
echo -e "\n${CLIENV_COLOR_TITLE}=== Cleaning artifacts ===${CLIENV_COLOR_RESET}"
local CIRCUIT=$1
local CIRCUIT_DIR=./build/$CIRCUIT
rm -rf $CIRCUIT_DIR
echo -e "${LOG_COLOR}Deleted $CIRCUIT_DIR${RESET}"
echo -e "${CLIENV_COLOR_LOG}Deleted $CIRCUIT_DIR${CLIENV_COLOR_RESET}"
}

View File

@@ -1,6 +1,6 @@
## Compile the circuit, outputting R1CS and JS files
compile() {
echo -e "\n${TITLE_COLOR}=== Compiling the circuit ===${RESET}"
echo -e "\n${CLIENV_COLOR_TITLE}=== Compiling the circuit ===${CLIENV_COLOR_RESET}"
local CIRCUIT=$1
local CIRCOM_IN=./circuits/main/$CIRCUIT.circom
local CIRCOM_OUT=./build/$CIRCUIT
@@ -13,5 +13,5 @@ compile() {
# compile with circom
circom $CIRCOM_IN -o $CIRCOM_OUT --r1cs --sym --wasm
echo -e "${LOG_COLOR}Built artifacts under $CIRCOM_OUT${RESET}"
echo -e "${CLIENV_COLOR_LOG}Built artifacts under $CIRCOM_OUT${CLIENV_COLOR_RESET}"
}

View File

@@ -1,6 +1,6 @@
## Generate a proof
prove() {
echo -e "\n${TITLE_COLOR}=== Generating proof ===${RESET}"
echo -e "\n${CLIENV_COLOR_TITLE}=== Generating proof ===${CLIENV_COLOR_RESET}"
local CIRCUIT=$1
local INPUT=$2
local CIRCUIT_DIR=./build/$CIRCUIT
@@ -12,5 +12,5 @@ prove() {
$OUTPUT_DIR/proof.json \
$OUTPUT_DIR/public.json
echo -e "${LOG_COLOR}Generated under $OUTPUT_DIR${RESET}"
echo -e "${CLIENV_COLOR_LOG}Generated under $OUTPUT_DIR${CLIENV_COLOR_RESET}"
}

View File

@@ -1,7 +1,7 @@
## Commence a circuit-specific phase-2 powers-of-tau ceremony
ptau() {
echo -e "\n${TITLE_COLOR}=== Phase-2 Powers of Tau ===${RESET}"
echo -e "${LOG_COLOR}this may take a while...${RESET}"
echo -e "\n${CLIENV_COLOR_TITLE}=== Phase-2 Powers of Tau ===${CLIENV_COLOR_RESET}"
echo -e "${CLIENV_COLOR_LOG}this may take a while...${CLIENV_COLOR_RESET}"
local CIRCUIT=$1 # circuit name
local NUM_CONTRIBS=$2 # number of contributions
local P1_PTAU=$3 # path to phase-1 ptau
@@ -43,5 +43,5 @@ ptau() {
# export
snarkjs zkey export verificationkey $PROVER_KEY $VERIFICATION_KEY
echo -e "${LOG_COLOR}Generated keys\n\tProver key: $PROVER_KEY\n\tVerification key: $VERIFICATION_KEY${RESET}"
echo -e "${CLIENV_COLOR_LOG}Generated keys\n\tProver key: $PROVER_KEY\n\tVerification key: $VERIFICATION_KEY${CLIENV_COLOR_RESET}"
}

View File

@@ -1,11 +1,11 @@
## Parse the symbols file and generate types for TypeScript
type() {
echo -e "\n${TITLE_COLOR}=== Generating types ===${RESET}"
echo -e "\n${CLIENV_COLOR_TITLE}=== Generating types ===${CLIENV_COLOR_RESET}"
CIRCUIT=$1
SYM=./build/$CIRCUIT/$CIRCUIT.sym
# choose lines with 1 dot only (these are the signals in main file), extract their names
cat $SYM | grep -E '^.+main[^.]*\.[^.]*$'
echo -e "\n${LOG_COLOR}Types generated!${RESET}"
echo -e "\n${CLIENV_COLOR_LOG}Types generated!${CLIENV_COLOR_RESET}"
}

View File

@@ -1,6 +1,6 @@
## Verify a witness & proof
verify() {
echo -e "\n${TITLE_COLOR}=== Verifying proof ===${RESET}"
echo -e "\n${CLIENV_COLOR_TITLE}=== Verifying proof ===${CLIENV_COLOR_RESET}"
local CIRCUIT=$1
local INPUT=$2
local CIRCUIT_DIR=./build/${CIRCUIT}
@@ -10,5 +10,5 @@ verify() {
$CIRCUIT_DIR/$INPUT/public.json \
$CIRCUIT_DIR/$INPUT/proof.json
echo -e "${LOG_COLOR}Verification complete.${RESET}"
echo -e "${CLIENV_COLOR_LOG}Verification complete.${CLIENV_COLOR_RESET}"
}

View File

@@ -1,6 +1,6 @@
## Computes the witness for the given circuit and input
witness() {
echo -e "\n${TITLE_COLOR}=== Computing witness ===${RESET}"
echo -e "\n${CLIENV_COLOR_TITLE}=== Computing witness ===${CLIENV_COLOR_RESET}"
local CIRCUIT=$1
local INPUT=$2
local JS_DIR=./build/$CIRCUIT/${CIRCUIT}_js # JS files for the circuit
@@ -15,5 +15,5 @@ witness() {
$INPUT_DIR/$INPUT.json \
$WITNESS
echo -e "${LOG_COLOR}Generated\n\tWitness: $WITNESS${RESET}"
echo -e "${CLIENV_COLOR_LOG}Generated\n\tWitness: $WITNESS${CLIENV_COLOR_RESET}"
}