Skip to content

Commit

Permalink
Merge pull request #8 from semaphore-protocol/feat/semaphore-v4-bench…
Browse files Browse the repository at this point in the history
…marks

feat(benchmarks): add semaphore-v4 benchmarks
  • Loading branch information
cedoor authored May 2, 2024
2 parents 82fa334 + 7a76749 commit 56718d6
Show file tree
Hide file tree
Showing 4 changed files with 624 additions and 61 deletions.
7 changes: 4 additions & 3 deletions apps/benchmarks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
"@chakra-ui/react": "^2.6.1",
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@semaphore-protocol/group": "^3.15.0",
"@semaphore-protocol/identity": "^3.15.0",
"@semaphore-protocol/proof": "^3.15.0",
"@semaphore-protocol/core": "4.0.0-beta.9",
"@semaphore-protocol/group": "3.15.2",
"@semaphore-protocol/identity": "3.15.2",
"@semaphore-protocol/proof": "3.15.2",
"buffer": "^6.0.3",
"events": "^3.3.0",
"framer-motion": "^10.12.12",
Expand Down
152 changes: 116 additions & 36 deletions apps/benchmarks/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Box, Button, Flex, List, ListIcon, ListItem, Text } from "@chakra-ui/react"
import { Box, Button, Flex, Heading, List, ListIcon, ListItem, Text } from "@chakra-ui/react"
import { Group } from "@semaphore-protocol/group"
import { Identity } from "@semaphore-protocol/identity"
import * as V4 from "@semaphore-protocol/core"
import { generateProof, verifyProof } from "@semaphore-protocol/proof"
import { useCallback, useState } from "react"
import { MdCheckCircle } from "react-icons/md"
Expand All @@ -11,9 +12,11 @@ import TreeDepth from "./components/TreeDepth"
const functions = ["new Identity", "new Group", "generateProof", "verifyProof", "addMember", "updateMember"]

function App() {
const [treeDepth, setTreeDepth] = useState<number>(20)
const [groupMembers, setGroupMembers] = useState<number>(100)
const [times, setTimes] = useState<number[]>([])
const [v3treeDepth, setV3TreeDepth] = useState<number>(20)
const [v3GroupMembers, setV3GroupMembers] = useState<number>(100)
const [v4GroupMembers, setV4GroupMembers] = useState<number>(100)
const [v3Times, setV3Times] = useState<number[]>([])
const [v4Times, setV4Times] = useState<number[]>([])

async function run(callback: () => any): Promise<[any, number]> {
const t0 = performance.now()
Expand All @@ -25,78 +28,155 @@ function App() {
return [result, t1 - t0]
}

const runFunctions = useCallback(async () => {
const runV3Functions = useCallback(async () => {
const timeValues = []

const [identity, time0] = await run(() => new Identity())

timeValues.push(time0)

setTimes(timeValues)
setV3Times(timeValues)

let members = Array.from(Array(groupMembers - 1).keys())
let members = Array.from(Array(v3GroupMembers - 1).keys())
members = [...members, identity.commitment]

const [group, time1] = await run(() => new Group(1, treeDepth, members))
const [group, time1] = await run(() => new Group(1, v3treeDepth, members))

timeValues.push(time1)

setTimes(timeValues.slice())
setV3Times(timeValues.slice())

const [proof, time2] = await run(async () => generateProof(identity, group, 1, 1))

timeValues.push(time2)

setTimes(timeValues.slice())
setV3Times(timeValues.slice())

const [, time3] = await run(async () => verifyProof(proof, treeDepth))
const [, time3] = await run(async () => verifyProof(proof, v3treeDepth))

timeValues.push(time3)

setTimes(timeValues.slice())
setV3Times(timeValues.slice())

const [, time4] = await run(() => {
group.addMember(1)
})

timeValues.push(time4)

setTimes(timeValues.slice())
setV3Times(timeValues.slice())

const [, time5] = await run(() => {
group.updateMember(0, 1)
})

timeValues.push(time5)

setTimes(timeValues.slice())
}, [treeDepth, groupMembers])
setV3Times(timeValues.slice())
}, [v3treeDepth, v3GroupMembers])

const runV4Functions = useCallback(async () => {
const timeValues = []

const [identity, time0] = await run(() => new V4.Identity())

timeValues.push(time0)

setV4Times(timeValues)

let members = Array.from(Array(v3GroupMembers - 1).keys()).map((m) => BigInt(m) + 1n)
members = [...members, identity.commitment]

const [group, time1] = await run(() => new V4.Group(members))

timeValues.push(time1)

setV4Times(timeValues.slice())

const [proof, time2] = await run(async () => V4.generateProof(identity, group, 1, 1))

timeValues.push(time2)

setV4Times(timeValues.slice())

const [, time3] = await run(async () => V4.verifyProof(proof))

timeValues.push(time3)

setV4Times(timeValues.slice())

const [, time4] = await run(() => {
group.addMember(1)
})

timeValues.push(time4)

setV4Times(timeValues.slice())

const [, time5] = await run(() => {
group.updateMember(0, 2n)
})

timeValues.push(time5)

setV4Times(timeValues.slice())
}, [v4GroupMembers])

return (
<Flex flexDir="column" flex="1">
<Navbar />
<Flex flex="1" align="center" justify="center">
<Flex flexDir="column" gap={4} width="400px">
<TreeDepth value={treeDepth} onChange={setTreeDepth} />
<GroupMembers value={groupMembers} onChange={setGroupMembers} max={2 ** treeDepth} />

<Button onClick={() => runFunctions()} size="sm" my="3">
Run functions
</Button>

<List spacing={3}>
{functions.map((f, i) => (
<ListItem key={f}>
<Flex justify="space-between">
<Box>
{times[i] && <ListIcon as={MdCheckCircle} color="green.500" />}
<b>{f}</b>
</Box>
<Text>{times[i] ? times[i] : 0} ms</Text>
</Flex>
</ListItem>
))}
</List>
<Flex gap={10}>
<Flex flexDir="column" gap={4} width="300px">
<Heading as="h3" size="lg">
Semaphore v3
</Heading>
<TreeDepth value={v3treeDepth} onChange={setV3TreeDepth} />
<GroupMembers value={v3GroupMembers} onChange={setV3GroupMembers} max={2 ** v3treeDepth} />

<Button onClick={() => runV3Functions()} size="sm" my="3">
Run functions
</Button>

<List spacing={3}>
{functions.map((f, i) => (
<ListItem key={f}>
<Flex justify="space-between">
<Box>
{v3Times[i] && <ListIcon as={MdCheckCircle} color="green.500" />}
<b>{f}</b>
</Box>
<Text>{v3Times[i] ? v3Times[i] : 0} ms</Text>
</Flex>
</ListItem>
))}
</List>
</Flex>
<Flex flexDir="column" gap={4} width="300px">
<Heading as="h3" size="lg" mb="12">
Semaphore v4
</Heading>

<GroupMembers value={v4GroupMembers} onChange={setV4GroupMembers} max={2 ** 32} />

<Button onClick={() => runV4Functions()} size="sm" my="3">
Run functions
</Button>

<List spacing={3}>
{functions.map((f, i) => (
<ListItem key={f}>
<Flex justify="space-between">
<Box>
{v4Times[i] && <ListIcon as={MdCheckCircle} color="green.500" />}
<b>{f}</b>
</Box>
<Text>{v4Times[i] ? v4Times[i] : 0} ms</Text>
</Flex>
</ListItem>
))}
</List>
</Flex>
</Flex>
</Flex>
</Flex>
Expand Down
2 changes: 1 addition & 1 deletion apps/benchmarks/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function Navbar() {
<Link href="https://semaphore.pse.dev/" isExternal>
<Image src="semaphore-logo.svg" htmlWidth={150} />
</Link>
<Link href="https://github.com/semaphore-protocol/benchmarks" isExternal>
<Link href="https://github.com/semaphore-protocol/extensions/tree/main/apps/benchmarks" isExternal>
<IconButton
variant="unstyled"
aria-label="Github repository"
Expand Down
Loading

0 comments on commit 56718d6

Please sign in to comment.