Skip to content

Commit

Permalink
feat: add zpk client wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
juliopavila committed May 14, 2024
1 parent 54fd4d1 commit bf4a17f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 31 deletions.
9 changes: 3 additions & 6 deletions packages/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,19 @@ import About from '@/pages/About/About'
import PollResult from '@/pages/PollResult/PollResult'
import useScrollToTop from '@/hooks/generic/useScrollToTop'
import { useVoteManagementContext } from '@/context/voteManagement'
import useCircuit from '@/hooks/wasm/useCircuit'

const App: React.FC = () => {
useScrollToTop()
const { initialLoad, wasmInstance } = useVoteManagementContext()
const { client } = useCircuit()
const { initialLoad, wasmInstance, zpkClient } = useVoteManagementContext()

console.log('client', client)
useEffect(() => {
if (!wasmInstance) {
if (!wasmInstance && !zpkClient) {
async function loadWasm() {
await initialLoad()
}
loadWasm()
}
}, [wasmInstance])
}, [wasmInstance, zpkClient])

return (
<Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { convertPollData, convertTimestampToDate } from '@/utils/methods'
import { Poll, PollResult } from '@/model/poll.model'
import { generatePoll } from '@/utils/generate-random-poll'
import { handleGenericError } from '@/utils/handle-generic-error'
import useCircuitHook from '@/hooks/wasm/useCircuit'

const [useVoteManagementContext, VoteManagementContextProvider] = createGenericContext<VoteManagementContextType>()

Expand All @@ -30,6 +31,7 @@ const VoteManagementProvider = ({ children }: VoteManagementProviderProps) => {
* Voting Management Methods
**/
const { isLoading: wasmLoading, wasmInstance, encryptInstance, initWebAssembly, encryptVote } = useWebAssemblyHook()
const { proveVote, initCircuits, zpkClient } = useCircuitHook()
const {
isLoading: enclaveLoading,
getRoundStateLite: getRoundStateLiteRequest,
Expand All @@ -40,6 +42,7 @@ const VoteManagementProvider = ({ children }: VoteManagementProviderProps) => {

const initialLoad = async () => {
await initWebAssembly()
await initCircuits()
const round = await getRound()
if (round) {
await getRoundStateLite(round.round_count)
Expand Down Expand Up @@ -104,6 +107,8 @@ const VoteManagementProvider = ({ children }: VoteManagementProviderProps) => {
pollOptions,
roundState,
pastPolls,
zpkClient,
proveVote,
existNewRound,
getWebResult,
setPastPolls,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import * as WasmInstance from 'libs/wasm/pkg/crisp_web'
import { SocialAuth } from '@/model/twitter.model'
import { BroadcastVoteRequest, BroadcastVoteResponse, VoteStateLite, VotingRound } from '@/model/vote.model'
import { Poll, PollRequestResult, PollResult } from '@/model/poll.model'
import { Proof, ZKPClient } from 'enclave-circuits/src/client'

export type VoteManagementContextType = {
isLoading: boolean
zpkClient: ZKPClient | null
wasmInstance: WasmInstance.InitOutput | null
encryptInstance: WasmInstance.Encrypt | null
user: SocialAuth | null
Expand All @@ -15,6 +17,7 @@ export type VoteManagementContextType = {
roundState: VoteStateLite | null
pastPolls: PollResult[]
setPollOptions: React.Dispatch<React.SetStateAction<Poll[]>>
proveVote: (vote: number) => Promise<Proof | undefined>
initialLoad: () => Promise<void>
existNewRound: () => Promise<void>
getPastPolls: (roundCount: number) => Promise<void>
Expand Down
78 changes: 57 additions & 21 deletions packages/client/src/hooks/wasm/useCircuit.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,69 @@
import { useEffect, useState } from 'react'
import { ZKPClient } from 'enclave-circuits/src/client'
import { useState } from 'react'
import { Proof, ZKPClient } from 'enclave-circuits/src/client'
import { Buffer } from 'buffer'
import { handleGenericError } from '@/utils/handle-generic-error'
import { useNotificationAlertContext } from '@/context/NotificationAlert'

let cache: ZKPClient | undefined

function useCircuit(): { client?: ZKPClient } {
const [client, setClient] = useState<ZKPClient>()
export const useCircuitHook = () => {
const { showToast } = useNotificationAlertContext()
const [zpkClient, setZPKClient] = useState<ZKPClient | null>(null)
const [isLoading, setIsLoading] = useState<boolean>(false)

useEffect(() => {
const initCircuits = async () => {
if (!cache) {
Promise.all([
fetch(`${import.meta.env.PUBLIC_URL}/libs/wasm/circuits/vote_integrity/vote_integrity.wasm`).then((res) => res.arrayBuffer()),
fetch(`${import.meta.env.PUBLIC_URL}/libs/wasm/circuits/vote_integrity/vote_integrity_0001.zkey`).then((res) => res.arrayBuffer()),
]).then(([wasm, zkey]) => {
console.log('wasm', wasm)
console.log('zkey', zkey)
new ZKPClient().init(Buffer.from(wasm), Buffer.from(zkey)).then((_client) => {
if (!cache) {
cache = _client
}
setClient(_client)
try {
setIsLoading(true)
const [wasmBuffer, zkeyBuffer] = await Promise.all([
fetch('libs/wasm/circuits/vote_integrity/vote_integrity.wasm').then((res) => res.arrayBuffer()),
fetch('libs/wasm/circuits/vote_integrity/vote_integrity_0001.zkey').then((res) => res.arrayBuffer()),
])

const newClient = new ZKPClient()
await newClient.init(Buffer.from(wasmBuffer), Buffer.from(zkeyBuffer))

cache = newClient
setZPKClient(newClient)
} catch (err) {
showToast({
type: 'danger',
message: 'Failed to initialize ZKPClient',
})
})
handleGenericError('initCircuit', err as Error)
} finally {
setIsLoading(false)
}
} else {
setClient(cache)
setZPKClient(cache)
}
}

const proveVote = async (vote: number): Promise<Proof | undefined> => {
if (!zpkClient) {
console.error('ZKPClient not initialized')
return
}
try {
setIsLoading(true)
return await zpkClient.prove({ vote })
} catch (err) {
showToast({
type: 'danger',
message: 'Failed to generate proof',
})
handleGenericError('proveVote', err as Error)
} finally {
setIsLoading(false)
}
}, [])
}

return { client }
return {
isLoading,
zpkClient,
initCircuits,
proveVote,
}
}

export default useCircuit
export default useCircuitHook
3 changes: 3 additions & 0 deletions packages/client/src/model/vote.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export interface RoundCount {
export interface BroadcastVoteRequest {
round_id: number
enc_vote_bytes: number[] //bytes
a: [bigint, bigint]
b: [[bigint, bigint], [bigint, bigint]]
c: [bigint, bigint]
}

export interface BroadcastVoteResponse {
Expand Down
11 changes: 7 additions & 4 deletions packages/client/src/pages/DailyPoll/DailyPoll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { useNotificationAlertContext } from '@/context/NotificationAlert'

const DailyPoll: React.FC = () => {
const { showToast } = useNotificationAlertContext()
const { encryptVote, broadcastVote, getRoundStateLite, existNewRound, votingRound, roundEndDate, roundState } = useVoteManagementContext()
const { encryptVote, broadcastVote, getRoundStateLite, existNewRound, proveVote, votingRound, roundEndDate, roundState } =
useVoteManagementContext()
const [voteCompleted, setVotedCompleted] = useState<boolean>(false)
const [loading, setLoading] = useState<boolean>(false)
const [newRoundLoading, setNewRoundLoading] = useState<boolean>(false)
Expand All @@ -26,16 +27,18 @@ const DailyPoll: React.FC = () => {
}
}, [roundState])

console.log('newRoundLoading', newRoundLoading)
const handleVoted = async (vote: Poll | null) => {
if (vote && votingRound) {
setLoading(true)
const voteEncrypted = await encryptVote(BigInt(vote.value), new Uint8Array(votingRound.pk_bytes))

if (voteEncrypted) {
const zpkProve = await proveVote(vote.value)
if (voteEncrypted && zpkProve) {
const broadcastVoteResponse = await broadcastVote({
round_id: votingRound.round_id,
enc_vote_bytes: Array.from(voteEncrypted),
a: zpkProve.a,
b: zpkProve.b,
c: zpkProve.c,
})
await getRoundStateLite(votingRound.round_id)
if (broadcastVoteResponse) {
Expand Down

0 comments on commit bf4a17f

Please sign in to comment.