Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ jobs:
- name: Install Nargo
uses: noir-lang/noirup@v0.1.4
with:
toolchain: v1.0.0-beta.11
toolchain: v1.0.0-beta.3
- name: Cache node modules
uses: actions/cache@v4
with:
Expand Down Expand Up @@ -425,7 +425,7 @@ jobs:
- name: Install Nargo
uses: noir-lang/noirup@v0.1.4
with:
toolchain: v1.0.0-beta.11
toolchain: v1.0.0-beta.3

- name: Install wasm-pack
uses: ./.github/actions/install-wasm-pack
Expand Down Expand Up @@ -497,7 +497,7 @@ jobs:
- name: Install Nargo
uses: noir-lang/noirup@v0.1.4
with:
toolchain: v1.0.0-beta.11
toolchain: v1.0.0-beta.3

- name: Check formatting
working-directory: ./circuits
Expand Down
2 changes: 1 addition & 1 deletion circuits/crates/libs/safe/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ license = "MIT"

[dependencies]
poseidon = { tag = "v0.1.1", git = "https://github.com/noir-lang/poseidon" }
sha256 = { tag = "v0.2.0", git = "https://github.com/noir-lang/sha256" }
sha256 = { tag = "v0.1.0", git = "https://github.com/noir-lang/sha256" }
1 change: 0 additions & 1 deletion examples/CRISP/client/libs/wasm/pkg/crisp_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
encodeVote,
encryptVote,
generateMerkleProof,
verifyProof,
hashLeaf,
} from '@crisp-e3/sdk'

Expand Down
5 changes: 2 additions & 3 deletions examples/CRISP/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"deploy": "gh-pages -d dist"
},
"dependencies": {
"@crisp-e3/sdk": "0.2.0-test",
"@crisp-e3/sdk": "0.2.3-test",
"@emotion/babel-plugin": "^11.11.0",
"@emotion/react": "^11.11.4",
"@phosphor-icons/react": "^2.1.4",
Expand Down Expand Up @@ -57,8 +57,7 @@
"prettier-plugin-tailwindcss": "^0.5.13",
"tailwindcss": "^3.4.2",
"typescript": "^5.8.3",
"vite": "^5.2.0",
"vite-plugin-wasm": "^3.3.0"
"vite": "^5.2.0"
},
"packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808"
}
13 changes: 1 addition & 12 deletions examples/CRISP/client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import viteTsconfigPaths from 'vite-tsconfig-paths'
import svgr from '@svgr/rollup'
import wasm from 'vite-plugin-wasm'
import topLevelAwait from 'vite-plugin-top-level-await'
import path from 'path'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
Expand All @@ -23,15 +22,7 @@ export default defineConfig({
},
optimizeDeps: {
esbuildOptions: { target: 'esnext' },
exclude: [
'@rollup/browser',
'@crisp-e3/zk-inputs',
'@crisp-e3/zk-inputs/init',
'@noir-lang/noirc_abi',
'@noir-lang/acvm_js',
'@noir-lang/noir_js',
'@aztec/bb.js',
],
exclude: ['@rollup/browser', '@noir-lang/noirc_abi', '@noir-lang/acvm_js', '@noir-lang/noir_js', '@aztec/bb.js'],
},
resolve: {
alias: {
Expand All @@ -41,11 +32,9 @@ export default defineConfig({
},
worker: {
format: 'es',
plugins: () => [wasm(), topLevelAwait()],
},
plugins: [
// here is the main update
wasm(),
topLevelAwait(),
react({
jsxImportSource: '@emotion/react',
Expand Down
173 changes: 71 additions & 102 deletions examples/CRISP/packages/crisp-contracts/contracts/CRISPVerifier.sol

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/CRISP/packages/crisp-contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@crisp-e3/contracts",
"version": "0.2.0-test",
"version": "0.2.3-test",
"type": "module",
"files": [
"contracts",
Expand Down
11 changes: 6 additions & 5 deletions examples/CRISP/packages/crisp-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@crisp-e3/sdk",
"version": "0.2.0-test",
"version": "0.2.3-test",
"type": "module",
"author": {
"name": "gnosisguild",
Expand All @@ -9,15 +9,16 @@
"files": [
"dist"
],
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
}
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"homepage": "https://github.com/gnosisguild/enclave",
"scripts": {
"build:wasm": "pnpm -C ../crisp-zk-inputs build",
Expand All @@ -42,9 +43,9 @@
"vitest": "^1.6.1"
},
"dependencies": {
"@aztec/bb.js": "0.87.0",
"@aztec/bb.js": "0.82.2",
"@crisp-e3/zk-inputs": "workspace:*",
"@noir-lang/noir_js": "1.0.0-beta.9",
"@noir-lang/noir_js": "1.0.0-beta.3",
"@zk-kit/lean-imt": "^2.2.4",
"poseidon-lite": "^0.3.0",
"viem": "2.30.6"
Expand Down
6 changes: 0 additions & 6 deletions examples/CRISP/packages/crisp-sdk/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ export const HALF_LARGEST_MINIMUM_DEGREE = 28
*/
export const MAXIMUM_VOTE_VALUE = BigInt(Math.pow(2, HALF_LARGEST_MINIMUM_DEGREE) - 1)

/**
* Default BFV parameters for the CRISP ZK inputs generator.
* These are the parameters used for the default testing purposes only.
*/
export const DEFAULT_BFV_PARAMS = ZKInputsGenerator.withDefaults().getBFVParams() as BFVParams

/**
* Mock message for masking signature
*/
Expand Down
1 change: 0 additions & 1 deletion examples/CRISP/packages/crisp-sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,6 @@ export interface EncryptVoteAndGenerateCRISPInputsParams {
message: string
merkleData: IMerkleProof
balance: bigint
bfvParams?: BFVParams
slotAddress: string
isFirstVote: boolean
}
37 changes: 17 additions & 20 deletions examples/CRISP/packages/crisp-sdk/src/vote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
// or FITNESS FOR A PARTICULAR PURPOSE.

import { ZKInputsGenerator } from '@crisp-e3/zk-inputs'
import initializeWasm from '@crisp-e3/zk-inputs/init'
import { BFVParams, type CRISPCircuitInputs, type EncryptVoteAndGenerateCRISPInputsParams, type IVote, VotingMode } from './types'
import { toBinary } from './utils'
import { MAXIMUM_VOTE_VALUE, DEFAULT_BFV_PARAMS, HALF_LARGEST_MINIMUM_DEGREE, MESSAGE } from './constants'
import { MAXIMUM_VOTE_VALUE, HALF_LARGEST_MINIMUM_DEGREE, MESSAGE } from './constants'
import { extractSignature } from './signature'
import { Noir, type CompiledCircuit } from '@noir-lang/noir_js'
import { UltraHonkBackend, type ProofData } from '@aztec/bb.js'
Expand Down Expand Up @@ -62,13 +61,16 @@ export const calculateValidIndicesForPlaintext = (totalVotingPower: bigint, degr
* @param bfvParams The BFV parameters to use for encoding
* @returns The encoded vote as a string
*/
export const encodeVote = (vote: IVote, votingMode: VotingMode, votingPower: bigint, bfvParams?: BFVParams): string[] => {
export const encodeVote = (vote: IVote, votingMode: VotingMode, votingPower: bigint): string[] => {
const zkInputsGenerator = ZKInputsGenerator.withDefaults()
const bfvParams = zkInputsGenerator.getBFVParams() as BFVParams

validateVote(votingMode, vote, votingPower)

switch (votingMode) {
case VotingMode.GOVERNANCE:
const voteArray = []
const length = bfvParams?.degree || DEFAULT_BFV_PARAMS.degree
const length = bfvParams.degree
const halfLength = length / 2
const yesBinary = toBinary(vote.yes).split('')
const noBinary = toBinary(vote.no).split('')
Expand Down Expand Up @@ -154,18 +156,18 @@ export const validateVote = (votingMode: VotingMode, vote: IVote, votingPower: b
}

export const encryptVote = async (encodedVote: string[], publicKey: Uint8Array): Promise<Uint8Array> => {
await initializeWasm()
const zkInputsGenerator: ZKInputsGenerator = new ZKInputsGenerator(
DEFAULT_BFV_PARAMS.degree,
DEFAULT_BFV_PARAMS.plaintextModulus,
DEFAULT_BFV_PARAMS.moduli,
)
const zkInputsGenerator = ZKInputsGenerator.withDefaults()

const vote = BigInt64Array.from(encodedVote.map(BigInt))

return zkInputsGenerator.encryptVote(publicKey, vote)
}

export const generatePublicKey = async (): Promise<Uint8Array> => {
const zkInputsGenerator = ZKInputsGenerator.withDefaults()
return zkInputsGenerator.generatePublicKey()
}

/**
* This is a wrapper around enclave-e3/sdk encryption functions as CRISP circuit will require some more
* input values which generic Greco do not need.
Expand All @@ -185,22 +187,21 @@ export const encryptVoteAndGenerateCRISPInputs = async ({
encodedVote,
publicKey,
previousCiphertext,
bfvParams = DEFAULT_BFV_PARAMS,
merkleData,
message,
signature,
balance,
slotAddress,
isFirstVote,
}: EncryptVoteAndGenerateCRISPInputsParams): Promise<CRISPCircuitInputs> => {
await initializeWasm()
const zkInputsGenerator: ZKInputsGenerator = ZKInputsGenerator.withDefaults()

const bfvParams = zkInputsGenerator.getBFVParams() as BFVParams

if (encodedVote.length !== bfvParams.degree) {
throw new RangeError(`encodedVote length ${encodedVote.length} does not match BFV degree ${bfvParams.degree}`)
}

const zkInputsGenerator: ZKInputsGenerator = new ZKInputsGenerator(bfvParams.degree, bfvParams.plaintextModulus, bfvParams.moduli)

const vote = BigInt64Array.from(encodedVote.map(BigInt))

const crispInputs = (await zkInputsGenerator.generateInputs(previousCiphertext, publicKey, vote)) as CRISPCircuitInputs
Expand Down Expand Up @@ -228,7 +229,6 @@ export const encryptVoteAndGenerateCRISPInputs = async ({
* @param voter The voter's address
* @param publicKey The voter's public key
* @param previousCiphertext The previous ciphertext
* @param bfvParams The BFV parameters
* @param merkleRoot The merkle root of the census tree
* @param slotAddress The voter's slot address
* @param isFirstVote Whether this is the first vote for this slot
Expand All @@ -237,21 +237,18 @@ export const encryptVoteAndGenerateCRISPInputs = async ({
export const generateMaskVote = async (
publicKey: Uint8Array,
previousCiphertext: Uint8Array,
bfvParams = DEFAULT_BFV_PARAMS,
merkleRoot: bigint,
slotAddress: string,
isFirstVote: boolean,
): Promise<CRISPCircuitInputs> => {
await initializeWasm()
const zkInputsGenerator = ZKInputsGenerator.withDefaults()

const plaintextVote: IVote = {
yes: 0n,
no: 0n,
}

const encodedVote = encodeVote(plaintextVote, VotingMode.GOVERNANCE, 0n, bfvParams)

const zkInputsGenerator: ZKInputsGenerator = new ZKInputsGenerator(bfvParams.degree, bfvParams.plaintextModulus, bfvParams.moduli)
const encodedVote = encodeVote(plaintextVote, VotingMode.GOVERNANCE, 0n)

const vote = BigInt64Array.from(encodedVote.map(BigInt))

Expand Down
51 changes: 10 additions & 41 deletions examples/CRISP/packages/crisp-sdk/tests/vote.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
verifyProof,
} from '../src/vote'
import { BFVParams, VotingMode } from '../src/types'
import { DEFAULT_BFV_PARAMS, generateMerkleProof, hashLeaf, MAXIMUM_VOTE_VALUE } from '../src'
import { generateMerkleProof, hashLeaf, MAXIMUM_VOTE_VALUE } from '../src'

import { LEAVES, merkleProof, MESSAGE, SIGNATURE, testAddress, VOTE, votingPowerLeaf } from './constants'
import { privateKeyToAccount } from 'viem/accounts'
Expand All @@ -29,6 +29,8 @@ describe('Vote', () => {
const votingPower = 10n

let zkInputsGenerator = ZKInputsGenerator.withDefaults()
const DEFAULT_BFV_PARAMS = zkInputsGenerator.getBFVParams() as BFVParams

let publicKey = zkInputsGenerator.generatePublicKey()
const previousCiphertext = zkInputsGenerator.encryptVote(publicKey, new BigInt64Array([0n]))

Expand All @@ -37,20 +39,6 @@ describe('Vote', () => {
const encoded = encodeVote(VOTE, VotingMode.GOVERNANCE, votingPower)
expect(encoded.length).toBe(DEFAULT_BFV_PARAMS.degree)
})
it('should work with small moduli', () => {
const params: BFVParams = {
degree: 10,
// Irrelevant for this test.
plaintextModulus: 0n,
moduli: new BigInt64Array([0n]),
}
const encoded = encodeVote(VOTE, VotingMode.GOVERNANCE, votingPower, params)
expect(encoded.length).toBe(params.degree)

// 01010 = 10
// 00000 = 0
expect(encoded).toEqual(['0', '1', '0', '1', '0', '0', '0', '0', '0', '0'])
})
})

describe('decode tally', () => {
Expand Down Expand Up @@ -223,14 +211,7 @@ describe('Vote', () => {

describe('generateMaskVote', () => {
it('should generate a mask vote and the right circuit inputs', async () => {
const crispInputs = await generateMaskVote(
publicKey,
previousCiphertext,
DEFAULT_BFV_PARAMS,
merkleProof.proof.root,
testAddress,
false,
)
const crispInputs = await generateMaskVote(publicKey, previousCiphertext, merkleProof.proof.root, testAddress, false)

expect(crispInputs.prev_ct0is).toBeInstanceOf(Array)
expect(crispInputs.prev_ct1is).toBeInstanceOf(Array)
Expand Down Expand Up @@ -290,15 +271,11 @@ describe('Vote', () => {

it('should generate a proof for a masking user and verify it', { timeout: 180000 }, async () => {
const encodedVote = encodeVote(VOTE, VotingMode.GOVERNANCE, votingPower)
const zkInputsGenerator: ZKInputsGenerator = new ZKInputsGenerator(
DEFAULT_BFV_PARAMS.degree,
DEFAULT_BFV_PARAMS.plaintextModulus,
DEFAULT_BFV_PARAMS.moduli,
)
const zkInputsGenerator = ZKInputsGenerator.withDefaults()
const vote = BigInt64Array.from(encodedVote.map(BigInt))
const encryptedVote = zkInputsGenerator.encryptVote(publicKey, vote)

let maskVote = await generateMaskVote(publicKey, encryptedVote, DEFAULT_BFV_PARAMS, merkleProof.proof.root, testAddress, false)
let maskVote = await generateMaskVote(publicKey, encryptedVote, merkleProof.proof.root, testAddress, false)

const proof = await generateProof(maskVote)
const isValid = await verifyProof(proof)
Expand All @@ -308,15 +285,11 @@ describe('Vote', () => {

it('should return ciphertext if masking a vote and it is the first operation on the slot', { timeout: 180000 }, async () => {
const encodedVote = encodeVote(VOTE, VotingMode.GOVERNANCE, votingPower)
const zkInputsGenerator: ZKInputsGenerator = new ZKInputsGenerator(
DEFAULT_BFV_PARAMS.degree,
DEFAULT_BFV_PARAMS.plaintextModulus,
DEFAULT_BFV_PARAMS.moduli,
)
const zkInputsGenerator = ZKInputsGenerator.withDefaults()
const vote = BigInt64Array.from(encodedVote.map(BigInt))
const encryptedVote = zkInputsGenerator.encryptVote(publicKey, vote)

let maskVote = await generateMaskVote(publicKey, encryptedVote, DEFAULT_BFV_PARAMS, merkleProof.proof.root, testAddress, true)
let maskVote = await generateMaskVote(publicKey, encryptedVote, merkleProof.proof.root, testAddress, true)

const { returnValue } = await generateProofWithReturnValue(maskVote)

Expand All @@ -326,15 +299,11 @@ describe('Vote', () => {

it('should return the sum if masking a vote and it is not the first operation on the slot', { timeout: 180000 }, async () => {
const encodedVote = encodeVote(VOTE, VotingMode.GOVERNANCE, votingPower)
const zkInputsGenerator: ZKInputsGenerator = new ZKInputsGenerator(
DEFAULT_BFV_PARAMS.degree,
DEFAULT_BFV_PARAMS.plaintextModulus,
DEFAULT_BFV_PARAMS.moduli,
)
const zkInputsGenerator = ZKInputsGenerator.withDefaults()
const vote = BigInt64Array.from(encodedVote.map(BigInt))
const encryptedVote = zkInputsGenerator.encryptVote(publicKey, vote)

let maskVote = await generateMaskVote(publicKey, encryptedVote, DEFAULT_BFV_PARAMS, merkleProof.proof.root, testAddress, false)
let maskVote = await generateMaskVote(publicKey, encryptedVote, merkleProof.proof.root, testAddress, false)

const { returnValue } = await generateProofWithReturnValue(maskVote)

Expand Down
8 changes: 0 additions & 8 deletions examples/CRISP/packages/crisp-zk-inputs/init.d.ts

This file was deleted.

Loading
Loading