add sha1 proof generation to modal prover

This commit is contained in:
turnoffthiscomputer
2024-07-18 16:16:38 +02:00
parent 4a06dc6564
commit 52638fa289
19 changed files with 1960 additions and 52 deletions

View File

@@ -5,6 +5,8 @@ RUN apt-get update && apt-get upgrade -y
# Update the package list and install necessary dependencies
RUN apt-get update && \
apt install -y cmake build-essential pkg-config libssl-dev libgmp-dev libsodium-dev nasm git awscli gcc nodejs npm
# Install jq
RUN apt-get update && apt-get install -y jq
# Node install
RUN npm install -g n

View File

@@ -5,6 +5,7 @@ import subprocess
import asyncio
import json
import hashlib
image = Image.from_dockerfile("Dockerfile")
app = App(image=image)
@@ -16,6 +17,16 @@ mount = Mount.from_local_dir("src", remote_path="/root/src")
async def generate_dsc_proof(request: Request):
# Read the JSON data from the request body
data = await request.json()
# Extract the signature_algorithm
signature_algorithm = data.get("signature_algorithm")
if signature_algorithm not in ["sha256_rsa", "sha1_rsa"]:
return PlainTextResponse("Invalid or missing signature_algorithm", status_code=400)
# Ensure 'inputs' key exists
if "inputs" not in data:
return PlainTextResponse("Missing 'inputs' in request data", status_code=400)
# Convert JSON data to a properly formatted string
json_data = json.dumps(data)
@@ -54,5 +65,4 @@ async def generate_dsc_proof(request: Request):
# Run the app
if __name__ == "__main__":
app.run()
app.run()

View File

@@ -1,3 +1,6 @@
cp ../circuits/build/dsc_4096_final.zkey src/circuit/dsc_4096_final.zkey
cp ../circuits/build/dsc_4096_js/dsc_4096.wasm src/circuit/dsc_4096.wasm
modal deploy dsc_prover.py --name dsc_prover
cp ../circuits/build/dsc_sha256_rsa_4096_final.zkey src/circuit/dsc_sha256_rsa_4096_final.zkey
cp ../circuits/build/dsc_sha256_rsa_4096_js/dsc_sha256_rsa_4096.wasm src/circuit/dsc_sha256_rsa_4096.wasm
cp ../circuits/build/dsc_sha1_rsa_4096_final.zkey src/circuit/dsc_sha1_rsa_4096_final.zkey
cp ../circuits/build/dsc_sha1_rsa_4096_js/dsc_sha1_rsa_4096.wasm src/circuit/dsc_sha1_rsa_4096.wasm
cp ../circuits/build/dsc_sha256_rsa_4096_vkey.json src/vkey/dsc_sha256_rsa_4096_vkey.json
cp ../circuits/build/dsc_sha1_rsa_4096_vkey.json src/vkey/dsc_sha1_rsa_4096_vkey.json

View File

@@ -0,0 +1 @@
modal deploy dsc_prover.py --name dsc_prover

View File

@@ -2,6 +2,18 @@
# Read input from stdin
input=$(cat)
# Extract the signature_algorithm
signature_algorithm=$(echo "$input" | jq -r '.signature_algorithm // "sha256_rsa"')
# Set the circuit files based on the signature_algorithm
if [ "$signature_algorithm" == "sha1_rsa" ]; then
circuit_wasm="/root/src/circuit/dsc_sha1_rsa_4096.wasm"
circuit_zkey="/root/src/circuit/dsc_sha1_rsa_4096_final.zkey"
else
circuit_wasm="/root/src/circuit/dsc_sha256_rsa_4096.wasm"
circuit_zkey="/root/src/circuit/dsc_sha256_rsa_4096_final.zkey"
fi
# Compute the hash of the input data
hash=$(echo -n "$input" | sha256sum | cut -d ' ' -f 1)
@@ -11,13 +23,14 @@ mkdir -p /root/src/data/$hash
# Write input to the unique directory
echo "$input" > /root/src/data/$hash/input.json
# Extract only the 'inputs' part of the JSON for the circuit
jq '.inputs' /root/src/data/$hash/input.json > /root/src/data/$hash/circuit_input.json
# Define paths
input_path="/root/src/data/$hash/input.json"
input_path="/root/src/data/$hash/circuit_input.json"
witness_path="/root/src/data/$hash/witness.wtns"
proof_path="/root/src/data/$hash/proof.json"
public_path="/root/src/data/$hash/public.json"
circuit_wasm="/root/src/circuit/dsc_4096.wasm"
circuit_zkey="/root/src/circuit/dsc_4096_final.zkey"
prover_path="/root/rapidsnark/build/prover"
# Calculate the witness
@@ -47,7 +60,7 @@ fi
echo "ldd $prover_path"
ldd "$prover_path"
status_lld=$?
echo "✓ lld prover dependencies present! ${status_lld}"
echo "✓ ldd prover dependencies present! ${status_lld}"
echo "$prover_path $circuit_zkey $witness_path $proof_path $public_path"
"$prover_path" "$circuit_zkey" "$witness_path" "$proof_path" "$public_path" | tee /dev/stderr

View File

@@ -0,0 +1,99 @@
{
"protocol": "groth16",
"curve": "bn128",
"nPublic": 2,
"vk_alpha_1": [
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
"1"
],
"vk_beta_2": [
[
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
],
[
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
],
[
"1",
"0"
]
],
"vk_gamma_2": [
[
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
],
[
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
],
[
"1",
"0"
]
],
"vk_delta_2": [
[
"10238320193043068829157960501967854222692702878458503554377378628488406921948",
"2504819411237842658609352397158415272245653421477946289695883131063258228520"
],
[
"18340470375805803608701337556657721848991359834488959516971530751169316859620",
"12816079684433910946739040167512171044510230919779819953946700906887571584144"
],
[
"1",
"0"
]
],
"vk_alphabeta_12": [
[
[
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
],
[
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
],
[
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
]
],
[
[
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
],
[
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
],
[
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
]
]
],
"IC": [
[
"12988588557782490372720106385872966314967422240534584361175457924756107643693",
"14646142751640522118026183869854599975857973506262663217812464078644335492697",
"1"
],
[
"21227048561254712863337958008644060921163858069022181377071355406552412741483",
"11145905413764400843127715849833092427485801651255980452289482279055672757081",
"1"
],
[
"6756928444291085777119241838626515299290626488852428949035210829352311876378",
"1864326467329351741201710240834361213001354015077536966380306996231129299589",
"1"
]
]
}

View File

@@ -0,0 +1,99 @@
{
"protocol": "groth16",
"curve": "bn128",
"nPublic": 2,
"vk_alpha_1": [
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
"1"
],
"vk_beta_2": [
[
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
],
[
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
],
[
"1",
"0"
]
],
"vk_gamma_2": [
[
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
],
[
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
],
[
"1",
"0"
]
],
"vk_delta_2": [
[
"13321797380673210476515077034913864616333897796635017120985610572456619578202",
"5794615369833932449623711589651728862835090361076583083326728412120661912694"
],
[
"242783906272443516559840962669397308390618651647582683340262167519339576708",
"1627189806585647035450761519737947618200743049504008744031689523936664845869"
],
[
"1",
"0"
]
],
"vk_alphabeta_12": [
[
[
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
],
[
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
],
[
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
]
],
[
[
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
],
[
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
],
[
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
]
]
],
"IC": [
[
"14799294619686504347123706464984449377033577151047902926075007068263899855296",
"4138452911775673696088952365685111981651322204728180622715924120168892012882",
"1"
],
[
"19237066254572577791709165085639802359499616635829287221569436085741781781740",
"10362088703927009878905137753566677570786091714652005156465176142264008904616",
"1"
],
[
"1633277393836614509092356048427487579995470358819940373097445848231970157637",
"12348867875321881462145411826101774663987266006830069071058772539021485934684",
"1"
]
]
}

View File

@@ -1,9 +0,0 @@
import requests
import json
with open("csca_inputs.json", "r") as file:
inputs = json.load(file)
response = requests.post("https://zk-passport--dsc-prover-generate-dsc-proof.modal.run", json=inputs , timeout=600)
with open("response.json", "w") as file:
file.write(response.text)

113
prover/tests/modal.test.ts Normal file
View File

@@ -0,0 +1,113 @@
import { getCSCAInputs } from "../../common/src/utils/csca";
import { mock_csca_sha256_rsa_4096, mock_dsc_sha256_rsa_4096, mock_csca_sha1_rsa_4096, mock_dsc_sha1_rsa_4096 } from "../../common/src/constants/mockCertificates";
import forge from "node-forge";
import { MODAL_SERVER_ADDRESS } from "../../common/src/constants/constants";
import axios from 'axios';
import fs from 'fs';
import { groth16 } from 'snarkjs'
import { expect } from "chai";
import path from 'path';
const n_dsc = 121;
const k_dsc = 17;
const n_csca = 121;
const k_csca = 34;
const max_cert_bytes = 1664;
const dscCert_sha256_rsa = forge.pki.certificateFromPem(mock_dsc_sha256_rsa_4096);
const cscaCert_sha256_rsa = forge.pki.certificateFromPem(mock_csca_sha256_rsa_4096);
const dscCert_sha1_rsa = forge.pki.certificateFromPem(mock_dsc_sha1_rsa_4096);
const cscaCert_sha1_rsa = forge.pki.certificateFromPem(mock_csca_sha1_rsa_4096);
const vkey_sha256_rsa = JSON.parse(fs.readFileSync(path.join(__dirname, '../src/vkey/dsc_sha256_rsa_4096_vkey.json'), 'utf8'));
const vkey_sha1_rsa = JSON.parse(fs.readFileSync(path.join(__dirname, '../src/vkey/dsc_sha1_rsa_4096_vkey.json'), 'utf8'));
describe('MODAL PROVER', function () {
this.timeout(0); // Disable timeout
describe("SHA256 RSA", async () => {
it("verify proof", async () => {
const circuitInputs = getCSCAInputs(
BigInt(0).toString(),
dscCert_sha256_rsa,
cscaCert_sha256_rsa,
n_dsc,
k_dsc,
n_csca,
k_csca,
max_cert_bytes,
true
);
const inputs = {
"signature_algorithm": "sha256_rsa",
"inputs": circuitInputs
}
//console.log(JSON.stringify(inputs));
console.log('\x1b[34msending request to modal server\x1b[0m');
const response = await sendCSCARequest(inputs);
console.log('\x1b[34mresponse from modal server received\x1b[0m');
const proof = JSON.parse(JSON.stringify(response));
const verifyProof = await groth16.verify(
vkey_sha256_rsa,
proof.pub_signals,
proof.proof
)
expect(verifyProof).to.be.true;
console.log('\x1b[32mproof for sha256 rsa verified\x1b[0m');
});
});
describe("SHA1 RSA", async () => {
it("verify proof", async () => {
const circuitInputs = getCSCAInputs(
BigInt(0).toString(),
dscCert_sha1_rsa,
cscaCert_sha1_rsa,
n_dsc,
k_dsc,
n_csca,
k_csca,
max_cert_bytes,
true
);
const inputs = {
"signature_algorithm": "sha1_rsa",
"inputs": circuitInputs
}
//console.log(JSON.stringify(inputs));
console.log('\x1b[34msending request to modal server\x1b[0m');
const response = await sendCSCARequest(inputs);
console.log('\x1b[34mresponse from modal server received\x1b[0m');
const proof = JSON.parse(JSON.stringify(response));
const verifyProof = await groth16.verify(
vkey_sha1_rsa,
proof.pub_signals,
proof.proof
)
expect(verifyProof).to.be.true;
console.log('\x1b[32mproof for sha1 rsa verified\x1b[0m');
});
});
});
export const sendCSCARequest = async (inputs_csca: any): Promise<any> => {
try {
const response = await axios.post(MODAL_SERVER_ADDRESS, inputs_csca, {
headers: {
'Content-Type': 'application/json'
}
});
return response.data;
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Axios error:', error.message);
if (error.response) {
console.error('Response data:', error.response.data);
console.error('Response status:', error.response.status);
}
} else {
console.error('Unexpected error:', error);
}
throw error;
}
};

29
prover/tests/package.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "modal-tests",
"version": "0.0.1",
"author": "",
"license": "MIT",
"scripts": {},
"dependencies": {
"@types/chai-as-promised": "^7.1.6",
"@types/node": "^20.11.19",
"@types/node-forge": "^1.3.5",
"@types/snarkjs": "^0.7.8",
"axios": "^1.7.2",
"chai-as-promised": "^7.1.1",
"node-forge": "https://github.com/remicolin/forge",
"poseidon-lite": "^0.2.0",
"snarkjs": "^0.7.4",
"typescript": "^5.3.3"
},
"devDependencies": {
"@types/chai": "^4.3.6",
"@types/circomlibjs": "^0.1.6",
"@types/mocha": "^10.0.7",
"chai": "^4.3.8",
"mocha": "^10.3.0",
"prettier": "^3.3.3",
"ts-mocha": "^10.0.0",
"ts-node": "^10.9.2"
}
}

View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}

1158
prover/tests/yarn.lock Normal file

File diff suppressed because it is too large Load Diff