Export witness as json

pull/5132/head
ioedeveloper 3 months ago
parent b87bfc70bf
commit 873ec52f01
  1. 14
      apps/circuit-compiler/src/app/actions/index.ts
  2. 2
      apps/circuit-compiler/src/app/components/container.tsx
  3. 25
      apps/circuit-compiler/src/app/components/witness.tsx
  4. 9
      apps/circuit-compiler/src/app/reducers/state.ts
  5. 3
      apps/circuit-compiler/src/app/services/circomPluginClient.ts
  6. 2
      apps/circuit-compiler/src/app/types/index.ts
  7. 1
      apps/remix-ide/src/app/tabs/locales/en/circuit.json

@ -19,12 +19,20 @@ 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 { try {
if (status !== "computing") { if (status !== "computing") {
const input = JSON.stringify(witnessValues) 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))
}
} else { } else {
console.log('Existing witness computation in progress') console.log('Existing witness computation in progress')
} }
@ -110,6 +118,7 @@ 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 { 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')) 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.call('terminal', 'log', { type: 'log', value: 'zk proof validity ' + verified })
if (appState.exportVerifierCalldata) { if (appState.exportVerifierCalldata) {
const calldata = await snarkjs.groth16.exportSolidityCallData(proof, publicSignals) const calldata = await snarkjs.groth16.exportSolidityCallData(proof, publicSignals)
@ -120,6 +129,7 @@ export const generateProof = async (plugin: CircomPluginClient, appState: AppSta
const { proof, publicSignals } = await snarkjs.plonk.prove(zkey_final, wtns, zkLogger(plugin, dispatch, 'SET_PROOF_FEEDBACK')) 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')) 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.call('terminal', 'log', { type: 'log', value: 'zk proof validity ' + verified })
if (appState.exportVerifierCalldata) { if (appState.exportVerifierCalldata) {
const calldata = await snarkjs.plonk.exportSolidityCallData(proof, publicSignals) const calldata = await snarkjs.plonk.exportSolidityCallData(proof, publicSignals)

@ -140,7 +140,7 @@ export function Container () {
<RenderIf condition={circuitApp.appState.signalInputs.length > 0}> <RenderIf condition={circuitApp.appState.signalInputs.length > 0}>
<Toggler title='circuit.computeWitness' dataId='witness_toggler' show={!!circuitApp.appState.setupExportStatus}> <Toggler title='circuit.computeWitness' dataId='witness_toggler' show={!!circuitApp.appState.setupExportStatus}>
<> <>
<WitnessSection plugin={circuitApp.plugin} signalInputs={circuitApp.appState.signalInputs} status={circuitApp.appState.status} /> <WitnessSection />
<RenderIf condition={circuitApp.appState.status !== 'computing'}> <RenderIf condition={circuitApp.appState.status !== 'computing'}>
<CompilerFeedback feedback={circuitApp.appState.computeFeedback} filePathToId={circuitApp.appState.filePathToId} openErrorLocation={handleOpenErrorLocation} hideWarnings={circuitApp.appState.hideWarnings} askGPT={askGPT} /> <CompilerFeedback feedback={circuitApp.appState.computeFeedback} filePathToId={circuitApp.appState.filePathToId} openErrorLocation={handleOpenErrorLocation} hideWarnings={circuitApp.appState.hideWarnings} askGPT={askGPT} />
</RenderIf> </RenderIf>

@ -1,12 +1,14 @@
import { RenderIf, RenderIfNot } from "@remix-ui/helper"; import { RenderIf, RenderIfNot } from "@remix-ui/helper";
import { FormattedMessage } from "react-intl"; import { FormattedMessage } from "react-intl";
import { CompilerStatus } from "../types";
import { computeWitness } from "../actions"; import { computeWitness } from "../actions";
import { useState } from "react"; import { useContext, useState } from "react";
import type { CircomPluginClient } from "../services/circomPluginClient";
import * as remixLib from '@remix-project/remix-lib' import * as remixLib from '@remix-project/remix-lib'
import { CircuitAppContext } from "../contexts";
export function WitnessSection ({ plugin, signalInputs, status }: {plugin: CircomPluginClient, signalInputs: string[], status: CompilerStatus}) { export function WitnessSection () {
const circuitApp = useContext(CircuitAppContext)
const { signalInputs, status, exportWtnsJson } = circuitApp.appState
const { plugin, dispatch, appState } = circuitApp
const [witnessValues, setWitnessValues] = useState<Record<string, string>>({}) const [witnessValues, setWitnessValues] = useState<Record<string, string>>({})
const handleSignalInput = (e: any) => { const handleSignalInput = (e: any) => {
@ -47,9 +49,22 @@ export function WitnessSection ({ plugin, signalInputs, status }: {plugin: Circo
</div> </div>
)) ))
} }
<div className="custom-control custom-checkbox">
<input
className="custom-control-input"
type="checkbox"
title="Export Witness As JSON"
id="circuitExportWtnsJson"
onChange={() => { dispatch({ type: 'SET_EXPORT_WTNS_JSON', payload: !exportWtnsJson }) }}
checked={exportWtnsJson}
/>
<label className="form-check-label custom-control-label pt-1" htmlFor="circuitExportWtnsJson">
<FormattedMessage id="circuit.exportWtnsJson" />
</label>
</div>
<button <button
className="btn btn-secondary btn-block d-block w-100 text-break mb-1 mt-1" className="btn btn-secondary btn-block d-block w-100 text-break mb-1 mt-1"
onClick={() => { computeWitness(plugin, status, witnessValues) }} onClick={() => { computeWitness(plugin, appState, dispatch, status, witnessValues) }}
disabled={(status === "compiling") || (status === "computing")} disabled={(status === "compiling") || (status === "computing")}
data-id="compute_witness_btn" data-id="compute_witness_btn"
> >

@ -21,8 +21,9 @@ export const appInitialState: AppState = {
ptauList: PTAU_LIST, ptauList: PTAU_LIST,
ptauValue: "final_14.ptau", ptauValue: "final_14.ptau",
exportVerificationContract: true, exportVerificationContract: true,
exportVerificationKey: true, exportVerificationKey: false,
exportVerifierCalldata: true, exportVerifierCalldata: true,
exportWtnsJson: false,
verificationKey: null, verificationKey: null,
zKey: null zKey: null
} }
@ -138,6 +139,12 @@ export const appReducer = (state = appInitialState, action: Actions): AppState =
setupExportStatus: action.payload setupExportStatus: action.payload
} }
case 'SET_EXPORT_WTNS_JSON':
return {
...state,
exportWtnsJson: action.payload
}
case 'SET_VERIFICATION_KEY': case 'SET_VERIFICATION_KEY':
return { return {
...state, ...state,

@ -237,7 +237,7 @@ export class CircomPluginClient extends PluginClient {
} }
} }
async computeWitness (input: string): Promise<void> { async computeWitness (input: string): Promise<Uint8Array> {
this.internalEvents.emit('circuit_computing_witness_start') this.internalEvents.emit('circuit_computing_witness_start')
this.emit('statusChanged', { key: 'loading', title: 'Computing...', type: 'info' }) this.emit('statusChanged', { key: 'loading', title: 'Computing...', type: 'info' })
const wasmPath = this.lastCompiledCircuitPath const wasmPath = this.lastCompiledCircuitPath
@ -252,6 +252,7 @@ export class CircomPluginClient extends PluginClient {
this._paq.push(['trackEvent', 'circuit-compiler', 'computeWitness', 'Witness computing successful']) this._paq.push(['trackEvent', 'circuit-compiler', 'computeWitness', 'Witness computing successful'])
this.internalEvents.emit('circuit_computing_witness_done') this.internalEvents.emit('circuit_computing_witness_done')
this.emit('statusChanged', { key: 'succeed', title: 'witness computed successfully', type: 'success' }) this.emit('statusChanged', { key: 'succeed', title: 'witness computed successfully', type: 'success' })
return witness
} }
async resolveDependencies(filePath: string, fileContent: string, output?: Record<string, string>, depPath: string = '', blackPath: string[] = []): Promise<Record<string, string>> { async resolveDependencies(filePath: string, fileContent: string, output?: Record<string, string>, depPath: string = '', blackPath: string[] = []): Promise<Record<string, string>> {

@ -39,6 +39,7 @@ export interface ActionPayloadTypes {
SET_EXPORT_VERIFICATION_CONTRACT: boolean, SET_EXPORT_VERIFICATION_CONTRACT: boolean,
SET_EXPORT_VERIFICATION_KEY: boolean, SET_EXPORT_VERIFICATION_KEY: boolean,
SET_EXPORT_VERIFIER_CALLDATA: boolean, SET_EXPORT_VERIFIER_CALLDATA: boolean,
SET_EXPORT_WTNS_JSON: boolean,
SET_SETUP_EXPORT_STATUS: SetupExportStatus, SET_SETUP_EXPORT_STATUS: SetupExportStatus,
SET_VERIFICATION_KEY: Record<string, any>, SET_VERIFICATION_KEY: Record<string, any>,
SET_ZKEY: any SET_ZKEY: any
@ -71,6 +72,7 @@ export interface AppState {
exportVerificationContract: boolean, exportVerificationContract: boolean,
exportVerificationKey: boolean, exportVerificationKey: boolean,
exportVerifierCalldata: boolean, exportVerifierCalldata: boolean,
exportWtnsJson: boolean,
verificationKey: Record<string, any>, verificationKey: Record<string, any>,
zKey: Uint8Array zKey: Uint8Array
} }

@ -21,5 +21,6 @@
"circuit.exportVerifierContract": "Export verifier contract", "circuit.exportVerifierContract": "Export verifier contract",
"circuit.exportVerificationKey": "Export verification key", "circuit.exportVerificationKey": "Export verification key",
"circuit.exportVerifierCalldata": "Export verifier calldata", "circuit.exportVerifierCalldata": "Export verifier calldata",
"circuit.exportWtnsJson": "Export witness as JSON",
"circuit.runSetup": "Run setup" "circuit.runSetup": "Run setup"
} }

Loading…
Cancel
Save