Save witness file

pull/4144/head
ioedeveloper 1 year ago
parent 63620c85dd
commit f0d76b9159
  1. 26
      apps/circuit-compiler/src/app/actions/index.ts
  2. 26
      apps/circuit-compiler/src/app/app.tsx
  3. 6
      apps/circuit-compiler/src/app/components/compileBtn.tsx
  4. 2
      apps/circuit-compiler/src/app/components/container.tsx
  5. 6
      apps/circuit-compiler/src/app/components/r1csBtn.tsx
  6. 21
      apps/circuit-compiler/src/app/components/witness.tsx
  7. 23
      apps/circuit-compiler/src/app/services/circomPluginClient.ts
  8. 2
      yarn.lock

@ -1,7 +1,7 @@
import { CircomPluginClient } from "../services/circomPluginClient" import type { CircomPluginClient } from "../services/circomPluginClient"
import { Actions, AppState } from "../types" import { Actions, AppState } from "../types"
export const compileCircuit = async (plugin: CircomPluginClient, appState: AppState, dispatch: React.Dispatch<Actions>) => { export const compileCircuit = async (plugin: CircomPluginClient, appState: AppState) => {
try { try {
if (appState.status !== "compiling") { if (appState.status !== "compiling") {
await plugin.compile(appState.filePath, { version: appState.version, prime: appState.primeValue }) await plugin.compile(appState.filePath, { version: appState.version, prime: appState.primeValue })
@ -9,12 +9,12 @@ export const compileCircuit = async (plugin: CircomPluginClient, appState: AppSt
console.log('Exisiting circuit compilation in progress') console.log('Exisiting circuit compilation in progress')
} }
} catch (e) { } catch (e) {
plugin.internalEvents.emit('circuit_compiling_errored', e)
console.error(e) console.error(e)
dispatch({ type: 'SET_SIGNAL_INPUTS', payload: [] })
} }
} }
export const generateR1cs = async (plugin: CircomPluginClient, appState: AppState, dispatch: React.Dispatch<Actions>) => { export const generateR1cs = async (plugin: CircomPluginClient, appState: AppState) => {
try { try {
if (appState.status !== "generating") { if (appState.status !== "generating") {
await plugin.generateR1cs(appState.filePath, { version: appState.version, prime: appState.primeValue }) await plugin.generateR1cs(appState.filePath, { version: appState.version, prime: appState.primeValue })
@ -22,6 +22,22 @@ export const generateR1cs = async (plugin: CircomPluginClient, appState: AppStat
console.log('Exisiting r1cs generation in progress') console.log('Exisiting r1cs generation in progress')
} }
} catch (e) { } catch (e) {
plugin.internalEvents.emit('circuit_generating_r1cs_errored', e)
console.error('Generating R1CS failed: ', e) console.error('Generating R1CS failed: ', e)
} }
} }
export const computeWitness = async (plugin: CircomPluginClient, status: string, witnessValues: Record<string, string>) => {
try {
if (status !== "computing") {
const input = JSON.stringify(witnessValues)
await plugin.computeWitness(input)
} else {
console.log('Exisiting witness computation in progress')
}
} catch (e) {
plugin.internalEvents.emit('circuit_computing_witness_errored', e)
console.error('Computing witness failed: ', e)
}
}

@ -16,7 +16,6 @@ function App() {
messages: null messages: null
}) })
const [isContentChanged, setIsContentChanged] = useState<boolean>(false) const [isContentChanged, setIsContentChanged] = useState<boolean>(false)
const [content, setNewContent] = useState<string>("")
useEffect(() => { useEffect(() => {
const plugin = new CircomPluginClient() const plugin = new CircomPluginClient()
@ -34,25 +33,36 @@ function App() {
} }
}) })
// @ts-ignore // @ts-ignore
plugin.on('editor', 'contentChanged', async (filePath, content) => { plugin.on('editor', 'contentChanged', async () => {
setIsContentChanged(true) setIsContentChanged(true)
setNewContent(content)
}) })
setPlugin(plugin) setPlugin(plugin)
}) })
plugin.internalEvents.on('circuit_compiling', () => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'compiling' }))
plugin.internalEvents.on('circuit_done', (signalInputs) => { // compiling events
plugin.internalEvents.on('circuit_compiling_start', () => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'compiling' }))
plugin.internalEvents.on('circuit_compiling_done', (signalInputs) => {
signalInputs = (signalInputs || []).filter(input => input) signalInputs = (signalInputs || []).filter(input => input)
dispatch({ type: 'SET_SIGNAL_INPUTS', payload: signalInputs }) dispatch({ type: 'SET_SIGNAL_INPUTS', payload: signalInputs })
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' }) dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' })
}) })
plugin.internalEvents.on('circuit_errored', (err) => dispatch({ type: 'SET_COMPILER_STATUS', payload: err.message })) plugin.internalEvents.on('circuit_compiling_errored', (err) => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'errored' }))
// r1cs events
plugin.internalEvents.on('circuit_generating_r1cs_start', () => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'generating' }))
plugin.internalEvents.on('circuit_generating_r1cs_done', () => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' }))
plugin.internalEvents.on('circuit_generating_r1cs_errored', (err) => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'errored' }))
// witness events
plugin.internalEvents.on('circuit_computing_witness_start', () => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'computing' }))
plugin.internalEvents.on('circuit_computing_witness_done', () => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' }))
plugin.internalEvents.on('circuit_computing_witness_errored', (err) => dispatch({ type: 'SET_COMPILER_STATUS', payload: 'errored' }))
}, []) }, [])
useEffect(() => { useEffect(() => {
if (isContentChanged) { if (isContentChanged) {
(async () => { (async () => {
if (appState.autoCompile) await compileCircuit(plugin, appState, dispatch) if (appState.autoCompile) await compileCircuit(plugin, appState)
})() })()
setIsContentChanged(false) setIsContentChanged(false)
} }
@ -67,7 +77,7 @@ function App() {
useEffect(() => { useEffect(() => {
if (appState.filePath) { if (appState.filePath) {
(async () => { (async () => {
if (appState.autoCompile) await compileCircuit(plugin, appState, dispatch) if (appState.autoCompile) await compileCircuit(plugin, appState)
})() })()
} }
}, [appState.filePath]) }, [appState.filePath])

@ -5,14 +5,12 @@ import { FormattedMessage } from "react-intl";
import { compileCircuit } from "../actions"; import { compileCircuit } from "../actions";
export function CompileBtn () { export function CompileBtn () {
const { plugin, appState, dispatch } = useContext(CircuitAppContext) const { plugin, appState } = useContext(CircuitAppContext)
return ( return (
<button <button
className="btn btn-primary btn-block d-block w-100 text-break mb-1 mt-3" className="btn btn-primary btn-block d-block w-100 text-break mb-1 mt-3"
onClick={() => { compileCircuit(plugin, appState, dispatch) }} onClick={() => { compileCircuit(plugin, appState) }}
disabled={(appState.filePath === "") || (appState.status === "compiling") || (appState.status === "generating")} disabled={(appState.filePath === "") || (appState.status === "compiling") || (appState.status === "generating")}
> >
<CustomTooltip <CustomTooltip

@ -37,7 +37,7 @@ export function Container () {
<CircuitActions /> <CircuitActions />
<RenderIf condition={circuitApp.appState.signalInputs.length > 0}> <RenderIf condition={circuitApp.appState.signalInputs.length > 0}>
<WitnessToggler> <WitnessToggler>
<WitnessSection signalInputs={circuitApp.appState.signalInputs} status={circuitApp.appState.status} /> <WitnessSection plugin={circuitApp.plugin} signalInputs={circuitApp.appState.signalInputs} status={circuitApp.appState.status} />
</WitnessToggler> </WitnessToggler>
</RenderIf> </RenderIf>
</div> </div>

@ -5,13 +5,13 @@ import { FormattedMessage } from "react-intl";
import { generateR1cs } from "../actions"; import { generateR1cs } from "../actions";
export function R1CSBtn () { export function R1CSBtn () {
const { plugin, appState, dispatch } = useContext(CircuitAppContext) const { plugin, appState } = useContext(CircuitAppContext)
return ( return (
<button <button
className="btn btn-secondary btn-block d-block w-100 text-break mb-1 mt-2" className="btn btn-secondary btn-block d-block w-100 text-break mb-1 mt-2"
onClick={() => { generateR1cs(plugin, appState, dispatch) }} onClick={() => { generateR1cs(plugin, appState) }}
disabled={(appState.filePath === "") || (appState.status === "compiling") || (appState.status === "generating")} disabled={(appState.filePath === "") || (appState.status === "compiling") || (appState.status === "generating") || (appState.status === "computing")}
> >
<CustomTooltip <CustomTooltip
placement="auto" placement="auto"

@ -1,8 +1,20 @@
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 { CompilerStatus } from "../types";
import { computeWitness } from "../actions";
import { useState } from "react";
import type { CircomPluginClient } from "../services/circomPluginClient";
export function WitnessSection ({ plugin, signalInputs, status }: {plugin: CircomPluginClient, signalInputs: string[], status: CompilerStatus}) {
const [witnessValues, setWitnessValues] = useState<Record<string, string>>({})
const handleSignalInput = (e: any) => {
setWitnessValues({
...witnessValues,
[e.target.name]: e.target.value
})
}
export function WitnessSection ({ signalInputs, status }: {signalInputs: string[], status: CompilerStatus}) {
return ( return (
<div className="pb-2 border-bottom flex-column"> <div className="pb-2 border-bottom flex-column">
<div className="flex-column d-flex"> <div className="flex-column d-flex">
@ -14,11 +26,14 @@ export function WitnessSection ({ signalInputs, status }: {signalInputs: string[
<label className="circuit_inner_label form-check-label" htmlFor="circuitPrimeSelector"> <label className="circuit_inner_label form-check-label" htmlFor="circuitPrimeSelector">
<FormattedMessage id="circuit.signalInput" /> { input } <FormattedMessage id="circuit.signalInput" /> { input }
</label> </label>
<input className="form-control m-0 txinput" placeholder={input} /> <input className="form-control m-0 txinput" placeholder={input} name={input} onChange={handleSignalInput} />
</div> </div>
)) ))
} }
<button className="btn btn-sm btn-secondary" > <button
className="btn btn-sm btn-secondary"
onClick={() => { computeWitness(plugin, status, witnessValues) }}
disabled={(status === "compiling") || (status === "generating") || (status === "computing")}>
<RenderIf condition={status === 'computing'}> <RenderIf condition={status === 'computing'}>
<i className="fas fa-sync fa-spin mr-2" aria-hidden="true"></i> <i className="fas fa-sync fa-spin mr-2" aria-hidden="true"></i>
</RenderIf> </RenderIf>

@ -107,7 +107,7 @@ export class CircomPluginClient extends PluginClient {
} }
async compile(path: string, compilationConfig?: CompilationConfig): Promise<void> { async compile(path: string, compilationConfig?: CompilationConfig): Promise<void> {
this.internalEvents.emit('circuit_compiling') this.internalEvents.emit('circuit_compiling_start')
if (compilationConfig) { if (compilationConfig) {
const { prime, version } = compilationConfig const { prime, version } = compilationConfig
@ -128,7 +128,6 @@ export class CircomPluginClient extends PluginClient {
if (circuitProgram.length < 1) { if (circuitProgram.length < 1) {
const circuitErrors = circuitApi.report() const circuitErrors = circuitApi.report()
this.internalEvents.emit('circuit_errored', circuitErrors)
throw new Error(circuitErrors) throw new Error(circuitErrors)
} else { } else {
const fileName = extractNameFromKey(path) const fileName = extractNameFromKey(path)
@ -142,9 +141,9 @@ export class CircomPluginClient extends PluginClient {
const componentName = searchComponentName[1] const componentName = searchComponentName[1]
const signals = circuitApi.input_signals(componentName) const signals = circuitApi.input_signals(componentName)
this.internalEvents.emit('circuit_done', signals) this.internalEvents.emit('circuit_compiling_done', signals)
} else { } else {
this.internalEvents.emit('circuit_done', []) this.internalEvents.emit('circuit_compiling_done', [])
} }
} }
// const witness = await generate_witness(compiledOutput, '{ "identityTrapdoor": "12656283236575022300303467601783819380815431272685589718060054649894766174337", "identityNullifier": "15178877681550417450385541477607788220584140707925739215609273992582659710290", "treePathIndices": "0", "treeSiblings": "1", "externalNullifier": "5df6e0e3480d6fbc32925076897ec6b9b935d75ae8f4d9f4858a426f8f6a4ab": "signalHash": "[85, 139, 239, 32, 221, 194, 165, 19, 20, 52, 104, 144, 41, 16, 40, 204, 171, 245, 198, 77, 94, 143, 30, 112, 105, 165, 33, 15, 62, 156, 18, 118]"}') // const witness = await generate_witness(compiledOutput, '{ "identityTrapdoor": "12656283236575022300303467601783819380815431272685589718060054649894766174337", "identityNullifier": "15178877681550417450385541477607788220584140707925739215609273992582659710290", "treePathIndices": "0", "treeSiblings": "1", "externalNullifier": "5df6e0e3480d6fbc32925076897ec6b9b935d75ae8f4d9f4858a426f8f6a4ab": "signalHash": "[85, 139, 239, 32, 221, 194, 165, 19, 20, 52, 104, 144, 41, 16, 40, 204, 171, 245, 198, 77, 94, 143, 30, 112, 105, 165, 33, 15, 62, 156, 18, 118]"}')
@ -207,7 +206,7 @@ export class CircomPluginClient extends PluginClient {
} }
async generateR1cs (path: string, compilationConfig?: CompilationConfig): Promise<void> { async generateR1cs (path: string, compilationConfig?: CompilationConfig): Promise<void> {
this.internalEvents.emit('circuit_generating') this.internalEvents.emit('circuit_generating_r1cs_start')
if (compilationConfig) { if (compilationConfig) {
const { prime, version } = compilationConfig const { prime, version } = compilationConfig
@ -228,10 +227,9 @@ export class CircomPluginClient extends PluginClient {
if (r1csProgram.length < 1) { if (r1csProgram.length < 1) {
const r1csErrors = r1csApi.report() const r1csErrors = r1csApi.report()
this.internalEvents.emit('circuit_errored', r1csErrors)
throw new Error(r1csErrors) throw new Error(r1csErrors)
} else { } else {
this.internalEvents.emit('circuit_done') this.internalEvents.emit('circuit_generating_r1cs_done')
const fileName = extractNameFromKey(path) const fileName = extractNameFromKey(path)
const writePath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'r1cs') const writePath = extractParentFromKey(path) + "/.bin/" + fileName.replace('circom', 'r1cs')
@ -240,15 +238,18 @@ export class CircomPluginClient extends PluginClient {
} }
} }
async computeWitness (input: string, wasmPath?: string): Promise<void> { async computeWitness (input: string): Promise<void> {
this.internalEvents.emit('circuit_computing') this.internalEvents.emit('circuit_computing_witness_start')
if (!wasmPath) wasmPath = this.lastCompiledCircuitPath const wasmPath = this.lastCompiledCircuitPath
if (!wasmPath) throw new Error('No wasm file found')
if (!wasmPath) throw new Error('No wasm file found')
// @ts-ignore // @ts-ignore
const buffer: any = await this.call('fileManager', 'readFile', wasmPath, true) const buffer: any = await this.call('fileManager', 'readFile', wasmPath, true)
const dataRead = new Uint8Array(buffer) const dataRead = new Uint8Array(buffer)
const witness = await generate_witness(dataRead, input) const witness = await generate_witness(dataRead, input)
// @ts-ignore
await this.call('fileManager', 'writeFile', wasmPath.replace('.wasm', '.wtn'), witness, true)
this.internalEvents.emit('circuit_computing_witness_done')
} }
async resolveDependencies(filePath: string, fileContent: string, output = {}, depPath: string = '', blackPath: string[] = []): Promise<Record<string, string>> { async resolveDependencies(filePath: string, fileContent: string, output = {}, depPath: string = '', blackPath: string[] = []): Promise<Record<string, string>> {

@ -9729,7 +9729,7 @@ circom_runtime@0.1.22:
"circom_wasm@https://github.com/ioedeveloper/circom_wasm.git": "circom_wasm@https://github.com/ioedeveloper/circom_wasm.git":
version "0.0.0-alpha.7" version "0.0.0-alpha.7"
resolved "https://github.com/ioedeveloper/circom_wasm.git#a8c53a02e97fa5e8533618a070d1b7fdb655fdc5" resolved "https://github.com/ioedeveloper/circom_wasm.git#dca0ba5f8f9c541e9f7e927bb8c32d6e326ce487"
circular-json@^0.3.0: circular-json@^0.3.0:
version "0.3.3" version "0.3.3"

Loading…
Cancel
Save