In order to use circom, it is recommended to use a linux system (I tried windows and some libraries do not work in windows).
- Install linux system. It is fine to stay in root. Otherwise create a linux account and make sure to grant the user sudo access.
- Install Nodejs
- sudo apt install nodejs npm -y
- check installation by using
npm --versionnodejs --version
- Install rust with the following command. (Current location /home/username)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shsource $HOME/.cargo/env- those two commands allow you to install rust and use 'cargo' terminal command
- check installation by using
cargo --version
- Create a new directory where you can put the circom files. cd to that directory (Current location /home/username/Snark)
- Install circom with following commands
git clone https://github.com/iden3/circom.gitcd circomcargo build --releaseecho 'export PATH="$HOME/circom/target/release:$PATH"' >> ~/.bashrcsource ~/.bashrc- check installation by using
circom --version
- Install Snarkjs (Current location /home/username)
npm install -g snarkjs- check installation by using
snarkjs --version
- Install some libraries for C++ (Current location /home/username)
sudo apt install -y nlohmann-json3-dev libgmp-dev nasm
- Some additional notes
- if Snarkjs prints out error that says "Error: Scalar size does not match", you need to go change a file in snarkjs.
- First, use command to open main.cjs
cd $(npm root -g)/snarkjs/node_modules/ffjavascript/buildnano main.cjs
- Second, open the main.cjs by using 'nano main.cjs' (The file is super long, using vscode iss highly recommanded refer to this link: Vscode in wsl)
- Next, search for the line (if you are using terminal nano, press control and w two keys at same time to search)
const nPoints = Math.floor(buffBases.byteLength / sGIn);const sScalar = Math.floor(buffScalars.byteLength / nPoints);
- Finally, replace them with (basically adding the bolded line in middle to check divide by 0 error)
const nPoints = Math.floor(buffBases.byteLength / sGIn);if (nPoints == 0) return G.zero; // add new hereconst sScalar = Math.floor(buffScalars.byteLength / nPoints);
- save all your changes.
- refer to this link if you have any problems
It is recommended to run an example file to make sure everything is install properly.
- Download the example folder in this github repo, and use the multiand example.
cd examplecd MultiAndcircom multiand.circom --r1cs --wasm --sym- This step will generate a folder called multiand_js. Open the folder, and drag all three files inside the folder out, so it will be in the same directory as multiand.circom.
- Create a file called 'input.json' in the same directory as multiand.circom, put the following inside it:
{"in": [1, 1, 0, 1]} snarkjs powersoftau new bn128 12 pot12_0000.ptau -vsnarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -vsnarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -vsnarkjs groth16 setup multiand.r1cs pot12_final.ptau multiand_0000.zkeysnarkjs zkey contribute multiand_0000.zkey multiand_0001.zkey --name="1st Contributor Name" -vsnarkjs zkey export verificationkey multiand_0001.zkey verification_key.jsonnode generate_witness.js multiand.wasm input.json witness.wtnssnarkjs groth16 prove ./multiand_0001.zkey witness.wtns proof.json public.jsonsnarkjs groth16 verify ./verification_key.json public.json proof.json- After all those steps, the terminal should print: snarkjs: OK. Which indicates that it is valid.
- In order to make sure it will reject the invalid input, change the code in public.json from
["0"]to["1"], and use commandsnarkjs groth16 verify ./verification_key.json public.json proof.jsonagain, it will show: SnarkJS: Invalide Proof