|
|
|
@ -3,7 +3,6 @@ import type { CircomPluginClient } from "../services/circomPluginClient" |
|
|
|
|
import { ActionPayloadTypes, AppState, ICircuitAppContext } from "../types" |
|
|
|
|
import { GROTH16_VERIFIER, PLONK_VERIFIER } from './constant' |
|
|
|
|
import { extractNameFromKey, extractParentFromKey } from '@remix-ui/helper' |
|
|
|
|
import { ethers } from 'ethers' |
|
|
|
|
|
|
|
|
|
export const compileCircuit = async (plugin: CircomPluginClient, appState: AppState) => { |
|
|
|
|
try { |
|
|
|
@ -19,12 +18,21 @@ export const compileCircuit = async (plugin: CircomPluginClient, appState: AppSt |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export const computeWitness = async (plugin: CircomPluginClient, status: string, witnessValues: Record<string, string>) => { |
|
|
|
|
export const computeWitness = async (plugin: CircomPluginClient, appState: AppState, dispatch: ICircuitAppContext['dispatch'], status: string, witnessValues: Record<string, string>) => { |
|
|
|
|
try { |
|
|
|
|
if (status !== "computing") { |
|
|
|
|
const input = JSON.stringify(witnessValues) |
|
|
|
|
const witness = await plugin.computeWitness(input) |
|
|
|
|
|
|
|
|
|
await plugin.computeWitness(input) |
|
|
|
|
if (appState.exportWtnsJson) { |
|
|
|
|
const wtns = await snarkjs.wtns.exportJson(witness) |
|
|
|
|
const wtnsJson = wtns.map(wtn => wtn.toString()) |
|
|
|
|
const fileName = extractNameFromKey(appState.filePath) |
|
|
|
|
const writePath = extractParentFromKey(appState.filePath) + `/.bin/${fileName.replace('.circom', '.wtn.json')}` |
|
|
|
|
|
|
|
|
|
await plugin.call('fileManager', 'writeFile', writePath, JSON.stringify(wtnsJson, null, 2)) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'computeWitness', 'wtns.exportJson', writePath]) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
console.log('Existing witness computation in progress') |
|
|
|
|
} |
|
|
|
@ -38,6 +46,8 @@ export const computeWitness = async (plugin: CircomPluginClient, status: string, |
|
|
|
|
export const runSetupAndExport = async (plugin: CircomPluginClient, appState: AppState, dispatch: ICircuitAppContext['dispatch']) => { |
|
|
|
|
try { |
|
|
|
|
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'exporting' }) |
|
|
|
|
dispatch({ type: 'SET_SETUP_EXPORT_FEEDBACK', payload: null }) |
|
|
|
|
plugin.emit('statusChanged', { key: 'none' }) |
|
|
|
|
const ptau_final = `https://ipfs-cluster.ethdevops.io/ipfs/${appState.ptauList.find(ptau => ptau.name === appState.ptauValue)?.ipfsHash}` |
|
|
|
|
await plugin.generateR1cs(appState.filePath, { version: appState.version, prime: appState.primeValue }) |
|
|
|
|
|
|
|
|
@ -50,32 +60,38 @@ export const runSetupAndExport = async (plugin: CircomPluginClient, appState: Ap |
|
|
|
|
const zkey_final = { type: "mem" } |
|
|
|
|
|
|
|
|
|
if (appState.provingScheme === 'groth16') { |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'runSetupAndExport', 'provingScheme', 'groth16']) |
|
|
|
|
await snarkjs.zKey.newZKey(r1cs, ptau_final, zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK')) |
|
|
|
|
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK')) |
|
|
|
|
|
|
|
|
|
if (appState.exportVerificationKey) { |
|
|
|
|
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/keys/verification_key.json`, JSON.stringify(vKey, null, 2)) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'runSetupAndExport', 'zKey.exportVerificationKey', `${extractParentFromKey(appState.filePath)}/groth16/zk/keys/verification_key.json`]) |
|
|
|
|
} |
|
|
|
|
if (appState.exportVerificationContract) { |
|
|
|
|
const templates = { groth16: GROTH16_VERIFIER } |
|
|
|
|
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK')) |
|
|
|
|
|
|
|
|
|
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/zk_verifier.sol`, solidityContract) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'runSetupAndExport', 'zKey.exportSolidityVerifier', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/zk_verifier.sol`]) |
|
|
|
|
} |
|
|
|
|
dispatch({ type: 'SET_ZKEY', payload: zkey_final }) |
|
|
|
|
dispatch({ type: 'SET_VERIFICATION_KEY', payload: vKey }) |
|
|
|
|
} else if (appState.provingScheme === 'plonk') { |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'runSetupAndExport', 'provingScheme', 'plonk']) |
|
|
|
|
await snarkjs.plonk.setup(r1cs, ptau_final, zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK')) |
|
|
|
|
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK')) |
|
|
|
|
|
|
|
|
|
if (appState.exportVerificationKey) { |
|
|
|
|
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/keys/verification_key.json`, JSON.stringify(vKey, null, 2)) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'runSetupAndExport', 'zKey.exportVerificationKey', `${extractParentFromKey(appState.filePath)}/plonk/zk/keys/verification_key.json`]) |
|
|
|
|
} |
|
|
|
|
if (appState.exportVerificationContract) { |
|
|
|
|
const templates = { plonk: PLONK_VERIFIER } |
|
|
|
|
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK')) |
|
|
|
|
|
|
|
|
|
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/zk_verifier.sol`, solidityContract) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'runSetupAndExport', 'zKey.exportSolidityVerifier', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/zk_verifier.sol`]) |
|
|
|
|
} |
|
|
|
|
dispatch({ type: 'SET_ZKEY', payload: zkey_final }) |
|
|
|
|
dispatch({ type: 'SET_VERIFICATION_KEY', payload: vKey }) |
|
|
|
@ -83,6 +99,7 @@ export const runSetupAndExport = async (plugin: CircomPluginClient, appState: Ap |
|
|
|
|
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' }) |
|
|
|
|
dispatch({ type: 'SET_SETUP_EXPORT_STATUS', payload: 'done' }) |
|
|
|
|
} catch (e) { |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'runSetupAndExport', 'error', e.message]) |
|
|
|
|
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'errored' }) |
|
|
|
|
console.error(e) |
|
|
|
|
} |
|
|
|
@ -91,6 +108,8 @@ export const runSetupAndExport = async (plugin: CircomPluginClient, appState: Ap |
|
|
|
|
export const generateProof = async (plugin: CircomPluginClient, appState: AppState, dispatch: ICircuitAppContext['dispatch']) => { |
|
|
|
|
try { |
|
|
|
|
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'proving' }) |
|
|
|
|
dispatch({ type: 'SET_PROOF_FEEDBACK', payload: null }) |
|
|
|
|
plugin.emit('statusChanged', { key: 'none' }) |
|
|
|
|
const fileName = extractNameFromKey(appState.filePath) |
|
|
|
|
const r1csPath = extractParentFromKey(appState.filePath) + `/.bin/${fileName.replace('.circom', '.r1cs')}` |
|
|
|
|
// @ts-ignore
|
|
|
|
@ -110,21 +129,27 @@ export const generateProof = async (plugin: CircomPluginClient, appState: AppSta |
|
|
|
|
const { proof, publicSignals } = await snarkjs.groth16.prove(zkey_final, wtns, zkLogger(plugin, dispatch, 'SET_PROOF_FEEDBACK')) |
|
|
|
|
const verified = await snarkjs.groth16.verify(vKey, publicSignals, proof, zkLogger(plugin, dispatch, 'SET_PROOF_FEEDBACK')) |
|
|
|
|
|
|
|
|
|
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/proof.json`, JSON.stringify(proof, null, 2)) |
|
|
|
|
plugin.call('terminal', 'log', { type: 'log', value: 'zk proof validity ' + verified }) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'generateProof', 'groth16.prove', verified]) |
|
|
|
|
if (appState.exportVerifierCalldata) { |
|
|
|
|
const calldata = await snarkjs.groth16.exportSolidityCallData(proof, publicSignals) |
|
|
|
|
|
|
|
|
|
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/verifierCalldata.json`, calldata) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'generateProof', 'groth16.exportSolidityCallData', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/verifierCalldata.json`]) |
|
|
|
|
} |
|
|
|
|
} else if (appState.provingScheme === 'plonk') { |
|
|
|
|
const { proof, publicSignals } = await snarkjs.plonk.prove(zkey_final, wtns, zkLogger(plugin, dispatch, 'SET_PROOF_FEEDBACK')) |
|
|
|
|
const verified = await snarkjs.plonk.verify(vKey, publicSignals, proof, zkLogger(plugin, dispatch, 'SET_PROOF_FEEDBACK')) |
|
|
|
|
|
|
|
|
|
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/proof.json`, JSON.stringify(proof, null, 2)) |
|
|
|
|
plugin.call('terminal', 'log', { type: 'log', value: 'zk proof validity ' + verified }) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'generateProof', 'plonk.prove', verified]) |
|
|
|
|
if (appState.exportVerifierCalldata) { |
|
|
|
|
const calldata = await snarkjs.plonk.exportSolidityCallData(proof, publicSignals) |
|
|
|
|
|
|
|
|
|
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/verifierCalldata.json`, calldata) |
|
|
|
|
plugin._paq.push(['trackEvent', 'circuit-compiler', 'generateProof', 'plonk.exportSolidityCallData', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/verifierCalldata.json`]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' }) |
|
|
|
|