Skip to content

Commit

Permalink
add sha1 proof generation to modal prover
Browse files Browse the repository at this point in the history
  • Loading branch information
remicolin committed Jul 18, 2024
1 parent 4a06dc6 commit 52638fa
Show file tree
Hide file tree
Showing 19 changed files with 1,960 additions and 52 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
contracts/contracts/RegisterASCII.txt
sdk/.env
dist
dist
**/node_modules
**/node_modules/
5 changes: 0 additions & 5 deletions circuits/circuits/tests/dsc/dsc_4096.circom

This file was deleted.

4 changes: 2 additions & 2 deletions circuits/circuits/tests/dsc/dsc_sha1_rsa_4096.circom
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pragma circom 2.1.6;

include "../../dsc_sha1WithRSAEncryption.circom";
include "../../dsc/dsc_sha1_rsa.circom";

component main { public [ merkle_root ] } = DSC_sha1WithRSAEncryption(1664,121 ,17 ,121, 34, 256, 12);
component main { public [ merkle_root ] } = DSC_SHA1_RSA(1664,121 ,17 ,121, 34, 256, 12);
5 changes: 5 additions & 0 deletions circuits/circuits/tests/dsc/dsc_sha256_rsa_4096.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pragma circom 2.1.6;

include "../../dsc/dsc_sha256_rsa.circom";

component main { public [ merkle_root ] } = DSC_SHA256_RSA(1664,121 ,17 ,121, 34, 256, 12);
76 changes: 50 additions & 26 deletions circuits/scripts/build_dsc_circuit.sh
Original file line number Diff line number Diff line change
@@ -1,44 +1,68 @@
#!/bin/bash

# Record the start time
START_TIME=$(date +%s)
TOTAL_START_TIME=$(date +%s)

mkdir -p build
cd build
if [ ! -f powersOfTau28_hez_final_22.ptau ]; then
echo "Download power of tau...."
echo -e "\033[34mDownload power of tau....\033[0m"
wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_22.ptau
echo "Finished download!"
echo -e "\033[32mFinished download!\033[0m"
else
echo "Powers of tau file already downloaded... Skip download action!"
echo -e "\033[90mPowers of tau file already downloaded\033[0m"
fi
cd ..

echo "compiling circuit"
circom circuits/tests/certificates/dsc_4096.circom -l node_modules -l ./node_modules/@zk-kit/binary-merkle-root.circom/src -l ./node_modules/circomlib/circuits --r1cs --O1 --wasm -c --output build
build_circuit() {
local CIRCUIT_NAME=$1
local START_TIME=$(date +%s)

echo "building zkey"
yarn snarkjs groth16 setup build/dsc_4096.r1cs build/powersOfTau28_hez_final_22.ptau build/dsc_4096.zkey
echo -e "\033[34mcompiling circuit: $CIRCUIT_NAME\033[0m"
circom circuits/tests/dsc/${CIRCUIT_NAME}.circom -l node_modules -l ./node_modules/@zk-kit/binary-merkle-root.circom/src -l ./node_modules/circomlib/circuits --r1cs --O1 --wasm -c --output build

if command -v openssl &> /dev/null
then
RAND_STR=$(openssl rand -hex 64)
else
RAND_STR="random text"
fi
echo -e "\033[34mbuilding zkey\033[0m"
yarn snarkjs groth16 setup build/${CIRCUIT_NAME}.r1cs build/powersOfTau28_hez_final_22.ptau build/${CIRCUIT_NAME}.zkey

if command -v openssl &> /dev/null
then
RAND_STR=$(openssl rand -hex 64)
else
RAND_STR="random text"
fi

echo -e "\033[34mbuilding vkey\033[0m"
echo $RAND_STR | yarn snarkjs zkey contribute build/${CIRCUIT_NAME}.zkey build/${CIRCUIT_NAME}_final.zkey
yarn snarkjs zkey export verificationkey build/${CIRCUIT_NAME}_final.zkey build/${CIRCUIT_NAME}_vkey.json

yarn snarkjs zkey export solidityverifier build/${CIRCUIT_NAME}_final.zkey build/Verifier_${CIRCUIT_NAME}.sol
sed -i '' "s/Groth16Verifier/Verifier_${CIRCUIT_NAME}/g" build/Verifier_${CIRCUIT_NAME}.sol
cp build/Verifier_${CIRCUIT_NAME}.sol ../contracts/contracts/Verifier_${CIRCUIT_NAME}.sol
echo -e "\033[34mcopied Verifier_${CIRCUIT_NAME}.sol to contracts\033[0m"

echo -e "\033[32mBuild of $CIRCUIT_NAME completed in $(($(date +%s) - START_TIME)) seconds\033[0m"

echo "building vkey"
echo $RAND_STR | yarn snarkjs zkey contribute build/dsc_4096.zkey build/dsc_4096_final.zkey
yarn snarkjs zkey export verificationkey build/dsc_4096_final.zkey build/dsc_4096_vkey.json
echo "file sizes:"
echo -e "\033[34mSize of ${CIRCUIT_NAME}.r1cs: $(wc -c <build/${CIRCUIT_NAME}.r1cs) bytes\033[0m"
echo -e "\033[34mSize of ${CIRCUIT_NAME}.wasm: $(wc -c <build/${CIRCUIT_NAME}_js/${CIRCUIT_NAME}.wasm) bytes\033[0m"
echo -e "\033[34mSize of ${CIRCUIT_NAME}_final.zkey: $(wc -c <build/${CIRCUIT_NAME}_final.zkey) bytes\033[0m"
}

yarn snarkjs zkey export solidityverifier build/dsc_4096_final.zkey build/Verifier_dsc_4096.sol
sed -i '' 's/Groth16Verifier/Verifier_dsc_4096/g' build/Verifier_dsc_4096.sol
cp build/Verifier_dsc_4096.sol ../contracts/contracts/Verifier_dsc_4096.sol
echo "copied Verifier_dsc_4096.sol to contracts"
# Define circuits and their deployment flags
# name:deploy_flag
CIRCUITS=(
"dsc_sha256_rsa_4096:true"
"dsc_sha1_rsa_4096:true"
)

echo "Build completed in $(($(date +%s) - $START_TIME)) seconds"
for circuit in "${CIRCUITS[@]}"; do
IFS=':' read -r CIRCUIT_NAME DEPLOY_FLAG <<< "$circuit"
if [ "$DEPLOY_FLAG" = "true" ]; then
echo -e "\033[34mBuilding circuit $CIRCUIT_NAME\033[0m"
build_circuit "$CIRCUIT_NAME"
else
echo -e "\033[90mSkipping build for $CIRCUIT_NAME\033[0m"
fi
done

echo "file sizes:"
echo "Size of dsc_4096.r1cs: $(wc -c <build/dsc_4096.r1cs) bytes"
echo "Size of dsc_4096.wasm: $(wc -c <build/dsc_4096_js/dsc_4096.wasm) bytes"
echo "Size of dsc_4096_final.zkey: $(wc -c <build/dsc_4096_final.zkey) bytes"
echo -e "\033[32mTotal build completed in $(($(date +%s) - TOTAL_START_TIME)) seconds\033[0m"
177 changes: 177 additions & 0 deletions contracts/contracts/Verifier_dsc_sha1_rsa_4096.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// 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 Verifier_dsc_sha1_rsa_4096 {
// 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 = 2504819411237842658609352397158415272245653421477946289695883131063258228520;
uint256 constant deltax2 = 10238320193043068829157960501967854222692702878458503554377378628488406921948;
uint256 constant deltay1 = 12816079684433910946739040167512171044510230919779819953946700906887571584144;
uint256 constant deltay2 = 18340470375805803608701337556657721848991359834488959516971530751169316859620;


uint256 constant IC0x = 12988588557782490372720106385872966314967422240534584361175457924756107643693;
uint256 constant IC0y = 14646142751640522118026183869854599975857973506262663217812464078644335492697;

uint256 constant IC1x = 21227048561254712863337958008644060921163858069022181377071355406552412741483;
uint256 constant IC1y = 11145905413764400843127715849833092427485801651255980452289482279055672757081;

uint256 constant IC2x = 6756928444291085777119241838626515299290626488852428949035210829352311876378;
uint256 constant IC2y = 1864326467329351741201710240834361213001354015077536966380306996231129299589;


// 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[2] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
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)))


// -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)))


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

mstore(0, isValid)
return(0, 0x20)
}
}
}
Loading

0 comments on commit 52638fa

Please sign in to comment.