@crisp-e3/sdk 0.17.0 → 0.18.0-insecure.0
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.
- package/README.md +38 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/circuits-BWegRaZy.d.ts +49 -0
- package/dist/index.d.ts +82 -10
- package/dist/index.js +70 -53
- package/dist/index.js.map +1 -1
- package/dist/presets/insecure-512.d.ts +14 -0
- package/dist/presets/insecure-512.js +26 -0
- package/dist/workers/generateCircuitInputs.worker.js +19 -27
- package/dist/workers/generateCircuitInputs.worker.js.map +1 -1
- package/package.json +21 -5
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { CompiledCircuit } from '@noir-lang/noir_js';
|
|
2
|
+
|
|
3
|
+
/** BFV parameter sets the circuits can be compiled against. */
|
|
4
|
+
type CircuitPreset = 'insecure-512' | 'secure-8192';
|
|
5
|
+
/**
|
|
6
|
+
* The circuits whose ABI is shaped by the BFV degree, and which therefore exist once per preset.
|
|
7
|
+
*
|
|
8
|
+
* The aggregation circuits — `crisp_fold`, `crisp_onchain_fold` and `user_data_encryption` — are
|
|
9
|
+
* deliberately absent. Their parameters are proof and verification-key shaped (410/115 fields), not
|
|
10
|
+
* polynomial shaped, so one compiled artifact serves both presets; the fold circuits assert
|
|
11
|
+
* `chain_key_hash` against the insecure *or* the secure constant for exactly that reason. They ship
|
|
12
|
+
* in the main entry point, which is why `verifyProof` works without a preset loaded.
|
|
13
|
+
*/
|
|
14
|
+
type CircuitBundle = {
|
|
15
|
+
readonly preset: CircuitPreset;
|
|
16
|
+
readonly crisp: CompiledCircuit;
|
|
17
|
+
readonly crispOnchain: CompiledCircuit;
|
|
18
|
+
readonly userDataEncryptionCt0: CompiledCircuit;
|
|
19
|
+
readonly userDataEncryptionCt1: CompiledCircuit;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Install the preset-bound circuits used by `generateProof`.
|
|
23
|
+
*
|
|
24
|
+
* The bundle is not bundled into the main entry point, because the secure-8192 artifacts are more
|
|
25
|
+
* than an order of magnitude larger than the insecure-512 ones and no consumer needs both. Load the
|
|
26
|
+
* one you want from its subpath and register it once at start-up:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { setCircuits } from '@crisp-e3/sdk'
|
|
30
|
+
* import { loadCircuits } from '@crisp-e3/sdk/insecure-512'
|
|
31
|
+
*
|
|
32
|
+
* setCircuits(await loadCircuits())
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
declare const setCircuits: (bundle: CircuitBundle) => void;
|
|
36
|
+
/** The registered bundle, or `null` when none has been installed yet. */
|
|
37
|
+
declare const getRegisteredCircuits: () => CircuitBundle | null;
|
|
38
|
+
/** The preset currently installed, or `null` when none has been installed yet. */
|
|
39
|
+
declare const registeredPreset: () => CircuitPreset | null;
|
|
40
|
+
/**
|
|
41
|
+
* The registered bundle, throwing a directed error when nothing has been installed.
|
|
42
|
+
*
|
|
43
|
+
* Proving cannot fall back to a default preset: a ballot proved against the wrong parameters fails
|
|
44
|
+
* on chain rather than locally, so guessing here would move the failure somewhere much harder to
|
|
45
|
+
* read.
|
|
46
|
+
*/
|
|
47
|
+
declare const requireCircuits: () => CircuitBundle;
|
|
48
|
+
|
|
49
|
+
export { type CircuitBundle as C, type CircuitPreset as a, requireCircuits as b, getRegisteredCircuits as g, registeredPreset as r, setCircuits as s };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export { C as CircuitBundle, a as CircuitPreset, g as getRegisteredCircuits, r as registeredPreset, b as requireCircuits, s as setCircuits } from './circuits-BWegRaZy.js';
|
|
1
2
|
import { LeanIMTMerkleProof, LeanIMT } from '@zk-kit/lean-imt';
|
|
2
3
|
import { Hex } from 'viem';
|
|
4
|
+
import '@noir-lang/noir_js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Get the merkle tree data from the CRISP server
|
|
@@ -94,6 +96,14 @@ type ProofData = {
|
|
|
94
96
|
publicInputs: string[];
|
|
95
97
|
proof: Uint8Array;
|
|
96
98
|
encryptedVote: Uint8Array;
|
|
99
|
+
/**
|
|
100
|
+
* The tree index of the entry this input extends, plus one; zero when it extends nothing.
|
|
101
|
+
*
|
|
102
|
+
* `CRISPProgram` reads the parent's commitment from this and hands it to the circuit as
|
|
103
|
+
* `prev_ct_commitment`, and the Secure Process walks each slot's chain by it. Offset by one so
|
|
104
|
+
* that zero means "no parent", which is what index 0 would otherwise be ambiguous with.
|
|
105
|
+
*/
|
|
106
|
+
parentIndexPlusOne: number;
|
|
97
107
|
};
|
|
98
108
|
/**
|
|
99
109
|
* Which circuit a ballot is built for.
|
|
@@ -103,14 +113,34 @@ type ProofData = {
|
|
|
103
113
|
* reads from the token, and matches `CensusMode.ONCHAIN`.
|
|
104
114
|
*/
|
|
105
115
|
type CensusVariant = 'merkle' | 'onchain';
|
|
116
|
+
/**
|
|
117
|
+
* The two halves of a slot head, which only mean anything together.
|
|
118
|
+
*
|
|
119
|
+
* Modelled as a pair rather than two optional fields: a ciphertext without its index would be
|
|
120
|
+
* proven against one entry and published against another, and the mismatch only surfaces as a
|
|
121
|
+
* rejected proof.
|
|
122
|
+
*/
|
|
123
|
+
type SlotHeadInputs = {
|
|
124
|
+
/**
|
|
125
|
+
* The ciphertext currently in the slot: the end of its chain of usable entries, not simply
|
|
126
|
+
* the newest one published. An entry whose bytes do not reproduce its commitment is never
|
|
127
|
+
* selected by the Secure Process and is never a valid parent, so building on it would have
|
|
128
|
+
* this input dropped from the tally.
|
|
129
|
+
*/
|
|
130
|
+
previousCiphertext: Uint8Array;
|
|
131
|
+
/** The tree index of `previousCiphertext`, which this input names as its parent. */
|
|
132
|
+
previousIndex: number;
|
|
133
|
+
} | {
|
|
134
|
+
previousCiphertext?: undefined;
|
|
135
|
+
previousIndex?: undefined;
|
|
136
|
+
};
|
|
106
137
|
type PrepareBallotInputsBase = {
|
|
107
|
-
previousCiphertext?: Uint8Array;
|
|
108
138
|
publicKey: Uint8Array;
|
|
109
139
|
slotAddress: string;
|
|
110
140
|
isMaskVote: boolean;
|
|
111
141
|
numOptions: number;
|
|
112
142
|
vote: Vote;
|
|
113
|
-
};
|
|
143
|
+
} & SlotHeadInputs;
|
|
114
144
|
/**
|
|
115
145
|
* Everything needed to encrypt a ballot, before the voter has signed anything.
|
|
116
146
|
*/
|
|
@@ -130,8 +160,21 @@ type PrepareBallotInputs = (PrepareBallotInputsBase & {
|
|
|
130
160
|
*/
|
|
131
161
|
type PreparedBallot = {
|
|
132
162
|
circuitInputs: any;
|
|
163
|
+
/**
|
|
164
|
+
* The ciphertext to publish, which is the ballot itself for a vote or a re-vote, and the slot's
|
|
165
|
+
* ciphertext plus the zero ballot for a mask over an occupied slot.
|
|
166
|
+
*/
|
|
133
167
|
encryptedVote: Uint8Array;
|
|
168
|
+
/**
|
|
169
|
+
* The commitment to `encryptedVote`: what the circuit returns, what the E3 program stores, and
|
|
170
|
+
* what `CRISPProgram.ballotDigest` takes as its `ciphertextCommitment` argument.
|
|
171
|
+
*
|
|
172
|
+
* Since the digest is itself a circuit input, a caller has to know this value before proving,
|
|
173
|
+
* which is why the wasm exports it rather than leaving it to be read off the finished proof.
|
|
174
|
+
*/
|
|
134
175
|
ctCommitment: `0x${string}`;
|
|
176
|
+
/** The value {@link ProofData.parentIndexPlusOne} carries through to `encodeSolidityProof`. */
|
|
177
|
+
parentIndexPlusOne: number;
|
|
135
178
|
censusMode: CensusVariant;
|
|
136
179
|
};
|
|
137
180
|
/**
|
|
@@ -144,11 +187,23 @@ type DistributiveOmit<T, K extends keyof never> = T extends unknown ? Omit<T, K>
|
|
|
144
187
|
/**
|
|
145
188
|
* A {@link PrepareBallotInputs} plus the round it belongs to.
|
|
146
189
|
*
|
|
147
|
-
* The SDK resolves
|
|
190
|
+
* The SDK resolves the slot head from the server, so callers pass neither part of it.
|
|
148
191
|
*/
|
|
149
192
|
type PrepareBallotRequest = {
|
|
150
193
|
e3Id: bigint;
|
|
151
|
-
} & DistributiveOmit<PrepareBallotInputs, 'previousCiphertext'>;
|
|
194
|
+
} & DistributiveOmit<PrepareBallotInputs, 'previousCiphertext' | 'previousIndex'>;
|
|
195
|
+
/**
|
|
196
|
+
* The end of a slot's chain of usable entries: what a new input extends.
|
|
197
|
+
*
|
|
198
|
+
* Not simply the newest entry published to the slot. An entry whose bytes do not reproduce its
|
|
199
|
+
* commitment is never selected by the Secure Process and is never a valid parent, so the server
|
|
200
|
+
* resolves the chain and answers with the entry that actually holds the slot.
|
|
201
|
+
*/
|
|
202
|
+
type SlotHead = {
|
|
203
|
+
ciphertext: Uint8Array;
|
|
204
|
+
/** The tree index of that entry. */
|
|
205
|
+
index: number;
|
|
206
|
+
};
|
|
152
207
|
/**
|
|
153
208
|
* Type representing the current round returned by the CRISP server (`rounds/current`)
|
|
154
209
|
*/
|
|
@@ -277,6 +332,22 @@ declare const getRoundTokenDetails: (serverUrl: string, e3Id: bigint) => Promise
|
|
|
277
332
|
* @returns The on chain round data
|
|
278
333
|
*/
|
|
279
334
|
declare const getOnChainRoundData: (programAddress: string, e3Id: bigint, chainId: number) => Promise<OnChainRoundData>;
|
|
335
|
+
/**
|
|
336
|
+
* Get the voting power a slot may spend in a `CensusMode.ONCHAIN` round, in ballot units.
|
|
337
|
+
*
|
|
338
|
+
* Read from the CRISP program rather than derived here. The contract scales raw token power by a
|
|
339
|
+
* per-round divisor before handing it to the circuit as public input 4, and it is the same
|
|
340
|
+
* contract that verifies the proof — so recomputing the value client-side would mean re-deriving
|
|
341
|
+
* the round's snapshot, its divisor and the rounding, and any drift surfaces only as an opaque
|
|
342
|
+
* verifier failure.
|
|
343
|
+
*
|
|
344
|
+
* @param programAddress - The CRISP program address
|
|
345
|
+
* @param e3Id - The e3Id of the round
|
|
346
|
+
* @param slot - The slot address the ballot is written to
|
|
347
|
+
* @param chainId - The chain the program is deployed on
|
|
348
|
+
* @returns The spendable voting power in ballot units, or 0 for a round that is not ONCHAIN
|
|
349
|
+
*/
|
|
350
|
+
declare const getOnchainVotingPower: (programAddress: string, e3Id: bigint, slot: string, chainId: number) => Promise<bigint>;
|
|
280
351
|
/**
|
|
281
352
|
* Get the previous ciphertext for a slot from the CRISP server.
|
|
282
353
|
* Returns undefined when the slot is empty (404).
|
|
@@ -284,9 +355,10 @@ declare const getOnChainRoundData: (programAddress: string, e3Id: bigint, chainI
|
|
|
284
355
|
* @param serverUrl - The base URL of the CRISP server
|
|
285
356
|
* @param e3Id - The e3Id of the round
|
|
286
357
|
* @param address - The address of the slot
|
|
287
|
-
* @returns The
|
|
358
|
+
* @returns The end of the slot's chain of usable entries and its tree index, or undefined when the
|
|
359
|
+
* slot holds nothing usable. The index is what a new input names as its parent.
|
|
288
360
|
*/
|
|
289
|
-
declare const getPreviousCiphertext: (serverUrl: string, e3Id: bigint, address: string) => Promise<
|
|
361
|
+
declare const getPreviousCiphertext: (serverUrl: string, e3Id: bigint, address: string) => Promise<SlotHead | undefined>;
|
|
290
362
|
|
|
291
363
|
/**
|
|
292
364
|
* Get the current (most recent) round, optionally filtered by requester addresses.
|
|
@@ -561,7 +633,7 @@ declare const verifyProof: (proof: ProofData, censusMode?: CensusVariant) => Pro
|
|
|
561
633
|
* @param proof The proof data.
|
|
562
634
|
* @returns The encoded proof data as a hex string.
|
|
563
635
|
*/
|
|
564
|
-
declare const encodeSolidityProof: ({ publicInputs, proof, encryptedVote }: ProofData) => Hex;
|
|
636
|
+
declare const encodeSolidityProof: ({ publicInputs, proof, encryptedVote, parentIndexPlusOne }: ProofData) => Hex;
|
|
565
637
|
|
|
566
638
|
/**
|
|
567
639
|
* A class representing the CRISP SDK.
|
|
@@ -700,9 +772,9 @@ declare class CrispSDK {
|
|
|
700
772
|
* Get the previous ciphertext input for a slot address in a given round.
|
|
701
773
|
* @param e3Id - The e3Id of the round
|
|
702
774
|
* @param address - The address of the slot
|
|
703
|
-
* @returns The
|
|
775
|
+
* @returns The slot head and its tree index, or undefined if the slot holds nothing usable
|
|
704
776
|
*/
|
|
705
|
-
getPreviousCiphertext(e3Id: bigint, address: string): Promise<
|
|
777
|
+
getPreviousCiphertext(e3Id: bigint, address: string): Promise<SlotHead | undefined>;
|
|
706
778
|
}
|
|
707
779
|
|
|
708
|
-
export { type BroadcastVoteRequest, type BroadcastVoteResponse, type CensusVariant, CreditMode, CrispSDK, type CurrentRoundResponse, type E3StateLiteResponse, type JsonResponse, MAX_MSG_NON_ZERO_COEFFS, MAX_VOTE_OPTIONS, MERKLE_TREE_MAX_DEPTH, type NewRoundRequest, type OnChainRoundData, type PrepareBallotInputs, type PrepareBallotRequest, type PreparedBallot, type ProofData, type RoundDetails, SIGNATURE_MESSAGE, SIGNATURE_MESSAGE_HASH, type TallyResult, type TokenDetails, type TokenHolder, type Vote, type VoteResponseStatus, type VoteStatusResponse, type WebResultResponse, broadcastVote, decodeTally, decryptVote, destroyBBApi, encodeSolidityProof, encodeVote, encryptVote, finishBallotProof, finishMaskProof, generateBFVKeys, generateMerkleProof, generateMerkleTree, getAddressFromSignature, getAllRoundResults, getBalanceAt, getCurrentRound, getEligibleAddresses, getMaxVoteValue, getOnChainRoundData, getPreviousCiphertext, getRoundCiphertext, getRoundDetails, getRoundPublicKey, getRoundResult, getRoundStateLite, getRoundTokenDetails, getScaledBalance, getTokenHolderHashes, getTotalSupplyAt, getTreeData, getVoteStatus, getZeroVote, hashLeaf, prepareBallot, prepareCircuitInputs, requestNewRound, splitDigest, validateVote, verifyProof };
|
|
780
|
+
export { type BroadcastVoteRequest, type BroadcastVoteResponse, type CensusVariant, CreditMode, CrispSDK, type CurrentRoundResponse, type E3StateLiteResponse, type JsonResponse, MAX_MSG_NON_ZERO_COEFFS, MAX_VOTE_OPTIONS, MERKLE_TREE_MAX_DEPTH, type NewRoundRequest, type OnChainRoundData, type PrepareBallotInputs, type PrepareBallotRequest, type PreparedBallot, type ProofData, type RoundDetails, SIGNATURE_MESSAGE, SIGNATURE_MESSAGE_HASH, type SlotHead, type TallyResult, type TokenDetails, type TokenHolder, type Vote, type VoteResponseStatus, type VoteStatusResponse, type WebResultResponse, broadcastVote, decodeTally, decryptVote, destroyBBApi, encodeSolidityProof, encodeVote, encryptVote, finishBallotProof, finishMaskProof, generateBFVKeys, generateMerkleProof, generateMerkleTree, getAddressFromSignature, getAllRoundResults, getBalanceAt, getCurrentRound, getEligibleAddresses, getMaxVoteValue, getOnChainRoundData, getOnchainVotingPower, getPreviousCiphertext, getRoundCiphertext, getRoundDetails, getRoundPublicKey, getRoundResult, getRoundStateLite, getRoundTokenDetails, getScaledBalance, getTokenHolderHashes, getTotalSupplyAt, getTreeData, getVoteStatus, getZeroVote, hashLeaf, prepareBallot, prepareCircuitInputs, requestNewRound, splitDigest, validateVote, verifyProof };
|