Skip to content

Commit

Permalink
*use react.context to lift engine and utils state.
Browse files Browse the repository at this point in the history
  • Loading branch information
ethan-crypto committed Oct 26, 2023
1 parent 80dc948 commit 61fd307
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 88 deletions.
50 changes: 50 additions & 0 deletions app/EngineContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Initialize the engine and util imports in the SharedResourcesProvider component:
// Note: must import Uitls as a module instead of a component for engine to work (or else you will get 'self' is undefined wasm errors)
'use client'
import React, { createContext, useContext, useState, useEffect } from 'react';
type Utils = typeof import("./Utils")
type Engine = typeof import("@ezkljs/engine/web/ezkl")

interface SharedResources {
engine: Engine;
utils: Utils;
}

const SharedResourcesContext = createContext<SharedResources | null>(null);
export const useSharedResources = (): SharedResources => {
const context = useContext(SharedResourcesContext);
if (!context) {
throw new Error('useSharedResources must be used within a SharedResourcesProvider');
}
return context;
};

interface SharedResourcesProviderProps {
children: React.ReactNode;
}

export const SharedResourcesProvider: React.FC<SharedResourcesProviderProps> = ({ children }) => {
const [engine, setEngine] = useState<any>(null); // Replace 'any' with the actual type of 'engine'
const [utils, setUtils] = useState<any>(null); // Replace 'any' with the actual type of 'utils'

useEffect(() => {
async function initializeResources() {
// Initialize the WASM module
const engine = await import("@ezkljs/engine/web/ezkl");
setEngine(engine)
await engine.default(undefined, new WebAssembly.Memory({ initial: 20, maximum: 4096, shared: true }))
// For human readable wasm debug errors call this function
engine.init_panic_hook()
// Initialize the utils module
const utils = await import("./Utils");
setUtils(utils)
}
initializeResources();
}, []);

return (
<SharedResourcesContext.Provider value={{ engine, utils }}>
{children}
</SharedResourcesContext.Provider>
);
};
22 changes: 3 additions & 19 deletions app/encryption/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import {
} from 'flowbite-react'
import React, { useEffect, useState } from 'react'
import { formDataSchemaEncrypt, formDataSchemaDecrypt } from './parsers'
import { parse, stringify } from "json-bigint";
import { stringify } from "json-bigint";
import { useSharedResources } from '../EngineContext';

type Utils = typeof import("../Utils")
type Engine = typeof import("@ezkljs/engine/web/ezkl")

type Cipher = number[][][]
type DecryptedCipher = number[][]

export default function Encryption() {
const { engine, utils } = useSharedResources();
const [alertEncrypt, setAlertEncrypt] = useState<string>('')
const [warningEncrypt, setWarningEncrypt] = useState<string>('')
const [alertDecrypt, setAlertDecrypt] = useState<string>('')
Expand All @@ -28,25 +29,8 @@ export default function Encryption() {
const [bufferCipher, setBufferCipher] = useState<Uint8Array | null>(null)
const [bufferDecrypt, setBufferDecrypt] = useState<Uint8Array | null>(null)
const [decrypted, setDecrypted] = useState<DecryptedCipher>([] as DecryptedCipher)
const [utils, setUtils] = useState<Utils>({} as Utils)
const [engine, setEngine] = useState<Engine>({} as Engine)
const [decryptResult, setDecryptResult] = useState('');

useEffect(() => {
async function run() {
// Initialize the WASM module
const engine = await import("@ezkljs/engine/web/ezkl");
setEngine(engine)
await engine.default(undefined, new WebAssembly.Memory({ initial: 20, maximum: 4096, shared: true }))
// For human readable wasm debug errors call this function
engine.init_panic_hook()
// Initialize the utils module
const utils = await import("../Utils");
setUtils(utils)
}
run()
})

const handleSubmitEncryption = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
Expand Down
28 changes: 28 additions & 0 deletions app/felt-utils/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Example for pages/Page1.js
'use client'
import {
TextInput,
Label,
Button,
Alert,
Spinner as _Spinner,
} from 'flowbite-react'
import React, { useState } from 'react'
// import { formDataSchemaEncrypt, formDataSchemaDecrypt } from './parsers'
import { useSharedResources } from '../EngineContext';
import { stringify } from "json-bigint";

type Utils = typeof import("../Utils")
type Engine = typeof import("@ezkljs/engine/web/ezkl")

type Cipher = number[][][]
type DecryptedCipher = number[][]

export default function FeltUtils() {
const { engine, utils } = useSharedResources();

return (
<div className='flex flex-col justify-center items-center h-5/6 pb-20'>
</div>
);
}
6 changes: 6 additions & 0 deletions app/felt-utils/parsers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { z } from 'zod'

const fileSchema = z.custom<File | null>((value) => {
if (value === null) return false
return value instanceof File && value.name.trim() !== ''
}, "File name can't be empty")
25 changes: 3 additions & 22 deletions app/hashing/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,19 @@ import {
} from 'flowbite-react'
import React, { useEffect, useState } from 'react'
import { formDataSchema } from './parsers'
import { parse, stringify } from "json-bigint";
import { number } from 'zod';

type Utils = typeof import("../Utils")
type Engine = typeof import("@ezkljs/engine/web/ezkl")
import { stringify } from "json-bigint";
import { useSharedResources } from '../EngineContext';

type Hash = number[][][]

export default function Hashing() {
const { engine, utils } = useSharedResources();
const [alert, setAlert] = useState<string>('')
const [warning, setWarning] = useState<string>('')
const [loading, setLoading] = useState(false)
const [hash, setHash] = useState<Hash>([] as Hash)
const [hashResult, setHashResult] = useState<string>('')
const [buffer, setBuffer] = useState<Uint8ClampedArray | null>(null)
const [utils, setUtils] = useState<Utils>({} as Utils)
const [engine, setEngine] = useState<Engine>({} as Engine)

useEffect(() => {
async function run() {
// Initialize the WASM module
const engine = await import("@ezkljs/engine/web/ezkl");
setEngine(engine)
await engine.default(undefined, new WebAssembly.Memory({ initial: 20, maximum: 4096, shared: true }))
// For human readable wasm debug errors call this function
engine.init_panic_hook()
// Initialize the utils module
const utils = await import("../Utils");
setUtils(utils)
}
run()
})

const handleSubmitHashing = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
Expand Down
29 changes: 16 additions & 13 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import './globals.css'
import type { Metadata } from 'next'
import APINavColumn from './components/APINavColumn'
import Main from './components/Main'
import { SharedResourcesProvider } from './EngineContext';

export const metadata: Metadata = {
title: 'Engine Example',
Expand All @@ -15,20 +16,22 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
<html lang='en'>
<body className='m-0 h-screen flex flex-col'>
{/* <!-- Top Navbar --> */}
<Header />
<SharedResourcesProvider>
<html lang='en'>
<body className='m-0 h-screen flex flex-col'>
{/* <!-- Top Navbar --> */}
<Header />

{/* <!-- Content Area --> */}
<div className='flex-grow flex flex-row mt-16'>
{/* <!-- Left Navigation Column --> */}
<APINavColumn />
{/* <!-- Content Area --> */}
<div className='flex-grow flex flex-row mt-16'>
{/* <!-- Left Navigation Column --> */}
<APINavColumn />

{/* <!-- Main Content Area --> */}
<Main>{children}</Main>
</div>
</body>
</html>
{/* <!-- Main Content Area --> */}
<Main>{children}</Main>
</div>
</body>
</html>
</SharedResourcesProvider>
)
}
2 changes: 1 addition & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function Home() {
making it easy to integrate ZKML in any javascript project.
</p>
<p>
Our simple, yet powerful APIs allow you to encyrpt, hash, prove and
Our simple, yet powerful APIs allow you to encyrpt, hash, prove and
verify ML inferences in a variety of ways.
</p>
</main>
Expand Down
25 changes: 3 additions & 22 deletions app/prove-verify/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ import {
} from 'flowbite-react'
import React, { useEffect, useState } from 'react'
import { formDataSchemaProve, formDataSchemaVerify } from './parsers'
import { parse, stringify } from "json-bigint";

type Utils = typeof import("../Utils")
type Engine = typeof import("@ezkljs/engine/web/ezkl")

import { stringify } from "json-bigint";
import { useSharedResources } from '../EngineContext';
interface Proof {
proof: string;
instances: string;
Expand All @@ -26,6 +23,7 @@ function showFirstAndLast(str: string, show: number): string {
}

export default function ProveVerify() {
const { engine, utils } = useSharedResources();
const [alertProof, setAlertProof] = useState<string>('')
const [warningProof, setWarningProof] = useState<string>('')
const [alertVerify, setAlertVerify] = useState<string>('')
Expand All @@ -34,25 +32,8 @@ export default function ProveVerify() {
const [proofResult, setProofResult] = useState('')
const [proof, setProof] = useState<Proof>({} as Proof)
const [buffer, setBuffer] = useState<Uint8Array | null>(null)
const [utils, setUtils] = useState<Utils>({} as Utils)
const [engine, setEngine] = useState<Engine>({} as Engine)
const [verifyResult, setVerifyResult] = useState<string>('');

useEffect(() => {
async function run() {
// Initialize the WASM module
const engine = await import("@ezkljs/engine/web/ezkl");
setEngine(engine)
await engine.default(undefined, new WebAssembly.Memory({ initial: 20, maximum: 4096, shared: true }))
// For human readable wasm debug errors call this function
engine.init_panic_hook()
// Initialize the utils module
const utils = await import("../Utils");
setUtils(utils)
}
run()
})

const handleSubmitProve = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
Expand Down
22 changes: 11 additions & 11 deletions tests/fieldElementUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@

import * as wasmFunctions from '@ezkljs/engine/nodejs';
import {
import {
uint8ArrayToJsonObject,
intToFieldElement,
randomZScore
} from './utils';
} from './utils';

describe('Field element utils', () => {

it('field serialization round trip fuzzing', async() => {
const numRuns = 10;
for(let i = 0; i < numRuns; i++) {
it('field serialization round trip fuzzing', async () => {
const numRuns = 10;
for (let i = 0; i < numRuns; i++) {
// Get a random z-score value for testing
const floatingPoint = randomZScore();
// Max scale used in the calibrate method on the main ezkl repo.
const maxScale = 16;
for(let j = 0; j <= maxScale; j++) {
for (let j = 0; j <= maxScale; j++) {
const scale = j;
// Convert floating point to fixed point integer value
const integer = Math.round(floatingPoint*(1<<scale));
const integer = Math.round(floatingPoint * (1 << scale));

const floatingPointRoundTrip = integer/(1<<scale);
const floatingPointRoundTrip = integer / (1 << scale);

console.debug("Test floating point value", floatingPoint)
console.debug("Test scale (multiply floating point by 2^scale then rounding to get integer fixed point)", scale)
Expand All @@ -38,18 +38,18 @@ describe('Field element utils', () => {

const result3 = wasmFunctions.vecU64ToInt(U64sSer);
let integerOutput = uint8ArrayToJsonObject(new Uint8Array(result3.buffer));
if (i == 0 && j == 0) console.debug("Vec u64s to integer output",integerOutput);
if (i == 0 && j == 0) console.debug("Vec u64s to integer output", integerOutput);
expect(integerOutput).toBeCloseTo(integer);

let feltHexOutput = wasmFunctions.vecU64ToFelt(U64sSer);
if (i == 0 && j == 0) console.debug("Vec u64s to field element output (hex)",feltHexOutput);
if (i == 0 && j == 0) console.debug("Vec u64s to field element output (hex)", feltHexOutput);
let referenceFelt = intToFieldElement(integerOutput);
if (i == 0 && j == 0) console.debug("Reference field element (decimal)", referenceFelt);
expect(BigInt(feltHexOutput)).toBe(referenceFelt);
}
}
});
it('buffer to vec of vec u64', async() => {
it('buffer to vec of vec u64', async () => {
const testString = "test";
const serializedString = wasmFunctions.serialize(testString);
const result = wasmFunctions.bufferToVecOfVecU64(serializedString);
Expand Down

0 comments on commit 61fd307

Please sign in to comment.