feat: add zk-inputs-wasm crate [skip-line-limit]#905
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
|
❌ License Header Check Failed Some files are missing the required SPDX license header. Please add the following header to the beginning of all You can run Or run |
WalkthroughRestructures the CRISP ZK inputs generator into a core Rust crate ( Changes
Sequence Diagram(s)sequenceDiagram
participant JS as JavaScript/Test
participant WASM as zk-inputs-wasm
participant Core as zk-inputs (Rust)
participant Crypto as BFV Engine
JS->>WASM: withDefaults() or new(...)
WASM->>Core: new(degree, plaintext_modulus, moduli)
Core-->>WASM: ZKInputsGenerator (core)
rect rgb(220,240,250)
note right of JS: Generate public key
JS->>WASM: generatePublicKey()
WASM->>Core: generate_public_key()
Core->>Crypto: BFV keygen
Crypto-->>Core: Vec<u8>
Core-->>WASM: Result<Vec<u8>>
WASM-->>JS: Result<Vec<u8>>
end
rect rgb(240,230,220)
note right of JS: Generate inputs / encrypt
JS->>WASM: generateInputs(prev_ct, pubkey, vote)
WASM->>Core: generate_inputs(&[u8], &[u8], u8)
Core->>Crypto: process bytes -> inputs JSON
Crypto-->>Core: String (JSON)
Core-->>WASM: Result<String>
WASM->>JS: Result<JsValue>
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
examples/CRISP/crates/zk-inputs/src/lib.rs (2)
38-48: Avoid panic on invalid BFV parameters (public API) — provide a fallible constructor
build_arc().unwrap()will panic on invalid params. From JS this aborts the WASM module. Expose a non‑panicking constructor and keepnew()as a thin wrapper if you want a convenience API.Apply:
pub struct ZKInputsGenerator { bfv_params: Arc<BfvParameters>, } -impl ZKInputsGenerator { - /// Creates a new generator with the specified BFV parameters. - pub fn new(degree: usize, plaintext_modulus: u64, moduli: &[u64]) -> Self { - let bfv_params = BfvParametersBuilder::new() - .set_degree(degree) - .set_plaintext_modulus(plaintext_modulus) - .set_moduli(moduli) - .build_arc() - .unwrap(); - Self { bfv_params } - } +impl ZKInputsGenerator { + /// Non-panicking constructor. + pub fn try_new(degree: usize, plaintext_modulus: u64, moduli: &[u64]) -> Result<Self> { + let bfv_params = BfvParametersBuilder::new() + .set_degree(degree) + .set_plaintext_modulus(plaintext_modulus) + .set_moduli(moduli) + .build_arc() + .with_context(|| "Invalid BFV parameters")?; + Ok(Self { bfv_params }) + } + + /// Convenience constructor that panics on invalid parameters (kept for back-compat). + pub fn new(degree: usize, plaintext_modulus: u64, moduli: &[u64]) -> Self { + Self::try_new(degree, plaintext_modulus, moduli).expect("Invalid BFV parameters") + }
74-82: Validatevote∈ {0,1} instead of silently coercingSilently mapping any non‑1 to 0 can hide caller bugs. Return an error for invalid values.
pub fn generate_inputs( @@ - // Set vote value (0 or 1) in the first coefficient. - message_data[0] = if vote == 1 { 1 } else { 0 }; + // Enforce {0,1} vote domain. + if vote > 1 { + eyre::bail!("vote must be 0 or 1"); + } + message_data[0] = vote as u64; @@ pub fn encrypt_vote(&self, public_key: &[u8], vote: u8) -> Result<Vec<u8>> { @@ - // Set vote value (0 or 1) in the first coefficient. - message_data[0] = if vote == 1 { 1 } else { 0 }; + if vote > 1 { + eyre::bail!("vote must be 0 or 1"); + } + message_data[0] = vote as u64;Consider adding a small negative test asserting error on
vote=2. Based on learningsAlso applies to: 124-131
🧹 Nitpick comments (8)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs (2)
47-67: Use JsError and preserve JSON parse context for better JS ergonomicsMap Rust errors to
JsErrorso callers get proper stack/name, and include parse error details. Functionally identical, but improves DX.Apply:
- pub fn generate_inputs( + pub fn generate_inputs( &self, prev_ciphertext: &[u8], public_key: &[u8], vote: u8, ) -> Result<JsValue, JsValue> { - match self - .generator - .generate_inputs(prev_ciphertext, public_key, vote) - { - Ok(inputs_json) => { - // Parse the JSON string and return as JsValue. - match js_sys::JSON::parse(&inputs_json) { - Ok(js_value) => Ok(js_value), - Err(_) => Err(JsValue::from_str("Failed to parse inputs JSON")), - } - } - Err(e) => Err(JsValue::from_str(&e.to_string())), - } + use wasm_bindgen::JsError; + let inputs_json = self + .generator + .generate_inputs(prev_ciphertext, public_key, vote) + .map_err(|e| JsError::new(&e.to_string()))?; + js_sys::JSON::parse(&inputs_json) + .map_err(|e| JsError::new(&format!("Failed to parse inputs JSON: {e:?}")).into()) }
69-76: Consistent error mapping across bindingsReturn
JsErrorinstead of stringlyJsValueforgeneratePublicKeyandencryptVote.- pub fn generate_public_key(&self) -> Result<Vec<u8>, JsValue> { - match self.generator.generate_public_key() { - Ok(public_key_bytes) => Ok(public_key_bytes), - Err(e) => Err(JsValue::from_str(&e.to_string())), - } - } + pub fn generate_public_key(&self) -> Result<Vec<u8>, JsValue> { + use wasm_bindgen::JsError; + self.generator + .generate_public_key() + .map_err(|e| JsError::new(&e.to_string()).into()) + } @@ - pub fn encrypt_vote(&self, public_key: &[u8], vote: u8) -> Result<Vec<u8>, JsValue> { - match self.generator.encrypt_vote(public_key, vote) { - Ok(ciphertext_bytes) => Ok(ciphertext_bytes), - Err(e) => Err(JsValue::from_str(&e.to_string())), - } - } + pub fn encrypt_vote(&self, public_key: &[u8], vote: u8) -> Result<Vec<u8>, JsValue> { + use wasm_bindgen::JsError; + self.generator + .encrypt_vote(public_key, vote) + .map_err(|e| JsError::new(&e.to_string()).into()) + }Also applies to: 79-85
examples/CRISP/crates/zk-inputs/src/lib.rs (2)
50-53: Mirror fallible ctor for defaults or guarantee non‑panic
with_defaults()relies onnew(). If defaults can never fail, fine; otherwise prefer the fallible variant.Option A (safe):
- pub fn with_defaults() -> Self { - Self::new(DEFAULT_DEGREE, DEFAULT_PLAINTEXT_MODULUS, &DEFAULT_MODULI) - } + pub fn try_with_defaults() -> Result<Self> { + Self::try_new(DEFAULT_DEGREE, DEFAULT_PLAINTEXT_MODULUS, &DEFAULT_MODULI) + }Option B (documented guarantee): keep as-is but add a
/// # Panicsdoc note stating defaults are known-valid.
166-207: Tests look solid; consider one negative case for invalid voteAdd a test that
generate_inputs(..., 2)andencrypt_vote(..., 2)returnErrafter the validation above. Keeps behavior explicit.examples/CRISP/crates/zk-inputs-wasm/Cargo.toml (2)
9-11: Addrlibfor tests andpublish = falseto prevent accidental release (example crate)Not required, but improves DX and safety.
[lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "rlib"] + +[package] +# ... +publish = falseOptional (if using wasm-pack): add
[package.metadata.wasm-pack.profile.release] wasm-opt = ['-Os']
12-18: Version alignment tipKeep
wasm-bindgen,wasm-bindgen-test,js-sys, andweb-syson compatible minor versions to avoid linker mismatches. Current specs look fine; pinning exact minors can reduce CI flakes.examples/CRISP/packages/crisp-sdk/tests/vote.test.ts (2)
7-12: Remove unused imports
fs,path, andbeforeAllare unused after the change.-import fs from 'fs/promises' -import path from 'path' -import { describe, it, expect, beforeAll } from 'vitest' +import { describe, it, expect } from 'vitest'
122-124: Initialize WASM-backed generator in a setup hook to avoid early evaluationCreating the generator at describe scope can run before WASM is fully initialized in some runners. Initialize once in a setup hook.
- let zkInputsGenerator = ZKInputsGenerator.withDefaults() - let publicKey = zkInputsGenerator.generatePublicKey() + let zkInputsGenerator: ZKInputsGenerator + let publicKey: Uint8Array + + // If your package requires explicit async init, call it here and await. + // e.g., const init = (await import('@enclave/crisp-zk-inputs/init.js')).default; await init(); + beforeAll(() => { + zkInputsGenerator = ZKInputsGenerator.withDefaults() + publicKey = zkInputsGenerator.generatePublicKey() + })Please run the test once with
--runInBandto confirm no flakiness due to WASM init order.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
examples/CRISP/Cargo.lockis excluded by!**/*.lockexamples/CRISP/packages/crisp-sdk/tests/fixtures/pubkey.binis excluded by!**/*.binpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (16)
.vscode/settings.json(1 hunks)Cargo.toml(0 hunks)examples/CRISP/Cargo.toml(1 hunks)examples/CRISP/crates/zk-inputs-wasm/Cargo.toml(1 hunks)examples/CRISP/crates/zk-inputs-wasm/src/lib.rs(1 hunks)examples/CRISP/crates/zk-inputs/Cargo.toml(1 hunks)examples/CRISP/crates/zk-inputs/src/lib.rs(16 hunks)examples/CRISP/crates/zk-inputs/src/serialization.rs(6 hunks)examples/CRISP/docker-compose.yaml(2 hunks)examples/CRISP/package.json(1 hunks)examples/CRISP/packages/crisp-contracts/deployed_contracts.json(1 hunks)examples/CRISP/packages/crisp-sdk/package.json(2 hunks)examples/CRISP/packages/crisp-sdk/tests/vote.test.ts(2 hunks)examples/CRISP/packages/crisp-sdk/vite.config.ts(1 hunks)examples/CRISP/server/Dockerfile(2 hunks)pnpm-workspace.yaml(1 hunks)
💤 Files with no reviewable changes (1)
- Cargo.toml
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-25T10:28:56.174Z
Learnt from: ctrlc03
PR: gnosisguild/enclave#657
File: Cargo.toml:32-34
Timestamp: 2025-08-25T10:28:56.174Z
Learning: The examples/CRISP directory has its own Cargo.toml workspace configuration with members like "server", "wasm-crypto", "program/core", "program/client", etc. The root workspace intentionally excludes "examples/CRISP/server", "examples/CRISP/program", and "examples/CRISP/wasm-crypto" to prevent double workspace membership, which is the correct approach for self-contained example workspaces.
Applied to files:
examples/CRISP/Cargo.tomlexamples/CRISP/crates/zk-inputs-wasm/Cargo.tomlexamples/CRISP/docker-compose.yamlexamples/CRISP/server/Dockerfilepnpm-workspace.yaml
📚 Learning: 2024-10-03T23:02:41.732Z
Learnt from: ryardley
PR: gnosisguild/enclave#133
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:137-139
Timestamp: 2024-10-03T23:02:41.732Z
Learning: In `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, using the same RNG instance `rng_test` for generating multiple key shares without advancing its state is acceptable.
Applied to files:
examples/CRISP/crates/zk-inputs/src/lib.rs
🧬 Code graph analysis (2)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs (1)
examples/CRISP/crates/zk-inputs/src/lib.rs (5)
new(40-48)with_defaults(51-53)generate_inputs(64-119)generate_public_key(151-158)encrypt_vote(129-145)
examples/CRISP/crates/zk-inputs/src/lib.rs (2)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs (5)
new(30-37)with_defaults(41-44)generate_inputs(48-67)encrypt_vote(80-85)generate_public_key(71-76)examples/CRISP/crates/zk-inputs/src/ciphertext_addition.rs (1)
new(42-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build_sdk
- GitHub Check: test_net
- GitHub Check: integration_prebuild
- GitHub Check: rust_unit
- GitHub Check: test_contracts
- GitHub Check: build_enclave_cli
- GitHub Check: build_e3_support_risc0
- GitHub Check: rust_integration
- GitHub Check: Build & Push Image
- GitHub Check: Build & Push Image
🔇 Additional comments (13)
examples/CRISP/packages/crisp-contracts/deployed_contracts.json (1)
85-162: Remove the imageId verification request; clarify that localhost addresses require fresh deployment scripts.The
imageIdis a cryptographic hash of the ELF file required for verification, and containerized builds ensure the same ImageID across all environments. This is correct and intentional—no changes needed.However, local blockchains do not persist state across runs; you must re-deploy contracts after restarting. The stored localhost addresses in this file will become stale each time the local blockchain is restarted. Ensure your deployment scripts regenerate these addresses dynamically rather than relying on static values from this config file.
examples/CRISP/docker-compose.yaml (1)
16-16: LGTM! Volume rename aligns with crate restructuring.The volume name change from
generator-targettozk-inputs-targetis correct and consistent between the volume mount and declaration.Also applies to: 44-44
examples/CRISP/server/Dockerfile (1)
34-34: LGTM! Dockerfile paths updated correctly.The COPY commands in both the chef and planner stages now correctly reference the new
zk-inputscrate path, aligning with the workspace restructuring.Also applies to: 55-55
examples/CRISP/package.json (1)
23-24: LGTM! WASM build script properly configured.The new
build:wasmscript correctly configures wasm-pack to build the zk-inputs-wasm crate with the appropriate scope and output directory that aligns with the workspace structure.pnpm-workspace.yaml (1)
8-8: LGTM! Workspace package added correctly.The new workspace path for
crisp-zk-inputsaligns with the wasm-pack output directory configured in the build script.examples/CRISP/crates/zk-inputs/Cargo.toml (1)
2-2: LGTM! Package name simplified appropriately.The package name change from
crisp-zk-inputstozk-inputsis consistent with the crate restructuring and simplifies the naming convention..vscode/settings.json (1)
4-4: LGTM! VSCode settings updated for new crate structure.The rust-analyzer linked projects correctly reference the new
zk-inputsandzk-inputs-wasmcrates, replacing the old wasm-crypto reference. The array formatting changes are also appropriate.Also applies to: 7-7, 13-14
examples/CRISP/packages/crisp-sdk/vite.config.ts (1)
1-15: LGTM! Vite configuration properly set up for WASM support.The new configuration correctly enables WASM support through the vite-plugin-wasm and sets the test environment to 'node', which is appropriate for the SDK testing workflow.
examples/CRISP/crates/zk-inputs/src/serialization.rs (1)
20-20: LGTM! Type rename applied consistently.The rename from
CrispZKInputstoZKInputsis applied consistently throughout the struct definition, function signatures, and documentation. The refactoring is clean with no logic changes.Also applies to: 57-57, 161-161, 258-258
examples/CRISP/Cargo.toml (1)
6-7: No workspace membership issues detectedVerified:
crates/zk-inputsandcrates/zk-inputs-wasmare only listed in theexamples/CRISP/Cargo.tomlworkspace and are not duplicated in the root workspace. These crates remain properly isolated with no double membership or feature unification conflicts.examples/CRISP/packages/crisp-sdk/package.json (3)
22-23: Verify build script integration and WASM output location.The build script now chains
build:wasm && tsc, which assumes the WASM build output from../../is accessible to TypeScript compilation. Clarify:
- Where does
pnpm -C ../../ build:wasmplace the generated WASM and binding files?- Are they configured to be importable from this package's source code (e.g., via paths in
tsconfig.jsonor vite configuration)?- Does the build process clean stale WASM artifacts before regenerating?
38-39: Verify Vite configuration for WASM support.
viteandvite-plugin-wasmare added as dev dependencies, suggesting this package uses Vite for bundling. However, the provided context does not include avite.config.ts(orvite.config.js) file. Verify:
- Does a Vite configuration file exist in this package? If so, does it reference
vite-plugin-wasm?- If not, is the Vite config inherited from a parent workspace configuration?
- Are TypeScript paths configured to resolve WASM imports correctly?
43-43: Verify the new dependency is actually used.
@enclave/crisp-zk-inputsis declared as a dependency, but it's unclear from this file whether it's actually imported and used in the source code. Verify:
- Is this package imported in any source files (e.g.,
src/index.ts)?- If so, confirm that the API (e.g.,
ZKInputsGenerator, methods likegeneratePublicKey) matches the new WASM bindings exposed by the crate.- Check for any circular dependencies or import path issues between this package and
@enclave/crisp-zk-inputs.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
examples/CRISP/crates/zk-inputs/src/lib.rs (2)
76-83: Reject invalid vote values instead of coercingCurrently, any non‑1 becomes 0. This is silent data corruption for out‑of‑range inputs.
- // Set vote value (0 or 1) in the first coefficient. - message_data[0] = if vote == 1 { 1 } else { 0 }; + // Validate vote ∈ {0,1}. + if vote > 1 { + return Err(eyre::eyre!("vote must be 0 or 1")); + } + // Set vote value (0 or 1) in the first coefficient. + message_data[0] = if vote == 1 { 1 } else { 0 };Apply the same check in encrypt_vote:
- // Set vote value (0 or 1) in the first coefficient. - message_data[0] = if vote == 1 { 1 } else { 0 }; + if vote > 1 { + return Err(eyre::eyre!("vote must be 0 or 1")); + } + message_data[0] = if vote == 1 { 1 } else { 0 };Also applies to: 133-139
20-20: Use OsRng for cryptographic randomnessPrefer OsRng for keygen and encryption to align with cryptographic best practices across targets (including WASM via Web Crypto).
-use rand::thread_rng; +use rand::rngs::OsRng; ... - let (ct, u_rns, e0_rns, e1_rns) = pk - .try_encrypt_extended(&pt, &mut thread_rng()) + let (ct, u_rns, e0_rns, e1_rns) = pk + .try_encrypt_extended(&pt, &mut OsRng) .with_context(|| "Failed to encrypt plaintext")?; ... - let (ct, _u_rns, _e0_rns, _e1_rns) = pk - .try_encrypt_extended(&pt, &mut thread_rng()) + let (ct, _u_rns, _e0_rns, _e1_rns) = pk + .try_encrypt_extended(&pt, &mut OsRng) .with_context(|| "Failed to encrypt plaintext")?; ... - let mut rng = thread_rng(); + let mut rng = OsRng; let sk = SecretKey::random(&self.bfv_params, &mut rng); let pk = PublicKey::new(&sk, &mut rng);Also applies to: 85-87, 140-142, 153-156
♻️ Duplicate comments (1)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs (1)
29-38: Resolved: ctor no longer panics (now returns Result) — good changeSwitching to core’s Result-returning constructor prevents WASM aborts on invalid params. This addresses the earlier concern.
🧹 Nitpick comments (5)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs (4)
35-37: Return JsError for proper JS exceptionsMap errors to JsError so callers get real Error objects (message/stack) instead of raw strings.
- let generator = CoreZKInputsGenerator::new(degree, plaintext_modulus, &moduli) - .map_err(|e| JsValue::from_str(&e.to_string()))?; + use wasm_bindgen::JsError; + let generator = CoreZKInputsGenerator::new(degree, plaintext_modulus, &moduli) + .map_err(|e| JsError::new(&e.to_string()))?; ... - let generator = CoreZKInputsGenerator::with_defaults() - .map_err(|e| JsValue::from_str(&e.to_string()))?; + let generator = CoreZKInputsGenerator::with_defaults() + .map_err(|e| JsError::new(&e.to_string()))?; ... - Err(e) => Err(JsValue::from_str(&e.to_string())), + Err(e) => Err(JsError::new(&e.to_string()).into()), ... - Err(e) => Err(JsValue::from_str(&e.to_string())), + Err(e) => Err(JsError::new(&e.to_string()).into()), ... - Err(e) => Err(JsValue::from_str(&e.to_string())), + Err(e) => Err(JsError::new(&e.to_string()).into()),Also applies to: 42-46, 67-68, 74-77, 83-86
31-34: Beware: Vec from JS requires BigInt/BigUint64ArrayJS must pass bigint[] (or BigUint64Array). Many apps still pass number[]. Consider:
- Documenting bigint[] requirement in JSDoc/README, or
- Providing an alt ctor accepting string[] (hex/dec) or Uint32Array[] pairs, or
- Accepting js_sys::BigUint64Array and converting internally.
Do your TS consumers already pass bigint[]? If not, I can draft a
newWithModuliStrings(moduli: string[])helper.
11-11: Remove unnecessary crate import
use js_sys;is redundant since you referencejs_sys::JSONwith a fully-qualified path.-use js_sys;
61-65: Preserve JSON parse error detailsSurface the underlying parse error to aid debugging.
- Err(_) => Err(JsValue::from_str("Failed to parse inputs JSON")), + Err(e) => { + let msg = js_sys::JSON::stringify(&e) + .ok() + .and_then(|s| s.as_string()) + .unwrap_or_else(|| "Failed to parse inputs JSON".to_string()); + Err(wasm_bindgen::JsError::new(&msg).into()) + },examples/CRISP/crates/zk-inputs/src/lib.rs (1)
63-69: Consider returning structured JSON instead of StringIf consumers are primarily JS/WASM, returning serde_json::Value avoids stringify→parse roundtrips and preserves types. The WASM layer can pass it directly via serde_wasm_bindgen.
If acceptable, I can provide a follow‑up patch switching generate_inputs to Result<serde_json::Value> and updating the WASM binding accordingly.
Also applies to: 118-119
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs(1 hunks)examples/CRISP/crates/zk-inputs/src/lib.rs(15 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
examples/CRISP/crates/zk-inputs/src/lib.rs (2)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs (5)
new(30-38)with_defaults(42-46)generate_inputs(50-69)encrypt_vote(82-87)generate_public_key(73-78)templates/default/program/src/lib.rs (1)
test(37-72)
examples/CRISP/crates/zk-inputs-wasm/src/lib.rs (1)
examples/CRISP/crates/zk-inputs/src/lib.rs (5)
new(40-48)with_defaults(51-53)generate_inputs(64-119)generate_public_key(151-158)encrypt_vote(129-145)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: build_sdk
- GitHub Check: build_enclave_cli
- GitHub Check: rust_unit
- GitHub Check: integration_prebuild
- GitHub Check: test_net
- GitHub Check: rust_integration
- GitHub Check: test_contracts
- GitHub Check: build_e3_support_risc0
- GitHub Check: Build & Push Image
- GitHub Check: Build & Push Image
🔇 Additional comments (1)
examples/CRISP/crates/zk-inputs/src/lib.rs (1)
170-187: Tests: great coverage; add a negative test for vote > 1 once validation landsAfter adding vote validation, assert errors for vote=2 in both generate_inputs and encrypt_vote.
Would you like me to append those two negative tests now?
Also applies to: 189-207, 210-226, 262-277, 281-297, 299-308, 311-335, 339-364
Adds a new
zk-inputs-wasmcrate that exposes the CRISP ZK inputs generator to JavaScript viawasm-bindgen, and updates CRISP workspace and package settings to build and consume the package.Summary by CodeRabbit
New Features
Refactor
Tests