@crisp-e3/sdk 0.0.1-test

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ import { BFVParams } from './types';
2
+ export declare const CRISP_SERVER_TOKEN_TREE_ENDPOINT = "state/token-holders";
3
+ export declare const CRISP_SERVER_STATE_LITE_ENDPOINT = "state/lite";
4
+ /**
5
+ * This is the maximum value for a vote (Yes or No). This is 2^28
6
+ * The minimum degree that BFV should use is 56 (to accommodate both Yes and No votes)
7
+ * If you change this value, make sure to update the circuit too.
8
+ */
9
+ export declare const MAXIMUM_VOTE_VALUE = 268435456n;
10
+ /**
11
+ * Default BFV parameters for the CRISP ZK inputs generator.
12
+ * These are the parameters used for the default testing purposes only.
13
+ */
14
+ export declare const DEFAULT_BFV_PARAMS: BFVParams;
15
+ /**
16
+ * Mock message for masking signature
17
+ */
18
+ export declare const MESSAGE = "Vote for round 0";
@@ -0,0 +1,23 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ import { ZKInputsGenerator } from '@crisp-e3/zk-inputs';
7
+ export const CRISP_SERVER_TOKEN_TREE_ENDPOINT = 'state/token-holders';
8
+ export const CRISP_SERVER_STATE_LITE_ENDPOINT = 'state/lite';
9
+ /**
10
+ * This is the maximum value for a vote (Yes or No). This is 2^28
11
+ * The minimum degree that BFV should use is 56 (to accommodate both Yes and No votes)
12
+ * If you change this value, make sure to update the circuit too.
13
+ */
14
+ export const MAXIMUM_VOTE_VALUE = 268435456n;
15
+ /**
16
+ * Default BFV parameters for the CRISP ZK inputs generator.
17
+ * These are the parameters used for the default testing purposes only.
18
+ */
19
+ export const DEFAULT_BFV_PARAMS = ZKInputsGenerator.withDefaults().getBFVParams();
20
+ /**
21
+ * Mock message for masking signature
22
+ */
23
+ export const MESSAGE = 'Vote for round 0';
@@ -0,0 +1,8 @@
1
+ export * from './token';
2
+ export * from './state';
3
+ export * from './constants';
4
+ export * from './utils';
5
+ export * from './vote';
6
+ export * from './signature';
7
+ export { VotingMode } from './types';
8
+ export type { IRoundDetails, IRoundDetailsResponse, ITokenDetails, IMerkleProof, IVote, CRISPCircuitInputs, NoirSignatureInputs, } from './types';
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ export * from './token';
7
+ export * from './state';
8
+ export * from './constants';
9
+ export * from './utils';
10
+ export * from './vote';
11
+ export * from './signature';
12
+ export { VotingMode } from './types';
@@ -0,0 +1,8 @@
1
+ import type { NoirSignatureInputs } from './types';
2
+ /**
3
+ * Given a message and its signed version, extract the signature components
4
+ * @param message The original message
5
+ * @param signedMessage The signed message (signature)
6
+ * @returns The extracted signature components
7
+ */
8
+ export declare const extractSignature: (message: string, signedMessage: `0x${string}`) => Promise<NoirSignatureInputs>;
@@ -0,0 +1,36 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ import { hashMessage, hexToBytes, recoverPublicKey } from 'viem';
7
+ /**
8
+ * Given a message and its signed version, extract the signature components
9
+ * @param message The original message
10
+ * @param signedMessage The signed message (signature)
11
+ * @returns The extracted signature components
12
+ */
13
+ export const extractSignature = async (message, signedMessage) => {
14
+ const messageHash = hashMessage(message);
15
+ const messageBytes = hexToBytes(messageHash);
16
+ const publicKey = await recoverPublicKey({
17
+ hash: messageHash,
18
+ signature: signedMessage,
19
+ });
20
+ const publicKeyBytes = hexToBytes(publicKey);
21
+ const publicKeyX = publicKeyBytes.slice(1, 33);
22
+ const publicKeyY = publicKeyBytes.slice(33, 65);
23
+ // Extract r and s from signature (remove v)
24
+ const sigBytes = hexToBytes(signedMessage);
25
+ const r = sigBytes.slice(0, 32); // First 32 bytes
26
+ const s = sigBytes.slice(32, 64); // Next 32 bytes
27
+ const signatureBytes = new Uint8Array(64);
28
+ signatureBytes.set(r, 0);
29
+ signatureBytes.set(s, 32);
30
+ return {
31
+ hashed_message: messageBytes,
32
+ pub_key_x: publicKeyX,
33
+ pub_key_y: publicKeyY,
34
+ signature: signatureBytes,
35
+ };
36
+ };
@@ -0,0 +1,12 @@
1
+ import type { IRoundDetails, ITokenDetails } from './types';
2
+ /**
3
+ * Get the details of a specific round
4
+ */
5
+ export declare const getRoundDetails: (serverUrl: string, e3Id: number) => Promise<IRoundDetails>;
6
+ /**
7
+ * Get the token address, balance threshold and snapshot block for a specific round
8
+ * @param serverUrl - The base URL of the CRISP server
9
+ * @param e3Id - The e3Id of the round
10
+ * @returns The token address, balance threshold and snapshot block
11
+ */
12
+ export declare const getRoundTokenDetails: (serverUrl: string, e3Id: number) => Promise<ITokenDetails>;
@@ -0,0 +1,48 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ import { CRISP_SERVER_STATE_LITE_ENDPOINT } from './constants';
7
+ /**
8
+ * Get the details of a specific round
9
+ */
10
+ export const getRoundDetails = async (serverUrl, e3Id) => {
11
+ const response = await fetch(`${serverUrl}/${CRISP_SERVER_STATE_LITE_ENDPOINT}`, {
12
+ method: 'POST',
13
+ headers: {
14
+ 'Content-Type': 'application/json',
15
+ },
16
+ body: JSON.stringify({ round_id: e3Id }),
17
+ });
18
+ const data = (await response.json());
19
+ return {
20
+ e3Id: BigInt(data.id),
21
+ tokenAddress: data.token_address,
22
+ balanceThreshold: BigInt(data.balance_threshold),
23
+ chainId: BigInt(data.chain_id),
24
+ enclaveAddress: data.enclave_address,
25
+ status: data.status,
26
+ voteCount: BigInt(data.vote_count),
27
+ startTime: BigInt(data.start_time),
28
+ duration: BigInt(data.duration),
29
+ expiration: BigInt(data.expiration),
30
+ startBlock: BigInt(data.start_block),
31
+ committeePublicKey: data.committee_public_key,
32
+ emojis: data.emojis,
33
+ };
34
+ };
35
+ /**
36
+ * Get the token address, balance threshold and snapshot block for a specific round
37
+ * @param serverUrl - The base URL of the CRISP server
38
+ * @param e3Id - The e3Id of the round
39
+ * @returns The token address, balance threshold and snapshot block
40
+ */
41
+ export const getRoundTokenDetails = async (serverUrl, e3Id) => {
42
+ const roundDetails = await getRoundDetails(serverUrl, e3Id);
43
+ return {
44
+ tokenAddress: roundDetails.tokenAddress,
45
+ threshold: roundDetails.balanceThreshold,
46
+ snapshotBlock: roundDetails.startBlock,
47
+ };
48
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Get the merkle tree data from the CRISP server
3
+ * @param serverUrl - The base URL of the CRISP server
4
+ * @param e3Id - The e3Id of the round
5
+ */
6
+ export declare const getTreeData: (serverUrl: string, e3Id: number) => Promise<bigint[]>;
7
+ /**
8
+ * Get the token balance at a specific block for a given address
9
+ * @param voterAddress - The address of the voter
10
+ * @param tokenAddress - The address of the token contract
11
+ * @param snapshotBlock - The block number at which to get the balance
12
+ * @param chainId - The chain ID of the network
13
+ * @returns The token balance as a bigint
14
+ */
15
+ export declare const getBalanceAt: (voterAddress: string, tokenAddress: string, snapshotBlock: number, chainId: number) => Promise<bigint>;
16
+ /**
17
+ * Get the total supply of a ERC20Votes Token at a specific block
18
+ * @param tokenAddress The token address to query
19
+ * @param snapshotBlock The block number at which to get the total supply
20
+ * @param chainId The chain ID of the network
21
+ * @returns The total supply as a bigint
22
+ */
23
+ export declare const getTotalSupplyAt: (tokenAddress: string, snapshotBlock: number, chainId: number) => Promise<bigint>;
@@ -0,0 +1,95 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ import { CRISP_SERVER_TOKEN_TREE_ENDPOINT } from './constants';
7
+ import ERC20Votes from './ERC20Votes.json';
8
+ import { createPublicClient, http } from 'viem';
9
+ import { localhost, sepolia } from 'viem/chains';
10
+ /**
11
+ * Get the merkle tree data from the CRISP server
12
+ * @param serverUrl - The base URL of the CRISP server
13
+ * @param e3Id - The e3Id of the round
14
+ */
15
+ export const getTreeData = async (serverUrl, e3Id) => {
16
+ const response = await fetch(`${serverUrl}/${CRISP_SERVER_TOKEN_TREE_ENDPOINT}`, {
17
+ method: 'POST',
18
+ headers: {
19
+ 'Content-Type': 'application/json',
20
+ },
21
+ body: JSON.stringify({ round_id: e3Id }),
22
+ });
23
+ const hashes = (await response.json());
24
+ // Convert hex strings to BigInts
25
+ return hashes.map((hash) => {
26
+ // Ensure the hash is treated as a hex string
27
+ if (!hash.startsWith('0x')) {
28
+ return BigInt('0x' + hash);
29
+ }
30
+ return BigInt(hash);
31
+ });
32
+ };
33
+ /**
34
+ * Get the token balance at a specific block for a given address
35
+ * @param voterAddress - The address of the voter
36
+ * @param tokenAddress - The address of the token contract
37
+ * @param snapshotBlock - The block number at which to get the balance
38
+ * @param chainId - The chain ID of the network
39
+ * @returns The token balance as a bigint
40
+ */
41
+ export const getBalanceAt = async (voterAddress, tokenAddress, snapshotBlock, chainId) => {
42
+ let chain;
43
+ switch (chainId) {
44
+ case 11155111:
45
+ chain = sepolia;
46
+ break;
47
+ case 31337:
48
+ chain = localhost;
49
+ break;
50
+ default:
51
+ throw new Error('Unsupported chainId');
52
+ }
53
+ const publicClient = createPublicClient({
54
+ transport: http(),
55
+ chain,
56
+ });
57
+ const balance = (await publicClient.readContract({
58
+ address: tokenAddress,
59
+ abi: ERC20Votes.abi,
60
+ functionName: 'getPastVotes',
61
+ args: [voterAddress, BigInt(snapshotBlock)],
62
+ }));
63
+ return balance;
64
+ };
65
+ /**
66
+ * Get the total supply of a ERC20Votes Token at a specific block
67
+ * @param tokenAddress The token address to query
68
+ * @param snapshotBlock The block number at which to get the total supply
69
+ * @param chainId The chain ID of the network
70
+ * @returns The total supply as a bigint
71
+ */
72
+ export const getTotalSupplyAt = async (tokenAddress, snapshotBlock, chainId) => {
73
+ let chain;
74
+ switch (chainId) {
75
+ case 11155111:
76
+ chain = sepolia;
77
+ break;
78
+ case 31337:
79
+ chain = localhost;
80
+ break;
81
+ default:
82
+ throw new Error('Unsupported chainId');
83
+ }
84
+ const publicClient = createPublicClient({
85
+ transport: http(),
86
+ chain,
87
+ });
88
+ const totalSupply = (await publicClient.readContract({
89
+ address: tokenAddress,
90
+ abi: ERC20Votes.abi,
91
+ functionName: 'getPastTotalSupply',
92
+ args: [BigInt(snapshotBlock)],
93
+ }));
94
+ return totalSupply;
95
+ };
@@ -0,0 +1,193 @@
1
+ import type { LeanIMTMerkleProof } from '@zk-kit/lean-imt';
2
+ /**
3
+ * Interface representing the details of a specific round returned by the CRISP server
4
+ */
5
+ export interface IRoundDetailsResponse {
6
+ id: string;
7
+ chain_id: string;
8
+ enclave_address: string;
9
+ status: string;
10
+ vote_count: string;
11
+ start_time: string;
12
+ duration: string;
13
+ expiration: string;
14
+ start_block: string;
15
+ committee_public_key: string[];
16
+ emojis: [string, string];
17
+ token_address: string;
18
+ balance_threshold: string;
19
+ }
20
+ /**
21
+ * Interface representing the details of a specific round in a more convenient format
22
+ */
23
+ export interface IRoundDetails {
24
+ e3Id: bigint;
25
+ chainId: bigint;
26
+ enclaveAddress: string;
27
+ status: string;
28
+ voteCount: bigint;
29
+ startTime: bigint;
30
+ duration: bigint;
31
+ expiration: bigint;
32
+ startBlock: bigint;
33
+ committeePublicKey: string[];
34
+ emojis: [string, string];
35
+ tokenAddress: string;
36
+ balanceThreshold: bigint;
37
+ }
38
+ /**
39
+ * Interface representing the token details required for participation in a round
40
+ */
41
+ export interface ITokenDetails {
42
+ tokenAddress: string;
43
+ threshold: bigint;
44
+ snapshotBlock: bigint;
45
+ }
46
+ /**
47
+ * Interface representing a Merkle proof
48
+ */
49
+ export interface IMerkleProof {
50
+ leaf: bigint;
51
+ index: number;
52
+ proof: LeanIMTMerkleProof<bigint>;
53
+ length: number;
54
+ indices: number[];
55
+ }
56
+ /**
57
+ * Enum representing the voting modes
58
+ */
59
+ export declare enum VotingMode {
60
+ /**
61
+ * Governance voting requires to spend all credits on one option
62
+ they cannot be split
63
+ */
64
+ GOVERNANCE = "GOVERNANCE"
65
+ }
66
+ /**
67
+ * Interface representing a vote with power for 'yes' and 'no'
68
+ */
69
+ export interface IVote {
70
+ /**
71
+ * The voting power for 'yes' votes
72
+ */
73
+ yes: bigint;
74
+ /**
75
+ * The voting power for 'no' votes
76
+ */
77
+ no: bigint;
78
+ }
79
+ /**
80
+ * Interface representing a vector with coefficients
81
+ */
82
+ export interface Polynomial {
83
+ coefficients: string[];
84
+ }
85
+ /**
86
+ * Interface representing cryptographic parameters
87
+ */
88
+ export interface GrecoCryptographicParams {
89
+ q_mod_t: string;
90
+ qis: string[];
91
+ k0is: string[];
92
+ }
93
+ /**
94
+ * Interface representing Greco bounds
95
+ */
96
+ export interface GrecoBoundParams {
97
+ e_bound: string;
98
+ u_bound: string;
99
+ k1_low_bound: string;
100
+ k1_up_bound: string;
101
+ p1_bounds: string[];
102
+ p2_bounds: string[];
103
+ pk_bounds: string[];
104
+ r1_low_bounds: string[];
105
+ r1_up_bounds: string[];
106
+ r2_bounds: string[];
107
+ }
108
+ /**
109
+ * Interface representing Greco parameters
110
+ */
111
+ export interface GrecoParams {
112
+ crypto: GrecoCryptographicParams;
113
+ bounds: GrecoBoundParams;
114
+ }
115
+ /**
116
+ * The inputs required for the CRISP circuit
117
+ */
118
+ export interface CRISPCircuitInputs {
119
+ prev_ct0is: Polynomial[];
120
+ prev_ct1is: Polynomial[];
121
+ sum_ct0is: Polynomial[];
122
+ sum_ct1is: Polynomial[];
123
+ sum_r0is: Polynomial[];
124
+ sum_r1is: Polynomial[];
125
+ params: GrecoParams;
126
+ ct0is: Polynomial[];
127
+ ct1is: Polynomial[];
128
+ pk0is: Polynomial[];
129
+ pk1is: Polynomial[];
130
+ r1is: Polynomial[];
131
+ r2is: Polynomial[];
132
+ p1is: Polynomial[];
133
+ p2is: Polynomial[];
134
+ u: Polynomial;
135
+ e0: Polynomial;
136
+ e1: Polynomial;
137
+ k1: Polynomial;
138
+ public_key_x: string[];
139
+ public_key_y: string[];
140
+ signature: string[];
141
+ hashed_message: string[];
142
+ merkle_root: string;
143
+ merkle_proof_length: string;
144
+ merkle_proof_indices: string[];
145
+ merkle_proof_siblings: string[];
146
+ slot_address: string;
147
+ balance: string;
148
+ is_first_vote: boolean;
149
+ }
150
+ /**
151
+ * Interface representing the BFV parameters
152
+ */
153
+ export interface BFVParams {
154
+ degree: number;
155
+ plaintextModulus: bigint;
156
+ moduli: BigInt64Array;
157
+ }
158
+ /**
159
+ * Interface representing the inputs for Noir signature verification
160
+ */
161
+ export interface NoirSignatureInputs {
162
+ /**
163
+ * X coordinate of the public key
164
+ */
165
+ pub_key_x: Uint8Array;
166
+ /**
167
+ * Y coordinate of the public key
168
+ */
169
+ pub_key_y: Uint8Array;
170
+ /**
171
+ * The signature to verify
172
+ */
173
+ signature: Uint8Array;
174
+ /**
175
+ * The hashed message that was signed
176
+ */
177
+ hashed_message: Uint8Array;
178
+ }
179
+ /**
180
+ * Parameters for encryptVoteAndGenerateCRISPInputs function
181
+ */
182
+ export interface EncryptVoteAndGenerateCRISPInputsParams {
183
+ encodedVote: string[];
184
+ publicKey: Uint8Array;
185
+ previousCiphertext: Uint8Array;
186
+ signature: `0x${string}`;
187
+ message: string;
188
+ merkleData: IMerkleProof;
189
+ balance: bigint;
190
+ bfvParams?: BFVParams;
191
+ slotAddress: string;
192
+ isFirstVote: boolean;
193
+ }
@@ -0,0 +1,16 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ /**
7
+ * Enum representing the voting modes
8
+ */
9
+ export var VotingMode;
10
+ (function (VotingMode) {
11
+ /**
12
+ * Governance voting requires to spend all credits on one option
13
+ they cannot be split
14
+ */
15
+ VotingMode["GOVERNANCE"] = "GOVERNANCE";
16
+ })(VotingMode || (VotingMode = {}));
@@ -0,0 +1,30 @@
1
+ import { LeanIMT } from '@zk-kit/lean-imt';
2
+ import type { IMerkleProof } from './types';
3
+ /**
4
+ * Hash a leaf node for the Merkle tree
5
+ * @param address The voter's address
6
+ * @param balance The voter's balance
7
+ * @returns The hashed leaf as a bigint
8
+ */
9
+ export declare const hashLeaf: (address: string, balance: string) => bigint;
10
+ /**
11
+ * Generate a new LeanIMT with the leaves provided
12
+ * @param leaves The leaves of the Merkle tree
13
+ * @returns the generated Merkle tree
14
+ */
15
+ export declare const generateMerkleTree: (leaves: bigint[]) => LeanIMT;
16
+ /**
17
+ * Generate a Merkle proof for a given address to prove inclusion in the voters' list
18
+ * @param threshold The minimum balance required to be eligible
19
+ * @param balance The voter's balance
20
+ * @param address The voter's address
21
+ * @param leaves The leaves of the Merkle tree
22
+ * @param maxDepth The maximum depth of the Merkle tree
23
+ */
24
+ export declare const generateMerkleProof: (threshold: bigint, balance: bigint, address: string, leaves: bigint[], maxDepth: number) => IMerkleProof;
25
+ /**
26
+ * Convert a number to its binary representation
27
+ * @param number The number to convert to binary
28
+ * @returns The binary representation of the number as a string
29
+ */
30
+ export declare const toBinary: (number: bigint) => string;
@@ -0,0 +1,71 @@
1
+ // SPDX-License-Identifier: LGPL-3.0-only
2
+ //
3
+ // This file is provided WITHOUT ANY WARRANTY;
4
+ // without even the implied warranty of MERCHANTABILITY
5
+ // or FITNESS FOR A PARTICULAR PURPOSE.
6
+ import { poseidon2 } from 'poseidon-lite';
7
+ import { LeanIMT } from '@zk-kit/lean-imt';
8
+ /**
9
+ * Hash a leaf node for the Merkle tree
10
+ * @param address The voter's address
11
+ * @param balance The voter's balance
12
+ * @returns The hashed leaf as a bigint
13
+ */
14
+ export const hashLeaf = (address, balance) => {
15
+ return poseidon2([address, balance]);
16
+ };
17
+ /**
18
+ * Generate a new LeanIMT with the leaves provided
19
+ * @param leaves The leaves of the Merkle tree
20
+ * @returns the generated Merkle tree
21
+ */
22
+ export const generateMerkleTree = (leaves) => {
23
+ return new LeanIMT((a, b) => poseidon2([a, b]), leaves);
24
+ };
25
+ /**
26
+ * Generate a Merkle proof for a given address to prove inclusion in the voters' list
27
+ * @param threshold The minimum balance required to be eligible
28
+ * @param balance The voter's balance
29
+ * @param address The voter's address
30
+ * @param leaves The leaves of the Merkle tree
31
+ * @param maxDepth The maximum depth of the Merkle tree
32
+ */
33
+ export const generateMerkleProof = (threshold, balance, address, leaves, maxDepth) => {
34
+ if (balance < threshold) {
35
+ throw new Error('Balance is below the threshold');
36
+ }
37
+ const leaf = hashLeaf(address, balance.toString());
38
+ const index = leaves.findIndex((l) => l === leaf);
39
+ if (index === -1) {
40
+ throw new Error('Leaf not found in the tree');
41
+ }
42
+ const tree = generateMerkleTree(leaves);
43
+ const proof = tree.generateProof(index);
44
+ // Pad siblings with zeros
45
+ const paddedSiblings = [...proof.siblings, ...Array(maxDepth - proof.siblings.length).fill(0n)];
46
+ // Pad indices with zeros
47
+ const indices = proof.siblings.map((_, i) => Number((BigInt(proof.index) >> BigInt(i)) & 1n));
48
+ const paddedIndices = [...indices, ...Array(maxDepth - indices.length).fill(0)];
49
+ return {
50
+ leaf,
51
+ index,
52
+ proof: {
53
+ ...proof,
54
+ siblings: paddedSiblings,
55
+ },
56
+ // Original length before padding
57
+ length: proof.siblings.length,
58
+ indices: paddedIndices,
59
+ };
60
+ };
61
+ /**
62
+ * Convert a number to its binary representation
63
+ * @param number The number to convert to binary
64
+ * @returns The binary representation of the number as a string
65
+ */
66
+ export const toBinary = (number) => {
67
+ if (number < 0) {
68
+ throw new Error('Value cannot be negative');
69
+ }
70
+ return number.toString(2);
71
+ };
@@ -0,0 +1,71 @@
1
+ import { BFVParams, type CRISPCircuitInputs, type EncryptVoteAndGenerateCRISPInputsParams, type IVote, VotingMode } from './types';
2
+ import { type ProofData } from '@aztec/bb.js';
3
+ /**
4
+ * This utility function calculates the first valid index for vote options
5
+ * based on the total voting power and degree.
6
+ * @dev This is needed to calculate the decoded plaintext
7
+ * @dev Also, we will need to check in the circuit that anything within these indices is
8
+ * either 0 or 1.
9
+ * @param totalVotingPower The maximum vote amount (if a single voter had all of the power)
10
+ * @param degree The degree of the polynomial
11
+ */
12
+ export declare const calculateValidIndicesForPlaintext: (totalVotingPower: bigint, degree: number) => {
13
+ yesIndex: number;
14
+ noIndex: number;
15
+ };
16
+ /**
17
+ * Encode a vote based on the voting mode
18
+ * @param vote The vote to encode
19
+ * @param votingMode The voting mode to use for encoding
20
+ * @param votingPower The voting power of the voter
21
+ * @param bfvParams The BFV parameters to use for encoding
22
+ * @returns The encoded vote as a string
23
+ */
24
+ export declare const encodeVote: (vote: IVote, votingMode: VotingMode, votingPower: bigint, bfvParams?: BFVParams) => string[];
25
+ /**
26
+ * Given an encoded tally, decode it into its decimal representation
27
+ * @param tally The encoded tally to decode
28
+ * @param votingMode The voting mode
29
+ */
30
+ export declare const decodeTally: (tally: string[], votingMode: VotingMode) => IVote;
31
+ /**
32
+ * Validate whether a vote is valid for a given voting mode
33
+ * @param votingMode The voting mode to validate against
34
+ * @param vote The vote to validate
35
+ * @param votingPower The voting power of the voter
36
+ */
37
+ export declare const validateVote: (votingMode: VotingMode, vote: IVote, votingPower: bigint) => void;
38
+ /**
39
+ * This is a wrapper around enclave-e3/sdk encryption functions as CRISP circuit will require some more
40
+ * input values which generic Greco do not need.
41
+ * @param encodedVote The encoded vote as string array
42
+ * @param publicKey The public key to use for encryption
43
+ * @param previousCiphertext The previous ciphertext to use for addition operation
44
+ * @param bfvParams The BFV parameters to use for encryption
45
+ * @param merkleData The merkle proof data
46
+ * @param message The message that was signed
47
+ * @param signature The signature of the message
48
+ * @param balance The voter's balance
49
+ * @param slotAddress The voter's slot address
50
+ * @param isFirstVote Whether this is the first vote for this slot
51
+ * @returns The CRISP circuit inputs
52
+ */
53
+ export declare const encryptVoteAndGenerateCRISPInputs: ({ encodedVote, publicKey, previousCiphertext, bfvParams, merkleData, message, signature, balance, slotAddress, isFirstVote, }: EncryptVoteAndGenerateCRISPInputsParams) => Promise<CRISPCircuitInputs>;
54
+ /**
55
+ * A function to generate the data required to mask a vote
56
+ * @param voter The voter's address
57
+ * @param publicKey The voter's public key
58
+ * @param previousCiphertext The previous ciphertext
59
+ * @param bfvParams The BFV parameters
60
+ * @param merkleRoot The merkle root of the census tree
61
+ * @param slotAddress The voter's slot address
62
+ * @param isFirstVote Whether this is the first vote for this slot
63
+ * @returns The CRISP circuit inputs for a mask vote
64
+ */
65
+ export declare const generateMaskVote: (publicKey: Uint8Array, previousCiphertext: Uint8Array, bfvParams: BFVParams | undefined, merkleRoot: bigint, slotAddress: string, isFirstVote: boolean) => Promise<CRISPCircuitInputs>;
66
+ export declare const generateProof: (crispInputs: CRISPCircuitInputs) => Promise<ProofData>;
67
+ export declare const generateProofWithReturnValue: (crispInputs: CRISPCircuitInputs) => Promise<{
68
+ returnValue: unknown;
69
+ proof: ProofData;
70
+ }>;
71
+ export declare const verifyProof: (proof: ProofData) => Promise<boolean>;