diff --git a/app/App.tsx b/app/App.tsx deleted file mode 100644 index dc3072b..0000000 --- a/app/App.tsx +++ /dev/null @@ -1,252 +0,0 @@ -// 'use client' -// import React, { useEffect, useState } from 'react' - -// import init, {init_panic_hook} from '@ezkljs/engine/web/ezkl.js' - -// import GenWitness from './components/GenWitness' -// import ElgamalRandomVar from './components/ElgamalRandomVar' -// import ElgamalEncrypt from './components/ElgamalEncrypt' -// import ElgamalDecrypt from './components/ElgamalDecrypt' -// import GenProof from './components/GenProof' -// import Verify from './components/Verify' -// import EvmVerify from './components/EvmVerify' -// import Hash from './components/Hash' - -// interface Files { -// [key: string]: File | null -// } - -// export default function Home() { -// const [files, setFiles] = useState({}) - -// useEffect(() => { -// async function run() { -// // Initialize the WASM module -// await init(undefined, new WebAssembly.Memory({initial:20,maximum:4096,shared:true})) -// init_panic_hook() -// } -// run() -// }) - - -// const handleFileChange = (event: React.ChangeEvent) => { -// const id = event.target.id -// const file = event.target.files?.item(0) || null -// setFiles((prevFiles) => ({ ...prevFiles, [id]: file })) -// } - -// async function populateWithSampleFiles(MNIST: boolean = false) { - -// const sampleFiles: Files = {}; - -// // Fetch the elgamal_cipher.txt file -// const cipherResponse = await fetch('/data/elgamal_cipher.txt'); -// const cipherBlob: Blob = await cipherResponse.blob(); -// sampleFiles['elgamal_cipher'] = new File([cipherBlob], "elgamal_cipher.txt"); - -// // Fetch the elgamal_sk.txt file -// const skResponse = await fetch('/data/elgamal_var/sk.txt'); -// const skBlob: Blob = await skResponse.blob(); -// sampleFiles['elgamal_sk'] = new File([skBlob], "elgamal_sk.txt"); - -// // Fetch the elgamal_pk.txt file -// const pkResponse = await fetch('/data/elgamal_var/pk.txt'); -// const pkBlob: Blob = await pkResponse.blob(); -// sampleFiles['elgamal_pk'] = new File([pkBlob], "elgamal_pk.txt"); - -// // Fetch the elgamal_message.txt file -// const messageResponse = await fetch('/data/message.txt'); -// const messageBlob: Blob = await messageResponse.blob(); -// sampleFiles['elgamal_message'] = new File([messageBlob], "elgamal_message.txt"); - -// // Fetch the elgamal_r.txt file -// const rResponse = await fetch('/data/elgamal_var/r.txt'); -// const rBlob: Blob = await rResponse.blob(); -// sampleFiles['elgamal_r'] = new File([rBlob], "elgamal_r.txt"); - -// if(MNIST) { -// // Fetch the data_prove.txt file -// const dataProveResponse = await fetch('/data/mnist/witness.json'); -// const dataProveBlob: Blob = await dataProveResponse.blob(); -// sampleFiles['data_prove'] = new File([dataProveBlob], "data_prove.txt"); - -// // Fetch the pk_prove.txt file -// const pkProveResponse = await fetch('/data/mnist/key.pk'); -// const pkProveBlob: Blob = await pkProveResponse.blob(); -// sampleFiles['pk_prove'] = new File([pkProveBlob], "pk_prove.txt"); - -// // Fetch the model_ser_prove.txt file -// const modelSerProveResponse = await fetch('/data/mnist/compiled_net.onnx'); -// const modelSerProveBlob: Blob = await modelSerProveResponse.blob(); -// sampleFiles['model_ser_prove'] = new File([modelSerProveBlob], "model_ser_prove.txt"); - -// // Fetch the circuit_settings_ser_prove.txt file -// const circuitSettingsSerProveResponse = await fetch('/data/mnist/settings.json'); -// const circuitSettingsSerProveBlob: Blob = await circuitSettingsSerProveResponse.blob(); -// sampleFiles['circuit_settings_ser_prove'] = new File([circuitSettingsSerProveBlob], "circuit_settings_ser_prove.txt"); - -// // Fetch the srs_ser_prove.txt file -// const srsSerProveResponse = await fetch('/data/mnist/srs-5'); -// const srsSerProveBlob: Blob = await srsSerProveResponse.blob(); -// sampleFiles['srs_ser_prove'] = new File([srsSerProveBlob], "srs_ser_prove.txt"); - -// // Fetch the proof_js.txt file -// const proofJsResponse = await fetch('/data/mnist/proof.pf'); -// const proofJsBlob: Blob = await proofJsResponse.blob(); -// sampleFiles['proof_js'] = new File([proofJsBlob], "proof_js.txt"); - -// // Fetch the vk.txt file -// const vkResponse = await fetch('/data/mnist/key.vk'); -// const vkBlob: Blob = await vkResponse.blob(); -// sampleFiles['vk'] = new File([vkBlob], "vk.txt"); - -// // Fetch the circuit_settings_ser_verify.txt file -// const circuitSettingsSerVerifyResponse = await fetch('/data/mnist/settings.json'); -// const circuitSettingsSerVerifyBlob: Blob = await circuitSettingsSerVerifyResponse.blob(); -// sampleFiles['circuit_settings_ser_verify'] = new File([circuitSettingsSerVerifyBlob], "circuit_settings_ser_verify.txt"); - -// // Fetch the srs_ser_verify.txt file -// const srsSerVerifyResponse = await fetch('/data/mnist/srs-5'); -// const srsSerVerifyBlob: Blob = await srsSerVerifyResponse.blob(); -// sampleFiles['srs_ser_verify'] = new File([srsSerVerifyBlob], "srs_ser_verify.txt"); -// } else { -// // Fetch the data_prove.txt file -// const dataProveResponse = await fetch('/data/test.witness.json'); -// const dataProveBlob: Blob = await dataProveResponse.blob(); -// sampleFiles['data_prove'] = new File([dataProveBlob], "data_prove.txt"); - -// // Fetch the pk_prove.txt file -// const pkProveResponse = await fetch('/data/test.provekey'); -// const pkProveBlob: Blob = await pkProveResponse.blob(); -// sampleFiles['pk_prove'] = new File([pkProveBlob], "pk_prove.txt"); - -// // Fetch the model_ser_prove.txt file -// const modelSerProveResponse = await fetch('/data/test_network.compiled'); -// const modelSerProveBlob: Blob = await modelSerProveResponse.blob(); -// sampleFiles['model_ser_prove'] = new File([modelSerProveBlob], "model_ser_prove.txt"); - -// // Fetch the circuit_settings_ser_prove.txt file -// const circuitSettingsSerProveResponse = await fetch('/data/settings.json'); -// const circuitSettingsSerProveBlob: Blob = await circuitSettingsSerProveResponse.blob(); -// sampleFiles['circuit_settings_ser_prove'] = new File([circuitSettingsSerProveBlob], "circuit_settings_ser_prove.txt"); - -// // Fetch the srs_ser_prove.txt file -// const srsSerProveResponse = await fetch('/data/kzg'); -// const srsSerProveBlob: Blob = await srsSerProveResponse.blob(); -// sampleFiles['srs_ser_prove'] = new File([srsSerProveBlob], "srs_ser_prove.txt"); - -// // Fetch the proof_js.txt file -// const proofJsResponse = await fetch('/data/proof.pf'); -// const proofJsBlob: Blob = await proofJsResponse.blob(); -// sampleFiles['proof_js'] = new File([proofJsBlob], "proof_js.txt"); - -// // Fetch the vk.txt file -// const vkResponse = await fetch('/data/test.key'); -// const vkBlob: Blob = await vkResponse.blob(); -// sampleFiles['vk'] = new File([vkBlob], "vk.txt"); - -// // Fetch the circuit_settings_ser_verify.txt file -// const circuitSettingsSerVerifyResponse = await fetch('/data/settings.json'); -// const circuitSettingsSerVerifyBlob: Blob = await circuitSettingsSerVerifyResponse.blob(); -// sampleFiles['circuit_settings_ser_verify'] = new File([circuitSettingsSerVerifyBlob], "circuit_settings_ser_verify.txt"); - -// // Fetch the srs_ser_verify.txt file -// const srsSerVerifyResponse = await fetch('/data/kzg'); -// const srsSerVerifyBlob: Blob = await srsSerVerifyResponse.blob(); -// sampleFiles['srs_ser_verify'] = new File([srsSerVerifyBlob], "srs_ser_verify.txt"); -// } - -// // Fetch the message_hash.txt file -// const messageHashResponse = await fetch('/data/message.txt'); -// const messageHashBlob: Blob = await messageHashResponse.blob(); -// sampleFiles['message_hash'] = new File([messageHashBlob], "message_hash.txt"); - -// // Fetch the proof_evm.txt file -// const proofEvmResponse = await fetch('/data/proof.pf'); -// const proofEvmBlob: Blob = await proofEvmResponse.blob(); -// sampleFiles['proof_evm'] = new File([proofEvmBlob], "proof_evm.txt"); - -// // Fetch the bytecode_verifier.txt file -// const bytecodeVerifierResponse = await fetch('/data/bytecode.code'); -// const bytecodeVerifierBlob: Blob = await bytecodeVerifierResponse.blob(); -// sampleFiles['bytecode_verifier'] = new File([bytecodeVerifierBlob], "bytecode_verifier.txt"); - -// // Fetch the model_ser_witness.txt file -// const modelSerWitnessResponse = await fetch('/data/test_network.compiled'); -// const modelSerWitnessBlob: Blob = await modelSerWitnessResponse.blob(); -// sampleFiles['model_ser_witness'] = new File([modelSerWitnessBlob], "model_ser_witness.txt"); - -// // Fetch the input_witness.txt file -// const inputWitnessResponse = await fetch('/data/input.json'); -// const inputWitnessBlob: Blob = await inputWitnessResponse.blob(); -// sampleFiles['input_witness'] = new File([inputWitnessBlob], "input_witness.txt"); -// setFiles(sampleFiles); -// } - - -// return ( -//
-// -// - -// - -// - -// - -// - -// - -// -// - -// -//
-// ) -// } diff --git a/app/components/APINavColumn.tsx b/app/components/APINavColumn.tsx index b8338d7..7ed4d9a 100644 --- a/app/components/APINavColumn.tsx +++ b/app/components/APINavColumn.tsx @@ -86,7 +86,10 @@ function NavList() { Encryption
  • - Prove -{'>'} Verify + Prove +
  • +
  • + Verify
  • Field Element Utilities diff --git a/app/components/Main.tsx b/app/components/Main.tsx index 301209e..69c6d06 100644 --- a/app/components/Main.tsx +++ b/app/components/Main.tsx @@ -1,7 +1,7 @@ import React from 'react'; export default function Main({ children }: { children: React.ReactNode }) { return ( -
    +
    {children}
    ) diff --git a/app/prove-verify/page.tsx b/app/prove/page.tsx similarity index 60% rename from app/prove-verify/page.tsx rename to app/prove/page.tsx index bf069ed..467207f 100644 --- a/app/prove-verify/page.tsx +++ b/app/prove/page.tsx @@ -8,30 +8,21 @@ import { Spinner as _Spinner, Modal } from 'flowbite-react' -import React, { useEffect, useState } from 'react' -import { formDataSchemaProve, formDataSchemaVerify } from './parsers' +import React, { useState } from 'react' +import { formDataSchemaProve } from './parsers' import { stringify } from "json-bigint"; import { useSharedResources } from '../EngineContext'; -// Truncate Proof string -function showFirstAndLast(str: string, show: number): string { - if (str.length <= show * 2) return str // If the string is already 10 characters or fewer, return it as is. - return str.slice(0, show) + ' . . . ' + str.slice(-show) -} - -export default function ProveVerify() { +export default function Prove() { const { engine, utils } = useSharedResources(); const [openModal, setOpenModal] = useState(); const props = { openModal, setOpenModal }; const [alertProof, setAlertProof] = useState('') const [warningProof, setWarningProof] = useState('') - const [alertVerify, setAlertVerify] = useState('') - const [warningVerify, setWarningVerify] = useState('') const [loading, setLoading] = useState(false) const [proofResult, setProofResult] = useState('') const [proof, setProof] = useState({}) const [buffer, setBuffer] = useState(null) - const [verifyResult, setVerifyResult] = useState(''); const handleSubmitProve = async (e: React.FormEvent) => { e.preventDefault() @@ -103,67 +94,6 @@ export default function ProveVerify() { setLoading(false) } - const handleSubmitVerify = async (e: React.FormEvent) => { - e.preventDefault() - const formData = new FormData(e.currentTarget) - - const formInputs = { - proof: formData.get('proof'), - vk: formData.get('vk'), - settings: formData.get('settings'), - srs: formData.get('srs'), - } - // Validate form has valid inputs (zod) - const validatedFormInputs = formDataSchemaVerify.safeParse(formInputs) - - if (warningVerify) setWarningVerify('') - - if (!validatedFormInputs.success) { - setAlertVerify('Please upload all files') - return - } - - // Clear alert and warning - if (alertVerify) setAlertVerify('') - - // Missing data - if ( - validatedFormInputs.data.proof === null || - validatedFormInputs.data.vk === null || - validatedFormInputs.data.settings === null || - validatedFormInputs.data.srs === null - ) { - setAlertVerify('Please upload all files') - return - } - - setLoading(true) - - // create file object - const files = { - proof: validatedFormInputs.data.proof, - vk: validatedFormInputs.data.vk, - settings: validatedFormInputs.data.settings, - srs: validatedFormInputs.data.srs - } - /* ================== ENGINE API ====================== */ - utils.handleVerifyButton(files as { [key: string]: File }) - .then(({ output, executionTime }) => { - // Update result based on the outcome - setVerifyResult( - output - ? 'Verification successful. Execution time: ' + executionTime + ' ms' - : 'Verification failed' - ) - }) - .catch((error) => { - console.error('An error occurred:', error) - setWarningVerify(`Verification process failed with an error: ${error}`) - }) - - setLoading(false) - } - return (
    @@ -205,25 +135,12 @@ export default function ProveVerify() {
    - ) : verifyResult && !warningVerify ? ( -
    -

    {verifyResult}

    -
    - -
    -
    ) : loading ? ( ) : (
    -
    ) } -function VerifyingArtifactForm({ - handleSubmit, - alert, - warning -}: { - handleSubmit: (e: React.FormEvent) => void - alert: string - warning: string -}) { - return ( -
    -

    Verifying

    - {alert && ( - - {alert} - - )} - {warning && ( - - {warning} - - )} -
    - {/* PROOF */} -
    -
    - {/* SETTINGS */} -
    -
    - {/* VK */} -
    -
    - {/* SRS */} -
    -
    - -
    -
    - ) -} diff --git a/app/prove-verify/parsers.ts b/app/prove/parsers.ts similarity index 100% rename from app/prove-verify/parsers.ts rename to app/prove/parsers.ts diff --git a/app/setup/page.tsx b/app/setup/page.tsx index 5bd0bea..3d5a0ee 100644 --- a/app/setup/page.tsx +++ b/app/setup/page.tsx @@ -1,12 +1,10 @@ -// Example for pages/Page1.js 'use client' import { FileInput, Label, Button, Alert, - Spinner as _Spinner, - Modal + Spinner as _Spinner } from 'flowbite-react' import React, { useState } from 'react' import { formDataSchemaGenVk, formDataSchemaGenPk } from './parsers' @@ -279,14 +277,6 @@ async function populateWithSampleFiles() { compiledOnnxInputPk.files = dataTransfers[0].files; srsInputPk.files = dataTransfers[1].files; vkInput.files = dataTransfers[2].files; - - // // If the 'vk' file is different, you'd handle it separately - // const vkFile = await fetchAndCreateFile(`/${sampleFileNames.vk}`, sampleFileNames.vk); - // const vkDataTransfer = new DataTransfer(); - // vkDataTransfer.items.add(vkFile); - - // Trigger any onChange or update logic if necessary - // This part depends on your application. For example, you might need to call a state setter function if you're using React state to track file input values. } diff --git a/app/verify/page.tsx b/app/verify/page.tsx new file mode 100644 index 0000000..e1420e9 --- /dev/null +++ b/app/verify/page.tsx @@ -0,0 +1,254 @@ +// Example for pages/Page1.js +'use client' +import { + FileInput, + Label, + Button, + Alert, + Spinner as _Spinner +} from 'flowbite-react' +import React, { useState } from 'react' +import { formDataSchemaVerify } from './parsers' +import { useSharedResources } from '../EngineContext'; + +export default function Verify() { + const { utils } = useSharedResources(); + const [alertVerify, setAlertVerify] = useState('') + const [warningVerify, setWarningVerify] = useState('') + const [loading, setLoading] = useState(false) + const [verifyResult, setVerifyResult] = useState(''); + + const handleSubmitVerify = async (e: React.FormEvent) => { + e.preventDefault() + const formData = new FormData(e.currentTarget) + + const formInputs = { + proof: formData.get('proof'), + vk: formData.get('vk'), + settings: formData.get('settings'), + srs: formData.get('srs'), + } + // Validate form has valid inputs (zod) + const validatedFormInputs = formDataSchemaVerify.safeParse(formInputs) + + if (warningVerify) setWarningVerify('') + + if (!validatedFormInputs.success) { + setAlertVerify('Please upload all files') + return + } + + // Clear alert and warning + if (alertVerify) setAlertVerify('') + + // Missing data + if ( + validatedFormInputs.data.proof === null || + validatedFormInputs.data.vk === null || + validatedFormInputs.data.settings === null || + validatedFormInputs.data.srs === null + ) { + setAlertVerify('Please upload all files') + return + } + + setLoading(true) + + // create file object + const files = { + proof: validatedFormInputs.data.proof, + vk: validatedFormInputs.data.vk, + settings: validatedFormInputs.data.settings, + srs: validatedFormInputs.data.srs + } + /* ================== ENGINE API ====================== */ + utils.handleVerifyButton(files as { [key: string]: File }) + .then(({ output, executionTime }) => { + // Update result based on the outcome + setVerifyResult( + output + ? 'Verification successful. Execution time: ' + executionTime + ' ms' + : 'Verification failed' + ) + }) + .catch((error) => { + console.error('An error occurred:', error) + setWarningVerify(`Verification process failed with an error: ${error}`) + }) + + setLoading(false) + } + + + return ( +
    + {verifyResult && !warningVerify ? ( +
    +

    {verifyResult}

    +
    + +
    +
    + ) : loading ? ( + + ) : ( +
    +
    + +
    + +
    + )} +
    + ); +} +// UI Component +function Spinner() { + return ( +
    + <_Spinner size='3xl' className='w-28 lg:w-44' /> +
    + ) +} + +async function populateWithSampleFiles() { + // Helper to assert that the element is not null + function assertElement(element: T | null): asserts element is T { + if (element === null) { + throw new Error('Element not found'); + } + } + + // Names of the sample files in the public directory + const sampleFileNames: { [key: string]: string } = { + srs: 'kzg', + proof: 'test.pf', + settings: 'settings.json', + vk: 'test.key' + }; + + // Helper function to fetch and create a file object from a public URL + const fetchAndCreateFile = async (path: string, filename: string): Promise => { + const response = await fetch(path); + const blob = await response.blob(); + return new File([blob], filename, { type: blob.type }); + }; + + // Fetch each sample file and create a File object + const filePromises = Object.entries(sampleFileNames).map(([key, filename]) => + fetchAndCreateFile(`/data/${filename}`, filename) + ); + + // Wait for all files to be fetched and created + const files = await Promise.all(filePromises); + + // Select the file input elements and assign the FileList to each + const proof = document.querySelector('#proof'); + const settings = document.querySelector('#settings'); + const vk = document.querySelector('#vk'); + const srsVerify = document.querySelector('#srs_verify'); + + // Assert that the elements are not null + assertElement(proof); + assertElement(settings); + assertElement(vk); + assertElement(srsVerify); + + // Create a new DataTransfer to hold the files + let dataTransfers: DataTransfer[] = []; + files.forEach( + (file, idx) => { + const dataTransfer = new DataTransfer(); + dataTransfer.items.add(file) + dataTransfers[idx] = dataTransfer; + } + + ); + + srsVerify.files = dataTransfers[0].files; + proof.files = dataTransfers[1].files; + settings.files = dataTransfers[2].files; + vk.files = dataTransfers[3].files; +} + +function VerifyingArtifactForm({ + handleSubmit, + alert, + warning +}: { + handleSubmit: (e: React.FormEvent) => void + alert: string + warning: string +}) { + return ( +
    +

    Verifying

    + {alert && ( + + {alert} + + )} + {warning && ( + + {warning} + + )} +
    + {/* PROOF */} +
    +
    + {/* SETTINGS */} +
    +
    + {/* VK */} +
    +
    + {/* SRS */} +
    +
    + +
    +
    + ) +} diff --git a/app/verify/parsers.tsx b/app/verify/parsers.tsx new file mode 100644 index 0000000..89da9e9 --- /dev/null +++ b/app/verify/parsers.tsx @@ -0,0 +1,20 @@ +import { z } from 'zod' + +const fileSchema = z.custom((value) => { + if (value === null) return false + return value instanceof File && value.name.trim() !== '' +}, "File name can't be empty") + +export const formDataSchemaProve = z.object({ + witness: fileSchema, + pk: fileSchema, + compiled_onnx: fileSchema, + srs: fileSchema +}) + +export const formDataSchemaVerify = z.object({ + proof: fileSchema, + vk: fileSchema, + settings: fileSchema, + srs: fileSchema +})