Skip to content

Commit

Permalink
add a script to do the generate
Browse files Browse the repository at this point in the history
Signed-off-by: Chengxuan Xing <[email protected]>
  • Loading branch information
Chengxuan committed Aug 2, 2024
1 parent 56b4652 commit 845983d
Show file tree
Hide file tree
Showing 23 changed files with 357 additions and 79 deletions.
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_anon.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract Groth16Verifier_Anon {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[4] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_anon_enc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ contract Groth16Verifier_AnonEnc {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[7] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_anon_enc_nullifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ contract Groth16Verifier_AnonEncNullifier {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[10] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_anon_nullifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ contract Groth16Verifier_AnonNullifier {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[7] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_check_hashes_value.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ contract Groth16Verifier_CheckValue {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[2] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract Groth16Verifier_CheckInputsOutputsValue {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[4] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_check_nullifier_value.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ contract Groth16Verifier_CheckNullifierValue {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[7] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
198 changes: 198 additions & 0 deletions solidity/contracts/lib/verifier_check_nullifiers.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/

pragma solidity >=0.7.0 <0.9.0;

contract Groth16Verifier_CheckNullifiers {
// Scalar field size
uint256 constant r = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
// Base field size
uint256 constant q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

// Verification Key data
uint256 constant alphax = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
uint256 constant alphay = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
uint256 constant betax1 = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
uint256 constant betax2 = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
uint256 constant betay1 = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
uint256 constant betay2 = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant deltax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant deltax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant deltay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint256 constant deltay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;


uint256 constant IC0x = 10140252967314138622156512489083018770148494354093882802039406047617787709800;
uint256 constant IC0y = 20698051546382693961454878036289908851972737376392085964268577923504666173429;

uint256 constant IC1x = 10601491462870191606236882058637360094269543767285027306530631917386407797174;
uint256 constant IC1y = 7869991804374762323474385618535722743870361529396163332542269918194422014565;

uint256 constant IC2x = 18364457316520398921170830868477465569187545398762454405797573551491002038447;
uint256 constant IC2y = 4029786243935716732018576355563691307667053457596632593648291564414047523687;

uint256 constant IC3x = 16765195518915393174374690216299424897408934037167261444515066379588536424349;
uint256 constant IC3y = 4149053851334031547630770016704587188155326062471946083864080602449903983625;

uint256 constant IC4x = 5136358456743952435950535767429048244403155058778244406142934324996947695436;
uint256 constant IC4y = 17453835193675291960532018937756979106981097079477612248578429602382325376629;

uint256 constant IC5x = 11676108830032481328698589416259315927694691096374450191853362097716864694491;
uint256 constant IC5y = 17857686384416679265464258176356123060768581787201770777010575259557283533118;


// Memory data
uint16 constant pVk = 0;
uint16 constant pPairing = 128;

uint16 constant pLastMem = 896;

function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[5] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
}

// G1 function to multiply a G1 value(x,y) to value in an address
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn, 32), y)
mstore(add(mIn, 64), s)

success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)

if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}

mstore(add(mIn, 64), mload(pR))
mstore(add(mIn, 96), mload(add(pR, 32)))

success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

if iszero(success) {
mstore(0, 0)
return(0, 0x20)
}
}

function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
let _pPairing := add(pMem, pPairing)
let _pVk := add(pMem, pVk)

mstore(_pVk, IC0x)
mstore(add(_pVk, 32), IC0y)

// Compute the linear combination vk_x

g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))

g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))

g1_mulAccC(_pVk, IC3x, IC3y, calldataload(add(pubSignals, 64)))

g1_mulAccC(_pVk, IC4x, IC4y, calldataload(add(pubSignals, 96)))

g1_mulAccC(_pVk, IC5x, IC5y, calldataload(add(pubSignals, 128)))


// -A
mstore(_pPairing, calldataload(pA))
mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))

// B
mstore(add(_pPairing, 64), calldataload(pB))
mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
mstore(add(_pPairing, 160), calldataload(add(pB, 96)))

// alpha1
mstore(add(_pPairing, 192), alphax)
mstore(add(_pPairing, 224), alphay)

// beta2
mstore(add(_pPairing, 256), betax1)
mstore(add(_pPairing, 288), betax2)
mstore(add(_pPairing, 320), betay1)
mstore(add(_pPairing, 352), betay2)

// vk_x
mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))


// gamma2
mstore(add(_pPairing, 448), gammax1)
mstore(add(_pPairing, 480), gammax2)
mstore(add(_pPairing, 512), gammay1)
mstore(add(_pPairing, 544), gammay2)

// C
mstore(add(_pPairing, 576), calldataload(pC))
mstore(add(_pPairing, 608), calldataload(add(pC, 32)))

// delta2
mstore(add(_pPairing, 640), deltax1)
mstore(add(_pPairing, 672), deltax2)
mstore(add(_pPairing, 704), deltay1)
mstore(add(_pPairing, 736), deltay2)


let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)

isOk := and(success, mload(_pPairing))
}

let pMem := mload(0x40)
mstore(0x40, add(pMem, pLastMem))

// Validate that all evaluations ∈ F

checkField(calldataload(add(_pubSignals, 0)))

checkField(calldataload(add(_pubSignals, 32)))

checkField(calldataload(add(_pubSignals, 64)))

checkField(calldataload(add(_pubSignals, 96)))

checkField(calldataload(add(_pubSignals, 128)))

checkField(calldataload(add(_pubSignals, 160)))


// Validate all evaluations
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

mstore(0, isValid)
return(0, 0x20)
}
}
}
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_nf_anon.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ contract Groth16Verifier_NFAnon {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[2] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
2 changes: 1 addition & 1 deletion solidity/contracts/lib/verifier_nf_anon_nullifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ contract Groth16Verifier_NFAnonNullifier {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[3] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
if iszero(lt(v, r)) {
mstore(0, 0)
return(0, 0x20)
}
Expand Down
69 changes: 69 additions & 0 deletions zkp/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/bin/bash

# Check if PROVING_KEYS_ROOT is not set or is empty
if [ -z "$PROVING_KEYS_ROOT" ]; then
echo "Error: PROVING_KEYS_ROOT is not set."
exit 1
fi

# Define arrays
X_values=(
"anon"
"anon_enc"
"anon_nullifier"
"anon_enc_nullifier"
"nf_anon"
"nf_anon_nullifier"
"check_hashes_value"
"check_inputs_outputs_value"
"check_nullifier_value"
"check_nullifiers"
)
Y_values=(
"powersOfTau28_hez_final_12"
"powersOfTau28_hez_final_13"
"powersOfTau28_hez_final_16"
"powersOfTau28_hez_final_16"
"powersOfTau28_hez_final_11"
"powersOfTau28_hez_final_15"
"powersOfTau28_hez_final_09"
"powersOfTau28_hez_final_11"
"powersOfTau28_hez_final_16"
"powersOfTau28_hez_final_11"
)

# Check if both arrays have the same length
if [ ${#X_values[@]} -ne ${#Y_values[@]} ]; then
echo "Error: X_values and Y_values arrays have different lengths."
exit 1
fi

# Loop through the arrays
for i in "${!X_values[@]}"; do
X=${X_values[$i]}
Y=${Y_values[$i]}
echo "Processing $X"

CIRCOM_INPUT="circuits/$X.circom"
PTIAU_FILE="$HOME/Downloads/$Y.ptau"
ZKEY_OUTPUT="$PROVING_KEYS_ROOT/$X.zkey"

if [ ! -f "$CIRCOM_INPUT" ]; then
echo "Error: Input file does not exist: $CIRCOM_INPUT"
continue
fi

echo "Compile circuit for $X"
circom "$CIRCOM_INPUT" --output ./js/lib --sym --wasm
circom "$CIRCOM_INPUT" --output "$PROVING_KEYS_ROOT" --r1cs

echo "Generate test proving key for $X with $Y"
snarkjs groth16 setup "$PROVING_KEYS_ROOT/$X.r1cs" "$PTIAU_FILE" "$ZKEY_OUTPUT"

echo "Generate verification key for $X"
snarkjs zkey export verificationkey "$PROVING_KEYS_ROOT/$X.zkey" "$PROVING_KEYS_ROOT/$X.-vkey.json"

echo "Generate solidity verifier for $X"
snarkjs zkey export solidityverifier "$PROVING_KEYS_ROOT/$X.zkey" "../solidity/contracts/lib/verifier_$X.sol"
done

Loading

0 comments on commit 845983d

Please sign in to comment.