@crisp-e3/sdk 0.14.0 → 0.15.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/dist/index.d.ts
CHANGED
|
@@ -81,6 +81,15 @@ type MerkleProof = {
|
|
|
81
81
|
* Type representing a vote
|
|
82
82
|
*/
|
|
83
83
|
type Vote = number[];
|
|
84
|
+
/**
|
|
85
|
+
* Type representing a decoded tally: one total per option.
|
|
86
|
+
*
|
|
87
|
+
* @remarks
|
|
88
|
+
* Uses `bigint` because an aggregated tally coefficient is a sum over all ballots,
|
|
89
|
+
* so a total can exceed `Number.MAX_SAFE_INTEGER`. This matches the `BigUint` the
|
|
90
|
+
* CRISP server returns and the `uint256` the CRISP contract returns.
|
|
91
|
+
*/
|
|
92
|
+
type TallyResult = bigint[];
|
|
84
93
|
type ProofData = {
|
|
85
94
|
publicInputs: string[];
|
|
86
95
|
proof: Uint8Array;
|
|
@@ -405,6 +414,17 @@ declare const getScaledBalance: (balance: bigint, decimals: bigint) => bigint;
|
|
|
405
414
|
* encoding, encryption, decryption, and tally decoding.
|
|
406
415
|
*/
|
|
407
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Encodes vote choices into a polynomial coefficient array for BFV encryption.
|
|
419
|
+
* Each choice occupies floor(MAX_MSG_NON_ZERO_COEFFS / n) binary coefficients;
|
|
420
|
+
* remaining slots in the first MAX_MSG_NON_ZERO_COEFFS coeffs are zero; then
|
|
421
|
+
* the vector is padded to the BFV degree.
|
|
422
|
+
*
|
|
423
|
+
* @param vote - Array of numeric values per choice (e.g. [10, 5] for 2 options)
|
|
424
|
+
* @returns Array of 0s and 1s representing coefficients
|
|
425
|
+
* @throws If vote has fewer than 2 choices, any value exceeds max for its segment, or degree is too small
|
|
426
|
+
*/
|
|
427
|
+
declare const encodeVote: (vote: Vote) => number[];
|
|
408
428
|
/**
|
|
409
429
|
* Encrypts an encoded vote using BFV homomorphic encryption.
|
|
410
430
|
*
|
|
@@ -414,14 +434,29 @@ declare const getScaledBalance: (balance: bigint, decimals: bigint) => bigint;
|
|
|
414
434
|
*/
|
|
415
435
|
declare const encryptVote: (vote: Vote, publicKey: Uint8Array) => Uint8Array;
|
|
416
436
|
/**
|
|
417
|
-
* Decodes raw tally bytes (or
|
|
437
|
+
* Decodes raw tally bytes (or coefficients) into a total per choice.
|
|
418
438
|
* Expects the same segment layout as used in encodeVote.
|
|
419
439
|
*
|
|
420
|
-
*
|
|
440
|
+
* Mirrors `crisp_utils::decode_tally` (Rust) and `CRISPProgram.decodeTally` (Solidity):
|
|
441
|
+
* only the first MAX_MSG_NON_ZERO_COEFFS coefficients carry the payload, split into
|
|
442
|
+
* `floor(MAX_MSG_NON_ZERO_COEFFS / numChoices)` binary coefficients per choice, MSB first.
|
|
443
|
+
*
|
|
444
|
+
* @param tallyBytes - Hex string, or the polynomial coefficients from tally/decryption
|
|
445
|
+
* @param numChoices - Number of vote options: an integer from 2 to MAX_VOTE_OPTIONS
|
|
446
|
+
* @returns One total per choice
|
|
447
|
+
* @throws If numChoices is outside 2..MAX_VOTE_OPTIONS or not an integer, or there are fewer
|
|
448
|
+
* coefficients than the payload region
|
|
449
|
+
*/
|
|
450
|
+
declare const decodeTally: (tallyBytes: string | number[] | bigint[], numChoices: number) => TallyResult;
|
|
451
|
+
/**
|
|
452
|
+
* Decrypts a BFV-encrypted vote and decodes it to vote values.
|
|
453
|
+
*
|
|
454
|
+
* @param ciphertext - Encrypted vote
|
|
455
|
+
* @param secretKey - BFV secret key
|
|
421
456
|
* @param numChoices - Number of vote options
|
|
422
|
-
* @returns
|
|
457
|
+
* @returns One total per choice
|
|
423
458
|
*/
|
|
424
|
-
declare const
|
|
459
|
+
declare const decryptVote: (ciphertext: Uint8Array, secretKey: Uint8Array, numChoices: number) => TallyResult;
|
|
425
460
|
/**
|
|
426
461
|
* Generates a BFV keypair for vote encryption and decryption.
|
|
427
462
|
*
|
|
@@ -596,4 +631,4 @@ declare class CrispSDK {
|
|
|
596
631
|
getPreviousCiphertext(e3Id: number, address: string): Promise<Uint8Array | undefined>;
|
|
597
632
|
}
|
|
598
633
|
|
|
599
|
-
export { type BroadcastVoteRequest, type BroadcastVoteResponse, CreditMode, CrispSDK, type CurrentRoundResponse, type E3StateLiteResponse, type JsonResponse, MAX_MSG_NON_ZERO_COEFFS, MAX_VOTE_OPTIONS, MERKLE_TREE_MAX_DEPTH, type MaskVoteProofInputs, type NewRoundRequest, type OnChainRoundData, type ProofData, type RoundDetails, SIGNATURE_MESSAGE, SIGNATURE_MESSAGE_HASH, type TokenDetails, type TokenHolder, type Vote, type VoteProofInputs, type VoteResponseStatus, type VoteStatusResponse, type WebResultResponse, broadcastVote, decodeTally, destroyBBApi, encodeSolidityProof, encryptVote, generateBFVKeys, generateMaskVoteProof, generateMerkleProof, generateMerkleTree, generateVoteProof, getAddressFromSignature, getAllRoundResults, getBalanceAt, getCurrentRound, getEligibleAddresses, getMaxVoteValue, getOnChainRoundData, getPreviousCiphertext, getRoundCiphertext, getRoundDetails, getRoundPublicKey, getRoundResult, getRoundStateLite, getRoundTokenDetails, getScaledBalance, getTokenHolderHashes, getTotalSupplyAt, getTreeData, getVoteStatus, getZeroVote, hashLeaf, requestNewRound, validateVote, verifyProof };
|
|
634
|
+
export { type BroadcastVoteRequest, type BroadcastVoteResponse, CreditMode, CrispSDK, type CurrentRoundResponse, type E3StateLiteResponse, type JsonResponse, MAX_MSG_NON_ZERO_COEFFS, MAX_VOTE_OPTIONS, MERKLE_TREE_MAX_DEPTH, type MaskVoteProofInputs, type NewRoundRequest, type OnChainRoundData, type ProofData, type RoundDetails, SIGNATURE_MESSAGE, SIGNATURE_MESSAGE_HASH, type TallyResult, type TokenDetails, type TokenHolder, type Vote, type VoteProofInputs, type VoteResponseStatus, type VoteStatusResponse, type WebResultResponse, broadcastVote, decodeTally, decryptVote, destroyBBApi, encodeSolidityProof, encodeVote, encryptVote, generateBFVKeys, generateMaskVoteProof, generateMerkleProof, generateMerkleTree, generateVoteProof, getAddressFromSignature, getAllRoundResults, getBalanceAt, getCurrentRound, getEligibleAddresses, getMaxVoteValue, getOnChainRoundData, getPreviousCiphertext, getRoundCiphertext, getRoundDetails, getRoundPublicKey, getRoundResult, getRoundStateLite, getRoundTokenDetails, getScaledBalance, getTokenHolderHashes, getTotalSupplyAt, getTreeData, getVoteStatus, getZeroVote, hashLeaf, requestNewRound, validateVote, verifyProof };
|
package/dist/index.js
CHANGED
|
@@ -295,7 +295,7 @@ var getMaxVoteValue = (numChoices) => {
|
|
|
295
295
|
var getZeroVote = (numChoices) => {
|
|
296
296
|
return Array(numChoices).fill(0);
|
|
297
297
|
};
|
|
298
|
-
var
|
|
298
|
+
var decodeBytesToBigInts = (data) => {
|
|
299
299
|
if (data.length % 8 !== 0) {
|
|
300
300
|
throw new Error("Data length must be multiple of 8");
|
|
301
301
|
}
|
|
@@ -305,7 +305,7 @@ var decodeBytesToNumbers = (data) => {
|
|
|
305
305
|
for (let i = 0; i < arrayLength; i++) {
|
|
306
306
|
result.push(view.getBigUint64(i * 8, true));
|
|
307
307
|
}
|
|
308
|
-
return result
|
|
308
|
+
return result;
|
|
309
309
|
};
|
|
310
310
|
var numberArrayToBigInt64Array = (numberArray) => {
|
|
311
311
|
return BigInt64Array.from(numberArray.map(BigInt));
|
|
@@ -338,6 +338,9 @@ var encodeVote = (vote) => {
|
|
|
338
338
|
if (numChoices < 2) {
|
|
339
339
|
throw new Error("Vote must have at least two choices");
|
|
340
340
|
}
|
|
341
|
+
if (numChoices > MAX_VOTE_OPTIONS) {
|
|
342
|
+
throw new Error(`Number of choices (${numChoices}) exceeds MAX_VOTE_OPTIONS (${MAX_VOTE_OPTIONS})`);
|
|
343
|
+
}
|
|
341
344
|
const bfvParams = getZkInputsGenerator().getBFVParams();
|
|
342
345
|
const degree = bfvParams.degree;
|
|
343
346
|
if (degree < MAX_MSG_NON_ZERO_COEFFS) {
|
|
@@ -371,27 +374,38 @@ var encryptVote = (vote, publicKey) => {
|
|
|
371
374
|
return getZkInputsGenerator().encryptVote(publicKey, numberArrayToBigInt64Array(encodedVote));
|
|
372
375
|
};
|
|
373
376
|
var decodeTally = (tallyBytes, numChoices) => {
|
|
377
|
+
if (!Number.isInteger(numChoices) || numChoices < 2) {
|
|
378
|
+
throw new Error(`Number of choices (${numChoices}) must be an integer of at least 2`);
|
|
379
|
+
}
|
|
380
|
+
if (numChoices > MAX_VOTE_OPTIONS) {
|
|
381
|
+
throw new Error(`Number of choices (${numChoices}) exceeds MAX_VOTE_OPTIONS (${MAX_VOTE_OPTIONS})`);
|
|
382
|
+
}
|
|
383
|
+
let coefficients;
|
|
374
384
|
if (typeof tallyBytes === "string") {
|
|
375
385
|
const hexString = tallyBytes.startsWith("0x") ? tallyBytes : `0x${tallyBytes}`;
|
|
376
|
-
|
|
386
|
+
coefficients = decodeBytesToBigInts(hexToBytes2(hexString));
|
|
387
|
+
} else {
|
|
388
|
+
coefficients = tallyBytes.map(BigInt);
|
|
377
389
|
}
|
|
378
|
-
if (
|
|
379
|
-
throw new Error(
|
|
390
|
+
if (coefficients.length < MAX_MSG_NON_ZERO_COEFFS) {
|
|
391
|
+
throw new Error(`decoded coefficient count (${coefficients.length}) is less than MAX_MSG_NON_ZERO_COEFFS (${MAX_MSG_NON_ZERO_COEFFS})`);
|
|
380
392
|
}
|
|
381
393
|
const segmentSize = Math.floor(MAX_MSG_NON_ZERO_COEFFS / numChoices);
|
|
382
394
|
const results = [];
|
|
383
395
|
for (let choiceIdx = 0; choiceIdx < numChoices; choiceIdx++) {
|
|
384
396
|
const segmentStart = choiceIdx * segmentSize;
|
|
385
|
-
|
|
386
|
-
let
|
|
387
|
-
|
|
388
|
-
const weight = 2 ** (segment.length - 1 - i);
|
|
389
|
-
value += segment[i] * weight;
|
|
397
|
+
let value = 0n;
|
|
398
|
+
for (let i = 0; i < segmentSize; i++) {
|
|
399
|
+
value += coefficients[segmentStart + i] << BigInt(segmentSize - 1 - i);
|
|
390
400
|
}
|
|
391
401
|
results.push(value);
|
|
392
402
|
}
|
|
393
403
|
return results;
|
|
394
404
|
};
|
|
405
|
+
var decryptVote = (ciphertext, secretKey, numChoices) => {
|
|
406
|
+
const decryptedVote = getZkInputsGenerator().decryptVote(secretKey, ciphertext);
|
|
407
|
+
return decodeTally(Array.from(decryptedVote), numChoices);
|
|
408
|
+
};
|
|
395
409
|
var generateBFVKeys = () => {
|
|
396
410
|
return getZkInputsGenerator().generateKeys();
|
|
397
411
|
};
|
|
@@ -3626,8 +3640,10 @@ export {
|
|
|
3626
3640
|
SIGNATURE_MESSAGE_HASH,
|
|
3627
3641
|
broadcastVote,
|
|
3628
3642
|
decodeTally,
|
|
3643
|
+
decryptVote,
|
|
3629
3644
|
destroyBBApi,
|
|
3630
3645
|
encodeSolidityProof,
|
|
3646
|
+
encodeVote,
|
|
3631
3647
|
encryptVote,
|
|
3632
3648
|
generateBFVKeys,
|
|
3633
3649
|
generateMaskVoteProof,
|