- Always Read First: Before creating or modifying any file, always read its existing content (if any) to understand the current state. Do not make assumptions about file existence or content.
- Verify and Confirm: Explicitly verify existing structures and confirm requirements before implementing changes.
- Keep Tasks Updated: Regularly update this document (
INTEGRATION_TASKS.md) by marking tasks as completed (e.g., checking off[ ]to[X]) as they are finished. - Refactor Large Files: Prioritize refactoring for any service or utility file exceeding approximately 500 lines of code to maintain readability and manageability.
- Modularity & Single Responsibility: Strive for modular code. Each function, class, and service should ideally have a single, well-defined responsibility.
- Clarity & Readability: Write clear, concise, and readable code. Use meaningful names for variables, functions, and classes.
- DRY (Don't Repeat Yourself): Avoid code duplication. Abstract common logic into reusable functions or utilities.
- Consistent Error Handling: (Related to optional task for
blockchainProvider.js) Aim for consistent error handling patterns, making it clear how errors are propagated. - Immutability (where practical): Prefer immutable data structures and pure functions when appropriate to reduce side effects and improve predictability.
To improve modularity, maintainability, and clarity, the frontend services will be reorganized as follows:
frontend/services/blockchainProvider.js: (Replaces/evolves fromethersBase.js) Handles core Web3 provider/signer logic, network connections, and basic contract interaction utilities.contracts/factoryService.js: All interactions withVoteSessionFactory.sol.registryParticipantService.js: Handles participant aspects ofParticipantRegistry.sol.registryFundService.js: Handles funding and reward aspects ofParticipantRegistry.sol.registryAdminService.js: Handles administrative aspects ofParticipantRegistry.sol.voteSessionService.js: All interactions withVoteSession.sol.
utils/cryptographyUtils.js: Core cryptographic operations (BLS, hashing, shares, etc.).aesUtils.js: AES encryption/decryption utilities.conversionUtils.js: Data type conversion utilities (hex, bytes, string, BigInt).blsUtils.js: Lower-level BLS point manipulations and pairings (if needed directly, otherwise abstracted bycryptographyUtils.js).lagrangeUtils.js: Lagrange interpolation logic.constants.js: Shared constants (e.g., domain separators for hashing).
- Provider & Signer Management: (Initial version implemented, including dynamic event handling)
- Initialize ethers.js provider (e.g.,
Web3Providerfromwindow.ethereumor a fallback RPC). - Manage signer acquisition and updates when account changes in wallet.
- Implement robust detection and handling of network changes (e.g., chain ID).
- Expose functions to get current provider, signer, user address, and chain ID.
- Initialize ethers.js provider (e.g.,
- Contract Interaction Utilities: (Initial version implemented)
- Generic function
getContractInstance(contractAddress, contractAbi): Returns an ethers.jsContractinstance. - Generic function
readContract(contractInstance, methodName, args): For calling view/pure functions.- Includes error handling for contract reverts, parsing error messages.
- Generic function
sendTransaction(contractInstance, methodName, args, value): For calling state-changing functions.- Handles transaction submission, waits for confirmation (configurable via
confirmationsparameter). - Parses transaction receipts and extracts relevant event data (returns full receipt; specific parsing can be in calling service).
- Includes robust error handling (reverts, gas issues, user rejection).
- Handles transaction submission, waits for confirmation (configurable via
- Generic function
- Event Handling: (Wallet event handling improved with CustomEvents; contract event helpers exist)
- Helper functions for subscribing to and unsubscribing from contract events.
- Utility Functions: (Implemented)
-
hashMessage(message): Usesethers.utils.id. - Wei/Ether conversion utilities (
formatEther,parseEther).
-
- Error Handling:
- (Optional) Define a consistent custom error object structure (e.g.,
BlockchainProviderErrorextendingErrorwith codes) for services to throw/return. - Centralized parsing of common Ethers.js errors and contract revert reasons (initial version implemented, can be expanded with custom errors).
- (Optional) Define a consistent custom error object structure (e.g.,
- JSDoc Comments: Add for all functions (initial pass completed, updated for event handlers).
General Requirements for all Contract Services:
- Load ABIs directly from the
crypto-core/artifacts/contracts/CONTRACT_NAME.sol/CONTRACT_NAME.jsonpaths (e.g.,crypto-core/artifacts/contracts/VoteSessionFactory.sol/VoteSessionFactory.json). - Utilize
blockchainProvider.jsfor all contract interactions. - Implement clear separation between functions performing read operations (view/pure) and write operations (transactions).
- Perform necessary data type conversions (e.g., JavaScript numbers/strings to BigNumber for contract calls, and vice-versa for results).
- Implement comprehensive error handling, catching errors from
blockchainProvider.jsand providing context-specific error messages. - Add JSDoc comments for all public functions, detailing parameters, return values, and contract methods called.
- Function Documentation Standard: For each public function in a service, clearly document (both in JSDoc and where function lists appear in this document):
- Call Signature: (e.g.,
functionName(param1: type, param2: type): Promise<ReturnType>) - Input(s): Detailed description of each parameter, its expected type, and purpose.
- Output: Detailed description of the return value, its type, and structure.
- Action: Brief description of what the function does, including the primary smart contract method it calls (if any) and whether it's a read or write operation.
- Call Signature: (e.g.,
2.1. factoryService.js (Interactions with VoteSessionFactory.sol)
- [~] Configuration: (Factory address currently read from global config; getter/setter function not implemented but current approach is acceptable)
- Function to set/get the deployed
VoteSessionFactorycontract address.
- Function to set/get the deployed
-
createSessionPair(title, description, startDate, endDate, sharesEndDate, options, metadata, requiredDeposit, minShareThreshold): (Implemented ascreateVoteSession)- Calls
VoteSessionFactory.createSessionPair(). - Input: All parameters as defined in
CONTRACT_API.md. Ensure correct types (e.g., timestamps as numbers/BigNumbers,requiredDepositas BigNumberish). - Output:
{ voteSessionProxyAddress: string, registryProxyAddress: string, sessionId: number/string }. - Action: Write transaction.
- Listen for
SessionPairDeployedevent to confirm and extract addresses/ID. (Event parsing implemented)
- Calls
-
getDeployedSessionCount():- Calls
VoteSessionFactory.getDeployedSessionCount(). - Output:
number. - Action: Read operation.
- Calls
-
getVoteSessionAddressByIndex(index):- Calls
VoteSessionFactory.getVoteSessionAddressByIndex(). - Input:
index (number). - Output:
string (address). - Action: Read operation.
- Calls
-
getVoteSessionAddressById(sessionId): (Covered bygetSessionAddressesmethod in service)- Calls
VoteSessionFactory.getVoteSessionAddressById(). - Input:
sessionId (number/string). - Output:
string (address). - Action: Read operation.
- Calls
-
getRegistryAddressById(sessionId): (Covered bygetSessionAddressesmethod in service)- Calls
VoteSessionFactory.getRegistryAddressById(). - Input:
sessionId (number/string). - Output:
string (address). - Action: Read operation.
- Calls
-
getFactoryOwner():- Calls
VoteSessionFactory.owner(). - Output:
string (address). - Action: Read operation.
- Calls
-
transferFactoryOwnership(newOwner):- Calls
VoteSessionFactory.transferOwnership(). - Input:
newOwner (string address). - Action: Write transaction.
- Calls
2.2. Refactoring registryService.js
Due to its increasing size, registryService.js will be refactored into three more focused services. Each service will handle a specific domain of the ParticipantRegistry.sol contract's functionality. They will reside in frontend/services/contracts/.
General Requirements for these new Registry-related Services:
- Each service will be a class exporting a singleton instance.
- Each service will import and use
blockchainProviderServicefor all contract interactions. - Each service will import and use
factoryService(specificallyfactoryService.getSessionAddresses(sessionId)) to resolve theregistryAddressfor a givensessionIdbefore interacting with the registry contract. - Each service will load/manage necessary ABIs (
ParticipantRegistry.json, andVoteSession.jsonif calls to VoteSession contract are needed from that specific service). - All methods will be aligned with
CONTRACT_API.mdforParticipantRegistry.sol. - Comprehensive JSDoc and error handling for all methods.
2.2.1. registryParticipantService.js (Handles participant registration and information)
-
registerAsHolder(sessionId, blsPublicKeyHex): (Moved fromregistryService.js)- Calls
ParticipantRegistry.joinAsHolder(). - Requires fetching
requiredDepositfromVoteSession.getRequiredDeposit(). - Requires checking
VoteSession.isRegistrationOpen().
- Calls
-
registerAsVoter(sessionId): (Moved fromregistryService.js)- Calls
ParticipantRegistry.registerAsVoter(). - Requires checking
VoteSession.isRegistrationOpen().
- Calls
-
getParticipantInfo(sessionId, participantAddress): (Moved fromregistryService.js)- Calls
ParticipantRegistry.getParticipantInfo(). - Returns
{ isRegistered, isHolder, depositAmount, blsPublicKeyHex, hasSubmittedShares }(deposit formatted).
- Calls
-
getActiveHolders(sessionId): (Moved fromregistryService.js)- Calls
ParticipantRegistry.getActiveHolders().
- Calls
-
getNumberOfActiveHolders(sessionId): (Moved fromregistryService.js)- Calls
ParticipantRegistry.getNumberOfActiveHolders().
- Calls
-
getHolderBlsKeys(sessionId): (Moved fromregistryService.js)- Calls
ParticipantRegistry.getHolderBlsKeys(). - Returns
{ addresses: string[], blsKeysHex: string[] }.
- Calls
-
getParticipantIndex(sessionId, participantAddress): (Moved fromregistryService.js)- Calls
ParticipantRegistry.getParticipantIndex().
- Calls
-
claimDeposit(sessionId): (Implemented inRegistryParticipantService.js)- Calls
ParticipantRegistry.claimDeposit(). - TODO: Check
VoteSession.isDepositClaimPeriodActive().
- Calls
-
hasClaimedDeposit(sessionId, participantAddress): (Implemented inRegistryParticipantService.js)- Calls
ParticipantRegistry.depositClaimed().
- Calls
2.2.2. registryFundService.js (Manages funding, claims, and financial queries)
-
addRewardFunding(sessionId, amountInWei): (Moved fromregistryService.js, Owner-only on contract)- Calls
ParticipantRegistry.addRewardFunding()withmsg.value.
- Calls
-
claimReward(sessionId): (Moved fromregistryService.js)- Calls
ParticipantRegistry.claimReward().
- Calls
-
getClaimableAmounts(sessionId, participantAddress): (Moved fromregistryService.js) - To be refactored/replaced bygetRewardsOwedand participant deposit info.- Fetches
rewardsOwedfor the participant. - Fetches participant's deposit and checks
hasSubmittedSharesviagetParticipantInfo(potentially fromRegistryParticipantServiceor directly if kept simple). - Returns
{ claimableRewardWei: bigint, claimableDepositWei: bigint }.
- Fetches
-
hasClaimedReward(sessionId, participantAddress): (Moved fromregistryService.js)- Calls
ParticipantRegistry.rewardClaimed().
- Calls
-
getTotalRewardPool(sessionId): (Implemented inRegistryFundService.js)- Calls
ParticipantRegistry.totalRewardPool(). - Output:
string (BigNumberish, amount in Wei).
- Calls
-
getRewardsOwed(sessionId, participantAddress): (Implemented inRegistryFundService.js)- Calls
ParticipantRegistry.rewardsOwed(). - Output:
string (BigNumberish, amount in Wei).
- Calls
2.2.3. registryAdminService.js (Handles administrative and owner-specific functions)
-
setVoteSessionContract(sessionId, sessionContractAddress): (Implemented inRegistryAdminService.js)- Calls
ParticipantRegistry.setVoteSessionContract().
- Calls
-
calculateRewards(sessionId): (Implemented inRegistryAdminService.js)- Calls
ParticipantRegistry.calculateRewards(). - Requires checking
VoteSession.isRewardCalculationPeriodActive()(TODO in service).
- Calls
-
getRegistryOwner(sessionId): (Implemented inRegistryAdminService.js)- Gets
registryAddressforsessionIdviafactoryService. - Calls
ParticipantRegistry.owner()on thatregistryAddress.
- Gets
-
transferRegistryOwnership(sessionId, newOwner): (Implemented inRegistryAdminService.js)- Gets
registryAddressforsessionIdviafactoryService. - Calls
ParticipantRegistry.transferOwnership()on thatregistryAddress.
- Gets
Old registryService.js Status:
- File
frontend/services/contracts/registryService.jshas been deleted as its functionality is now covered byRegistryParticipantService.js,RegistryFundService.js, andRegistryAdminService.js.
2.3. Refactoring voteSessionService.js
Due to its large size (800+ lines), voteSessionService.js will be refactored into three more focused services. Each service will handle a specific domain of the VoteSession.sol contract's functionality. They will reside in frontend/services/contracts/.
General Requirements for these new VoteSession-related Services:
- Each service will be a class exporting a singleton instance.
- Each service will import and use
blockchainProviderServicefor all contract interactions. - Each service will load/manage the
VoteSession.jsonABI. - All methods will be aligned with
CONTRACT_API.mdforVoteSession.sol. - Holder Submissions: Services interacting with
submitDecryptionShareandsubmitDecryptionValuemust account for theSharesCollectionOpenperiod (defined byendDatetosharesCollectionEndDateinVoteSession.sol), which serves as the primary window (e.g., 15 minutes) for holders to submit their cryptographic materials. Failure to complete necessary submissions within this window will result in penalties (loss of deposit/reward) enforced byParticipantRegistry.solduring reward calculation. - Comprehensive JSDoc and error handling for all methods.
- The existing
_getContractInstanceand_SessionStatusEnumfromvoteSessionService.jscan be reused or adapted in each new service.
2.3.1. voteSessionAdminService.js (Handles admin/owner functions, status updates, and calculations)
* [X] setDecryptionParameters(voteSessionAddress, alphas, threshold) (Moved from voteSessionService.js)
* [X] transferSessionOwnership(voteSessionAddress, newOwner) (Moved from voteSessionService.js)
* [X] updateSessionStatus(voteSessionAddress) (Moved from voteSessionService.js)
* [X] triggerRewardCalculation(voteSessionAddress) (Moved from voteSessionService.js)
* [X] Service created, relevant methods moved from voteSessionService.js.
* [X] voteSessionService.js updated to remove these methods and add deprecation tags.
2.3.2. voteSessionVotingService.js (Handles casting votes, submitting shares/values)
* [X] castEncryptedVote(voteSessionAddress, ciphertext, g1r, g2r, alpha, threshold) (Moved from voteSessionService.js)
* [X] submitDecryptionShare(voteSessionAddress, voteIndex, share, shareIndex) (Moved from voteSessionService.js)
* This is the first crucial step for a holder during the SharesCollectionOpen period (e.g., 15 minutes post-voting).
* Calls VoteSession.sol::submitDecryptionShare(), which in turn calls ParticipantRegistry.sol::recordShareSubmission().
* [X] submitDecryptionValue(voteSessionAddress, value) (Moved from voteSessionService.js)
* This is the second crucial step for a holder, ideally also within the SharesCollectionOpen period.
* Calls VoteSession.sol::submitDecryptionValue(). This function requires that recordShareSubmission was successfully called for the holder in ParticipantRegistry.sol.
* The "value" is typically a hash of the holder's private key (e.g., SHA256(sk)), confirming their active participation.
* [X] Service created, relevant methods moved from voteSessionService.js.
* [X] voteSessionService.js updated to remove these methods.
2.3.3. voteSessionViewService.js (Handles all read-only/getter functions)
* [X] isRegistrationOpen(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getRequiredDeposit(voteSessionAddress) (Moved from voteSessionService.js)
* [X] isRewardCalculationPeriodActive(voteSessionAddress) (Moved from voteSessionService.js)
* [X] isDepositClaimPeriodActive(voteSessionAddress) (Moved from voteSessionService.js)
* [] ] getSessionDetails(voteSessionAddress) (Moved from voteSessionService.js)
* (CONTRACT_API.md lists this, but VoteSession.sol source does NOT have getSessionDetails(). Service method needs refactor/removal. Test is currently commented out.)
* [getSessionInfo(voteSessionAddress) (Moved from voteSessionService.js)
* (CONTRACT_API.md signature is outdated. Service method calls contract.getSessionInfo() which returns 10-element tuple per VoteSession.sol source. Service parsing corrected.)
* [X] getStatus(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getEncryptedVote(voteSessionAddress, voteIndex) (Moved from voteSessionService.js)
* [X] getNumberOfVotes(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getDecryptionShare(voteSessionAddress, shareLogIndex) (Moved from voteSessionService.js)
* [X] getNumberOfSubmittedShares(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getDecryptionParameters(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getSubmittedValues(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getSessionOwner(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getSessionId(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getParticipantRegistryAddress(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getTitle(voteSessionAddress) (Moved from voteSessionService.js)
* [X] getDescription(voteSessionAddress) (Moved from voteSessionService.js)
* [X] Service created, all remaining view methods moved from voteSessionService.js.
* [X] (Add any other view functions from VoteSession.sol if deemed necessary) - Considered complete for now.
Old voteSessionService.js Status:
- File
frontend/services/contracts/voteSessionService.jshas been deleted as its functionality is now fully covered by the new services above.
General Requirements for all Utility Services:
- Pure JavaScript functions, no direct blockchain interactions.
- Comprehensive JSDoc comments for all functions.
- Thorough unit testing.
3.1. cryptographyUtils.js
* [X] Refactor cryptographyUtils.js into smaller, more focused modules.
* [X] shamirUtils.js created; getKAndSecretShares and recomputeKey moved into it.
* [X] blsCryptoUtils.js created; generateBLSKeyPair, verifyShares, and calculateDecryptionShareForSubmission moved into it.
* [X] voteCryptoUtils.js created; encodeVoteToPoint, decodePointToVote, encryptVoteData, decryptVote moved into it.
* [X] Verify remaining functions (calculateNullifier, calculateDecryptionValue).
* [X] calculateNullifier(blsPrivateKey, voteIdentifier): (Reviewed - Existing implementation in cryptographyUtils.js aligns with plan: SHA256(sk_hex + domain_sep + sessionId_str))
* Input: User's BLS private key, a unique voteIdentifier (e.g., sessionId + voteMessageHash or similar, needs clear definition).
* Process: Implement as SHA256(blsPrivateKey + domainSeparator + voteIdentifier) or as per specific nullifier scheme defined for the project. Ensure domain separation.
* Output: bytes32 formatted string. (Ensure this is what VoteSession.castEncryptedVote expects, though CONTRACT_API.md does not explicitly show a nullifier parameter for castEncryptedVote. This task might need to be re-evaluated based on the actual castEncryptedVote implementation or if it's handled implicitly via ZK-proof).
* Note: The CONTRACT_API.md for castEncryptedVote shows parameters (bytes memory ciphertext, bytes memory g1r, bytes memory g2r, bytes[] memory alpha, uint256 threshold). A nullifier is not explicitly listed. This task might be based on an older understanding or a ZK-proof related input. If ZK-proofs handle unicity, this explicit nullifier calculation might not be needed for castEncryptedVote directly, but might be part of ZK-proof inputs.
* [ ] generateZkProof(inputs): (Deferred - Full ZKP implementation is out of current scope. Function in cryptographyUtils.js throws an error if called.)
* Currently a placeholder.
* For testing purposes, define a mock structure it should return, e.g., { proof: "mock_proof_bytes", publicSignals: ["mock_signal_1"] }.
* The actual inputs will depend on the ZK circuit design (e.g., private key, message, nullifier, merkle path).
* [X] calculateDecryptionValue(password, encryptedSkPayloadHex): (Refactored to use aesUtils.decryptWithPassword)
* Input: User's password, and the encrypted SK payload (0xSALT_IV_CIPHERTEXT).
* Process: Uses decryptWithPassword to get SK hex, then hashes it (SHA256) to produce the v_i value.
* Output: bytes32 formatted string, suitable for VoteSession.submitDecryptionValue()'s _value parameter.
* [X] JSDoc Comments & Completeness: Ensure all crypto operations used by services are robust, secure, and well-documented (All remaining functions in cryptographyUtils.js now have up-to-date JSDoc).
3.1.1. shamirUtils.js (New file for Shamir's Secret Sharing functions)
* [X] getKAndSecretShares / getKAndAlphas (Now getKAndSecretShares in shamirUtils.js): Reviewed. Refactored getKAndSecretShares to use Shamir's Secret Sharing for a scalar k. getKAndAlphas (for point-based alphas) removed as it was part of the previous problematic scheme for k reconstruction.
* [X] Threshold setup logic for scalar k (Shamir's) verified.
* [X] recomputeKey (Now in shamirUtils.js): Reviewed. Refactored to reconstruct scalar k from Shamir's shares using Lagrange interpolation, then derive AES key.
* [X] Key reconstruction (Lagrange for scalar shares) verified.
* [X] Subsequent AES key derivation (e.g., HKDF from reconstructed scalar k / SHA256 of k via importBigIntAsCryptoKey) verified.
3.1.2. blsCryptoUtils.js (New file for BLS-specific functions)
* [X] generateBLSKeyPair (Moved from cryptographyUtils.js): Review and verify key generation (public and private key formats).
* [X] calculateDecryptionShareForSubmission(privateKey, g1r_from_vote): (Moved from cryptographyUtils.js, refactored to expect privateKey as bigint)
* [X] Input: User's BLS private key (bigint), g1r point associated with the encrypted vote from VoteSession.sol.
* [X] Process: Perform scalar multiplication share = g1r * blsPrivateKey. This share is the cryptographic material submitted via VoteSession.submitDecryptionShare().
* [X] Output: bytes (serialized point) representation suitable for VoteSession.submitDecryptionShare()'s _share parameter.
* [X] verifyShares (Moved from cryptographyUtils.js): Review BLS pairing logic for correctness (Reviewed, logic e(share, G2_Base) === e(PK, g2^r) appears correct for verifying shares of the form (g1^r)^sk).
3.1.3. voteCryptoUtils.js (New file for vote-specific cryptographic operations)
* [X] encodeVoteToPoint (Moved from cryptographyUtils.js): Reviewed. Verified H2C logic using library defaults.
* [X] decodePointToVote (Moved from cryptographyUtils.js): Review and verify; must be inverse of encodeVoteToPoint.
* [X] encryptVoteData(voteData, aesKey, activeHolderBlsPublicKeysHex, voteEncryptionThreshold) (Moved from cryptographyUtils.js): Implemented. Depends on aesUtils.AESEncrypt and conversionUtils.hexToBytes.
* [X] decryptVote(encryptedData, aesKey) (Moved from cryptographyUtils.js): Review and verify AES-GCM decryption logic, IV handling.
3.2. aesUtils.js
* [X] Verify encryptWithPassword, decryptWithPassword (Implemented and integrated with cryptographyUtils.calculateDecryptionValue). (Password wrapper tests passing)
* [X] Verify encryptAES_GCM, decryptAES_GCM for general data encryption (Reviewed, 0x prefix handling standardized). (Direct tests passing)
* [X] Ensure secure and correct handling of salt, IV, and authentication tags (Reviewed: Salt generated for password-based encryption, IV handled by AES-GCM, Auth tags implicit in AES-GCM success/failure). (Covered by wrapper and direct tests)
* [X] Add JSDoc comments (Review and ensure completeness for all functions) (All functions have JSDoc).
* [X] Add tests for randomBytes, deriveKeyFromPassword, importBigIntAsCryptoKey. (All direct and indirect tests passing)
3.3. conversionUtils.js
* [X] Verify all hex/bytes/string/BigInt/UTF8 conversion functions (Existing functions hexToBytes, bytesToHex, bigIntToHex, stringToBigInt, bigIntTo32Bytes, pointToBigint reviewed and seem robust. UTF8 handled by TextEncoder/Decoder directly where needed).
* [ ] Add utilities for padding/unpadding hex strings to specific lengths if needed (Deferred until specific use case arises).
* [X] Add JSDoc comments (Existing functions are well-documented).
* [X] aesUtils.test.js:
* [X] Test encryptWithPassword for correct AES-256 encryption.
* [X] Test decryptWithPassword for correct AES-256 decryption.
* [X] Test encryptAES_GCM for correct AES-GCM encryption.
* [X] Test decryptAES_GCM for correct AES-GCM decryption.
* [X] Test randomBytes.
* [X] Test deriveKeyFromPassword.
* [X] Test importBigIntAsCryptoKey.
* [X] conversionUtils.test.js: (Completed)
* [X] Test hexToBytes for correct conversion of hex strings to bytes.
* [X] Test bytesToHex for correct conversion of bytes to hex strings.
* [X] Test bigIntToHex for correct conversion of BigInt to hex.
* [X] Test stringToBigInt for correct conversion of strings to BigInt.
* [X] Test bigIntTo32Bytes for correct conversion of BigInt to 32-byte arrays.
* [X] Test pointToBigint for correct conversion of point data to BigInt.
3.4. blsPointUtils.js, lagrangeUtils.js
* [X] Verify correctness of low-level BLS operations (blsPointUtils.js: genR, getG1R, getG2R, computePkRValue) and Lagrange interpolation logic (lagrangeUtils.js: modInverse, lagrangeBasis, lagrangeInterpolate), especially as used by shamirUtils.js and voteCryptoUtils.js (formerly cryptographyUtils.js). (All functions reviewed and appear correct).
* [X] Add JSDoc comments (Existing functions in both files are well-documented).
* [X] Consolidate FIELD_ORDER into this file and update dependent utils (shamirUtils.js, blsCryptoUtils.js, lagrangeUtils.js, conversionUtils.js, blsPointUtils.js).
3.5. constants.js
* [X] Define any shared constants, e.g., domain separator strings for hashing, specific curve parameters if not handled by libraries.
* [X] Consolidate FIELD_ORDER into this file and update dependent utils (shamirUtils.js, blsCryptoUtils.js, lagrangeUtils.js, conversionUtils.js, blsPointUtils.js).
This section covers services and middleware primarily focused on UI-level concerns, such as authentication state management and route protection.
4.1. Authentication State Management (frontend/authentication.js)
- File Purpose: Provides a reactive Vue store for managing client-side authentication state, including user information and JWT token handling.
- Existing Functionalities:
-
store.loggedIn: Reactive boolean indicating login status. -
store.user: Reactive object holding user information (e.g., email parsed from token). -
store.checkLoginStatus(): CheckslocalStoragefor a token, updatesloggedInanduserstate. -
store.setLoggedIn(token): Stores token inlocalStorageand updates state. -
store.logout(): Clears token fromlocalStorageand resets state. -
store.getToken(): Retrieves token fromlocalStorage. -
store.isAuthenticated(): ChecksloggedInstatus and token presence.
-
- Potential Review/Enhancements (Future Considerations):
- More robust error handling during token parsing.
- Consider periodic token validation with a backend endpoint if session expiry needs proactive handling.
- Ensure sensitive user information is not stored excessively in the reactive store if only email is needed.
4.2. Route Middleware (frontend/middleware/auth.js)
- File Purpose: Nuxt route middleware to protect specified routes, redirecting unauthenticated users to the login page.
- Existing Functionalities:
- Defines a list of
protectedRoutes. - For protected routes, checks for a token in
localStorage(client-side). - If no token, redirects to
/loginwith aredirectquery parameter for post-login navigation.
- Defines a list of
- Potential Review/Enhancements (Future Considerations):
- Explore making
protectedRoutesmore dynamic or configurable if the application grows significantly. - Consider integration with Vuex store or Pinia (if adopted) for checking authentication status instead of direct
localStorageaccess in middleware, for better centralization (though current approach is common for Nuxt middleware).
- Explore making
This section details the strategy for testing frontend services that interact with smart contracts. The primary approach is to test against a live Hardhat node with contracts deployed.
5.1. Core Principles & Setup
- Live Hardhat Node: All service tests involving contract interaction will run against a local Hardhat node. This ensures tests reflect actual contract behavior.
frontend/test/setup.js: This file is responsible for:- Connecting to the Hardhat RPC endpoint (e.g.,
http://127.0.0.1:8545). - Providing
ethers.jsprovider and signers (e.g.,deployerSigner,userSigner) for tests. - Exporting the
DEPLOYED_FACTORY_ADDRESSwhich is the entry point for deploying new session and registry instances for tests.
- Connecting to the Hardhat RPC endpoint (e.g.,
- Fresh Contract Instances: For most tests, new instances of
VoteSessionandParticipantRegistrycontracts will be deployed via theVoteSessionFactoryto ensure test isolation. Helper functions (likedeployRegistryTestSessionordeployVoteSessionTestContextin test files) should be used for this. blockchainProviderService: All contract-interacting services are now built uponblockchainProviderService. Test setups will need to:- Instantiate
blockchainProviderService. - Initialize it with the
providerfromfrontend/test/setup.js. - Use
setSigner()or pass signers to service methods as appropriate, utilizingdeployerSigneranduserSignerfromsetup.js.
- Instantiate
- Time Advancement: Utilize Hardhat's time-travel capabilities (
provider.send('evm_increaseTime', ...)andprovider.send('evm_mine', [])) for testing time-sensitive logic (e.g., registration windows, share submission periods, claim periods). - ABI Loading: Services load ABIs directly from
crypto-core/artifacts/. Ensure the Hardhat node has the corresponding contracts compiled and ABIs are up-to-date.
5.1.1. Test Time Management (Crucial for Period-Dependent Logic)
- Setting
startDatefor New Sessions:- When deploying
VoteSessioninstances for tests that require interaction during the registration period (or any open period), set thestartDate(and consequentlyregistrationEndDate) sufficiently in the future to allow test operations before the period closes.- Example:
const now = await ethers.provider.getBlock('latest').then(block => block.timestamp); const startDate = now + 3600; // 1 hour from now - Set
endDateandsharesCollectionEndDateappropriately relative to thisstartDate.
- Example:
- When deploying
- Advancing Time:
- For tests that require a specific period to be closed (e.g., testing "registration not open" scenarios), create the session with a future
startDateas above. Then, explicitly advance time past the relevant date using Hardhat's time manipulation tools.- Example:
await network.provider.send("evm_setNextBlockTimestamp", [startDate + 10]); await network.provider.send("evm_mine"); // Advance time to 10 seconds after startDate
- Example:
- Or using
time.increaseTo()from@nomicfoundation/hardhat-network-helpers:await time.increaseTo(startDate + 10);
- For tests that require a specific period to be closed (e.g., testing "registration not open" scenarios), create the session with a future
- Avoid Small Time Offsets: Do not rely on very small time offsets (e.g.,
startDate = now + 1) as test execution overhead or concurrent operations can easily lead to the period closing before intended. - Verify Period Status: For complex tests, consider adding assertions that explicitly check the status (e.g.,
await voteSession.isRegistrationOpen()) after time manipulations to ensure the contract is in the expected state before proceeding with the main test logic.
5.2. Service Test Files (frontend/test/contracts-tests/)
The following test files need to be created or refactored from existing ones. Each test suite should thoroughly test the public interface of its corresponding service. (Status Key: [P] All Passing, [F] Some Failing/Todo, [R] Reviewed/Refactored, [NR] Not Run/Needs Rerun)
- [P]
blockchainProviderService.test.js: (High priority - critical service)- Test provider/signer initialization and retrieval.
- Test network change detection (if feasible in Hardhat environment, otherwise unit test logic).
- Test
getContractInstance,readContract,sendTransactionagainst a simple mock/test contract deployed to Hardhat. - Test event handling helpers.
- Test utility functions (
hashMessage, Wei/Ether conversions). (Initial tests added, one minor failure in parseEther to fix) - Enhance error specificity for
getSessionAddresseswhen testing with a non-existent session ID (e.g., expect/Factory: Invalid session ID/ior similar specific message if thrown by service/contract).
- [P]
factoryService.test.js: (All tests passing)- Update to use
blockchainProviderService. - Test
createVoteSession(formerlycreateSessionPair):- Successful deployment and event emission.
- Parameter validation (e.g., invalid dates, options). (Basic params are valid, extensive validation not explicitly tested yet - remains as lower priority TODO)
- Correct addresses and
sessionIdreturned.
- Test
getDeployedSessionCount. - Test
getVoteSessionAddressByIndex. - Test
getSessionAddresses(formerlygetVoteSessionAddressById/getRegistryAddressById). - Test
getFactoryOwner. - Test
transferFactoryOwnership. (Marked as TODO in test file - Now implemented) - Detailed Sub-Tasks & Review Notes: (All addressed)
- Refactor timestamp generation in
createVoteSessiontest to useprovider.getBlock('latest').timestampinstead ofDate.now()for robustness. - Improve test independence:
getDeployedSessionCountandgetVoteSessionAddressByIndextests should set up their own session context rather than relying on previous tests. - Enhance error specificity for
getSessionAddresseswhen testing with a non-existent session ID (e.g., expect/Factory: Invalid session ID/ior similar specific message if thrown by service/contract).
- Refactor timestamp generation in
- Update to use
- [P]
registryParticipantService.test.js: (Partially complete, 3 tests marked .todo)- Setup: Deploy a new session pair using
factoryService. - Test
registerAsHolder:- Successful registration with correct deposit.
- Preventing double registration.
- Handling insufficient deposit.
- Interaction with
VoteSessionforrequiredDepositandisRegistrationOpen.
- Test
registerAsVoter. - Test
getParticipantInfo. - Test
getActiveHolders,getNumberOfActiveHolders,getHolderBlsKeys. - Test
getParticipantIndex. - Test
claimDeposit(requires time advancement) - (Marked as .todo in test file due to share submission complexities, depends onvoteSessionVotingService.test.jsresolution) - Test
hasClaimedDeposit. (Marked as .todo for 'true' case, tied toclaimDepositcomplexities) - Verify
RewardClaimedevent and updated user balance or thatrewardsOwedbecomes 0.
- Setup: Deploy a new session pair using
- [P]
registryFundService.test.js: (Partially implemented)- Setup: Deploy session, register participants. (Basic setup done, share submission & reward calc in progress for claim tests)
- Test
addRewardFunding. - Test
claimReward(requires time advancement, prior reward calculation) - (Initial tests implemented, more complex scenarios marked as TODO)- Successful claim after share submission and reward calculation.
- Prevent claiming twice.
- Prevent claiming if shares not submitted.
- Prevent claiming if rewards not calculated.
- Test
hasClaimedReward. (Basic cases covered, tied to claimReward tests) - Test
getTotalRewardPool. - Test
getRewardsOwed. (Basic cases covered) - Detailed Sub-Tasks & Review Notes:
- Refactor timestamp generation in
deploySessionForFundTestshelper to useprovider.getBlock('latest').timestamp. - Review and potentially remove redundant
blockchainProviderService.initialize(provider)call inbeforeEach. (Done, removed) - Import
ParticipantRegistry.jsonABI directly inaddRewardFundingtest for event parsing. - Ensure tests for
getRewardsOwedandhasClaimedReward(where participant is registered) handle potential timing issues withregisterAsHolderif the maintestContextsession registration period closes too fast (should be mitigated by updating the deploy helper). (Partially addressed by new helper timing) - Implement full test scenario for
claimReward: (Initial implementation done, complex scenarios pending)- Setup: Deploy session, register holder, fund rewards (
addRewardFunding). - Simulate share submission for the holder (e.g., direct call to
registry.recordShareSubmissionor viavoteSessionVotingService.submitDecryptionShare). (Attempted viavoteSessionVotingService) - Advance time past
sharesEndDate. - Admin calls
registryAdminService.calculateRewards. (Attempted, with TODO forisRewardCalculationPeriodActivecheck) - Advance time if there's a specific reward claim period (or ensure
ParticipantRegistry.rewardsCalculatedByAdminis true). - User calls
registryFundService.claimReward(). - Verify
RewardClaimedevent and updated user balance or thatrewardsOwedbecomes 0.
- Setup: Deploy session, register holder, fund rewards (
- Refactor timestamp generation in
- [P]
registryAdminService.test.js: (Refactored, needs run)- Setup: Deploy session. (Implicitly done by helper)
- Test
setVoteSessionContract. (Success and non-admin failure implemented) - [~] Test
calculateRewards(requires time advancement, share submissions, interaction withVoteSession.isRewardCalculationPeriodActive). (Enhanced implementation)- Simulate share submission for at least one participant (e.g., direct call to
registryContract.recordShareSubmission(sessionId, participantAddress)usingdeployerSigneror ensure a mockvoteSessionVotingService.submitDecryptionShareis successful prior) to make them eligible for rewards. (Done viavoteSessionVotingService) - Before calling
registryAdminService.calculateRewards, ensure the conditions are met forVoteSession.isRewardCalculationPeriodActive()to be true. This involves advancing time pastsharesEndDateand potentially checking this state viavoteSessionViewService. (Done) - The
registryAdminService.calculateRewardsmethod itself should ideally perform a pre-check forisRewardCalculationPeriodActive(from the associated VoteSession contract) and throw a service-level error if not active. The test should then also cover this scenario. (Test for inactive period added) - After a successful
calculateRewardscall (and if a participant was eligible), assert thatregistryFundService.getRewardsOwed(sessionId, participantAddress)returns a value greater than 0. (Done) - Verify that a subsequent call to
ParticipantRegistry.voteSession()(via a direct read or a view service if available) on Registry A now returns the address of Session B. (Event checked, direct read verification is a TODO within test)
- Simulate share submission for at least one participant (e.g., direct call to
- Test
getRegistryOwner. - Test
transferRegistryOwnership. - Detailed Sub-Tasks & Review Notes (for registryAdminService.test.js):
- Refactor timestamp generation in
deploySessionForAdminTestshelper (if specific to this file, or ensure general helper is used correctly) to useprovider.getBlock('latest').timestamp. - Review and potentially remove redundant
blockchainProviderService.initialize(provider)call inbeforeEach. (Removed) - Import
ParticipantRegistry.jsonABI directly intransferRegistryOwnershipandcalculateRewardstests for event parsing (instead offactoryService.getContractABI). - Enhance
calculateRewardstest: (All sub-points addressed)- Crucially, simulate share submission for at least one participant (e.g., direct call to
registryContract.recordShareSubmission(sessionId, participantAddress)usingdeployerSigneror ensure a mockvoteSessionVotingService.submitDecryptionShareis successful prior) to make them eligible for rewards. (Done viavoteSessionVotingService) - Before calling
registryAdminService.calculateRewards, ensure the conditions are met forVoteSession.isRewardCalculationPeriodActive()to be true. This involves advancing time pastsharesEndDateand potentially checking this state viavoteSessionViewService. (Done) - The
registryAdminService.calculateRewardsmethod itself should ideally perform a pre-check forisRewardCalculationPeriodActive(from the associated VoteSession contract) and throw a service-level error if not active. The test should then also cover this scenario. (Test for inactive period added) - After a successful
calculateRewardscall (and if a participant was eligible), assert thatregistryFundService.getRewardsOwed(sessionId, participantAddress)returns a value greater than 0. (Done)
- Crucially, simulate share submission for at least one participant (e.g., direct call to
- Implement the placeholder test for
setVoteSessionContract(if not already covered by factory deployment implicitly): (Implemented with success and non-admin cases)- Setup: Deploy a session pair (yields Registry A, linked to Session A).
- Deploy a new, separate
VoteSessioncontract instance (Session B). - As admin, call
registryAdminService.setVoteSessionContract(sessionIdForRegistryA, addressOfSessionB). - Verify any event emitted by
ParticipantRegistry.setVoteSessionContract. - Verify that a subsequent call to
ParticipantRegistry.voteSession()(via a direct read or a view service if available) on Registry A now returns the address of Session B. (Event checked, direct read verification is a TODO within test)
- Refactor timestamp generation in
- [P]
voteSessionAdminService.test.js:- Setup: Deploy session.
- Test
setDecryptionParameters. - Test
transferSessionOwnership. - Test
updateSessionStatus(may require time advancement to trigger status changes). - Test
triggerRewardCalculation. - Detailed Sub-Tasks & Review Notes: (All addressed)
- Refactor timestamp generation in
deploySessionForVotingTestshelper to useprovider.getBlock('latest').timestamp. - Review and potentially remove redundant
blockchainProviderService.initialize(provider)call inbeforeEach. - Import
VoteSession.jsonABI directly intransferSessionOwnershiptest for event parsing. - In
transferSessionOwnershiptest, uncomment and usevoteSessionViewService.getSessionOwner()to verify the new owner state after transfer. - Implement placeholder test for
setDecryptionParameters:- Setup: Register mock holders.
- Generate mock alpha shares (e.g.,
bytes32[]) and a thresholduint256. - Call
voteSessionAdminService.setDecryptionParameters(). - Verify event emission (e.g.,
DecryptionParametersSet) and usevoteSessionViewService.getDecryptionParameters()to check stored values.
- Implement placeholder test for
updateSessionStatus:- Test transitions through different session states by advancing time past
startDate,endDate,sharesEndDate. - Call
voteSessionAdminService.updateSessionStatus()after each time advancement. - Use
voteSessionViewService.getStatus()to verify thecurrentStatus.
- Test transitions through different session states by advancing time past
- Implement placeholder test for
triggerRewardCalculation(VoteSession context):- Setup: Cast votes, submit shares (can be mocked if focusing on admin action).
- Advance time past
sharesCollectionEndDate. - Call
voteSessionAdminService.triggerRewardCalculation(). - Verify
RewardsCalculationTriggeredevent fromVoteSession.sol.
- Refactor timestamp generation in
- [P]
voteSessionVotingService.test.js: (All tests passing)- Setup: Deploy session, register participants as holders. (Enhanced in beforeEach blocks)
- Test
castEncryptedVote:- Successful vote casting (aligned with contract signature).
- Preventing voting outside period or if not registered (specific error expected).
- Test
submitDecryptionShare:- Successful submission within
SharesCollectionOpenperiod (parameters aligned, vote cast prior). - Preventing submission outside period (specific error expected).
- Successful submission within
- Test
submitDecryptionValue:- Successful submission (vote & share submitted prior).
- Dependency on share submission (tested with another user, specific error expected).
- Detailed Sub-Tasks & Review Notes: (All addressed)
- Refactor timestamp generation in
deploySessionForVotingTestshelper to useprovider.getBlock('latest').timestamp. - Review and potentially remove redundant
blockchainProviderService.initialize(provider)call inbeforeEach. (Removed) -
castEncryptedVotetest:- Align test parameters with the actual parameters expected by
voteSessionVotingService.castEncryptedVotethat map to the contract signature (_ciphertext,_g1r,_g2r,_alpha,_threshold). - Update event parsing to match the actual
EncryptedVoteCastevent (sessionId,voter,voteIndex).
- Align test parameters with the actual parameters expected by
-
submitDecryptionSharetest:- Provide necessary
_voteIndexand_shareIndexparameters if the service method expects them to align with the contract. - Update event parsing to match the actual
DecryptionShareSubmittedevent (sessionId,holder,voteIndex,shareIndex).
- Provide necessary
-
submitDecryptionValuetest:- Update event parsing to match the actual
DecryptionValueSubmittedevent (sessionId,holder,index,value).
- Update event parsing to match the actual
- Import
VoteSession.jsonABI directly in the test file for event parsing, instead of usingfactoryService.getContractABI. (Done) - For period check tests (e.g.,
should prevent casting vote if not voting period), enhance error assertions to expect specific messages (e.g.,/Voting period is not active/i) if the service throws them. (Done)
- Refactor timestamp generation in
- [P]
voteSessionViewService.test.js:- Setup: Deploy session, potentially perform actions like registration/voting to populate data.
- Test all getter functions for accuracy:
-
isRegistrationOpen,getRequiredDeposit,isRewardCalculationPeriodActive,isDepositClaimPeriodActive. - [~]
getSessionDetails,getSessionInfo. (CONTRACT_API.md outdated.getSessionDetailscontract method missing, test commented out.getSessionInfoservice/test updated based on actual contract tuple.) -
getStatus. -
getEncryptedVote,getNumberOfVotes. -
getDecryptionShare,getNumberOfSubmittedShares(NowgetNumberOfDecryptionShares). -
getDecryptionParameters,getSubmittedValues. -
getSessionOwner,getSessionId,getParticipantRegistryAddress,getTitle,getDescription.
-
- Detailed Sub-Tasks & Review Notes: (All addressed)
- Refactor timestamp generation in
deploySessionForVoteViewTestshelper to useprovider.getBlock('latest').timestamp. - Review and potentially remove redundant
blockchainProviderService.initialize(provider)call inbeforeEach. - Refine
isRegistrationOpen should be false after endDatetest:- Ensure time is advanced past
sessionParams.startDate(which isregistrationEndDate) notsessionParams.endDateto correctly testisRegistrationOpenbecoming false. (Addressed) - Consider splitting period checks into distinct tests for each relevant function (
isVotingPeriodActive,isSharesCollectionPeriodActive, etc.) with appropriate time advancements. (Addressed by individual tests for period-dependent functions)
- Ensure time is advanced past
- Correct
castEncryptedVoteparameters in thebeforeEachfor 'Vote and Share Data Getters': Ensure parameters passed align with whatvoteSessionVotingService.castEncryptedVoteexpects and can map to the contract signature (_ciphertext,_g1r,_g2r,_alpha,_threshold). (Addressed) - Correct
getEncryptedVoteassertion: Changeexpect(vote).toBe(ethers.hexlify(mockVoteDataBytes))toexpect(vote.ciphertext).toBe(ethers.hexlify(mockVoteDataBytes))as the service method returns an object. (Addressed) - Implement placeholder
TODOtests forisRewardCalculationPeriodActive,isDepositClaimPeriodActive,getDecryptionShare,getNumberOfSubmittedShares,getDecryptionParameters, andgetSubmittedValueswith appropriate time advancements and setup. (All implemented) - Verified: VoteSession.sol does NOT have a public getSessionDetails() method, despite CONTRACT_API.md listing it. Service method requires refactoring/removal.
- Corrected data parsing in voteSessionViewService.getSessionInfo based on the actual 10-element tuple returned by VoteSession.sol's getSessionInfo() method (CONTRACT_API.md signature was outdated). Test assertions updated accordingly.
- Refactor timestamp generation in
This section details the testing strategy for pure JavaScript utilities and a revised approach to End-to-End (E2E) testing.
-
Setup Vitest Framework: Ensure Vitest is configured and running for the frontend.
-
Mocking Strategy: (This section is largely deprecated by the live Hardhat node testing for services)
- Smart Contract Interactions:
- Develop a robust strategy for mocking
ethers.js.Contractinteractions. This can be achieved by:- Creating mock JavaScript classes that implement the same interface as
ethers.js.Contract. - Using libraries like
jest-ethers(if compatible with Vitest) or manually mocking provider/signer calls. - Mock implementations should allow simulating successful calls, reverts with specific error messages, event emissions, and different return values.
- Creating mock JavaScript classes that implement the same interface as
- Consider a
MockBlockchainProviderthat can be injected into services during tests.
- Develop a robust strategy for mocking
- Data Management for Unit Tests: (This is relevant for utility tests)
- Create sets of mock data for function inputs (e.g., sample keys, ciphertexts, shares) to be used across utility tests.
- Store these directly in test files or in
frontend/test/fixtures/if they become extensive.
- Smart Contract Interactions:
-
Unit Tests for Utilities (
frontend/test/utils/) - (Deprioritized for now, focus on service integration tests first. Revisit for completion later.)- Create separate test files for each utility (e.g.,
cryptographyUtils.test.js,aesUtils.test.js,conversionUtils.test.js). These tests do not interact with the blockchain. -
cryptographyUtils.test.js: (Refactor to test remaining functions)- Test
calculateNullifierfor consistent output given same inputs. - Test
generateZkProof(mock) returns the defined error or placeholder. - Test
calculateDecryptionValuefor correct output format and AES interaction (tested with mock AES). - Include tests for edge cases and expected failures/error throwing for invalid inputs. (Partially done for calculateDecryptionValue)
- Test
-
shamirUtils.test.js: (Completed)- Test
getKAndSecretShareswith various thresholds and participant counts. Verify share properties. - Test
recomputeKeywith correct and incorrect sets of shares. Test AES key derivation.
- Test
- [P]
blsCryptoUtils.test.js: (New file)- Test
generateBLSKeyPairfor valid key pair generation. - Test
calculateDecryptionShareForSubmissionagainst expected outputs given mock inputs. - Test
verifySharesfor correct BLS pairing logic.
- Test
-
voteCryptoUtils.test.js: (New file)- Test
encodeVoteToPointfor consistent output given same inputs. - Test
decodePointToVotefor correct inverse mapping. - Test
encryptVoteDatafor correct AES-GCM encryption. - Test
decryptVotefor correct AES-GCM decryption.
- Test
-
aesUtils.test.js:- Test
encryptWithPasswordfor correct AES-256 encryption. - Test
decryptWithPasswordfor correct AES-256 decryption. - Test
encryptAES_GCMfor correct AES-GCM encryption. - Test
decryptAES_GCMfor correct AES-GCM decryption.
- Test
-
conversionUtils.test.js: (Completed)- Test
hexToBytesfor correct conversion of hex strings to bytes. - Test
bytesToHexfor correct conversion of bytes to hex strings. - Test
bigIntToHexfor correct conversion of BigInt to hex. - Test
stringToBigIntfor correct conversion of strings to BigInt. - Test
bigIntTo32Bytesfor correct conversion of BigInt to 32-byte arrays. - Test
pointToBigintfor correct conversion of point data to BigInt.
- Test
-
blsPointUtils.test.js:- Test
genRfor correct generation of R point. - Test
getG1Rfor correct generation of g1R point. - Test
getG2Rfor correct generation of g2R point. - Test
computePkRValuefor correct computation of PKR value.
- Test
-
lagrangeUtils.test.js:- Test
modInversefor correct modular inverse computation. - Test
lagrangeBasisfor correct Lagrange basis computation. - Test
lagrangeInterpolatefor correct Lagrange interpolation computation.
- Test
-
constants.test.js:- Test
FIELD_ORDERdefinition for correct curve parameter.
- Test
- Create separate test files for each utility (e.g.,