Skip to main content

Crate curvy_wasm

Crate curvy_wasm 

Source
Expand description

§curvy-wasm

wasm-bindgen exports for curvy-core: Poseidon, seed-backed and direct-scalar BabyJubjub signing, note encryption and commitments, Merkle trees, witness-input builders, and stealth addressing.

This crate is the JavaScript binding for core cryptography and tree operations. Groth16 proving is emitted as a separate WASM module by curvy-prover, allowing applications to ship only the functionality they use.

§Build

Use the workspace scripts rather than invoking wasm-bindgen manually:

scripts/build.sh wasm-nodejs
scripts/build.sh wasm-web
scripts/build.sh wasm-bundler
scripts/build.sh wasm-web-threads

Portable builds are single-threaded. The threaded browser build exports initThreadPool(n), requires cross-origin isolation, and uses n as this module’s worker-pool size.

The generated TypeScript declarations are the JavaScript API reference for each concrete output package. Rust item documentation on docs.rs/curvy-wasm describes the underlying wasm-bindgen exports and boundary validation.

Both signing profiles are supported:

JavaScript APIProfile
pubFromPrivateKey, signSeed-backed BLAKE-512/prune derivation
pubFromScalar, signWithScalar, verifyScalarSignatureChecked direct-scalar derivation

See the workspace guide for exact output directories, per-target requirements, and worker-budget configuration.

§Boundary conventions

Seed-backed and direct-scalar signing are both supported. Scalar crypto operations cross the boundary as decimal strings (and Vec<String> for points / signatures), matching every existing TS wire shape. Bulk Merkle operations instead use concatenated canonical 32-byte field elements so thousands of nodes stay inside wasm.

Field-element inputs reduce mod the field (fr_from_dec); raw 256-bit inputs (cipher key material, EdDSA message, sha256BigInt) are parsed without reduction (dec_to_biguint) - see the core crate for why.

Structs§

ScanMatch
One scan candidate: index into the input arrays + the derived keys.
ViewerMatch
One viewer_scan candidate: index + the derived spending PUBLIC key.
WasmCompletedShard
WasmFrontierAppend
WasmInclusionProof
WasmMerkleTree
Generic incremental Merkle tree with a reverse leaf index.
WasmNotesFrontier
Constant-space append frontier. It retains no leaves or witnesses and emits a shard descriptor only at an exact boundary.
WasmOrderedMerkleTree
Position-addressed tree for public vectors whose values may repeat.
WasmOwnedNoteWitness
WasmShardedNotesTree
Rust-owned sharded notes tree. Field elements cross this bulk boundary as canonical packed 32-byte big-endian values, avoiding one JS↔wasm call and one decimal-string allocation per Poseidon node.

Functions§

dbg_is_valid_bn254_point
dbg_is_valid_secp256k1_point
decrypt_amount_token_wasm
Decrypt (encryptedAmount, encryptedToken) -> [amount, token].
encrypt_amount_token_wasm
Encrypt (amount, token) -> [encryptedAmount, encryptedToken].
ephemeral_pub_key_wasm
Ephemeral public key R = scalar · Base8 as [x, y] (ephemeralPubKey).
get_meta
Public meta-keys [k, v, K, V] for the given private spend (k) / view (v) keys. Throws on degenerate keys (zero reduction).
new_meta
Fresh random meta-keys [k, v, K, V] = spend priv, view priv, spend pub, view pub.
note_id
id = Poseidon([ownerHash, amount, token]).
notes_shard_height
notes_shard_size
notes_tree_depth
Protocol notes-tree parameters, exported so JavaScript consumers read them from the core rather than hardcoding a second copy.
notes_tree_version
nullifier
nullifier = Poseidon([sharedSecret, pub.x, pub.y]).
owner_hash
ownerHash = Poseidon([pub.x, pub.y, sharedSecret]).
poseidon
Poseidon hash of 1..=16 decimal field elements.
pub_from_private_key
BabyJubjub public key [x, y] from a hex private key (pubFromPrivateKey).
pub_from_scalar
BabyJubJub public key [x, y] = scalar * Base8 from a canonical subgroup scalar. This path performs no seed hashing, pruning, or clamping.
scan
Recipient scan → the SPARSE list of tag-matching announcements, in input order: each match carries its index into the input arrays plus the derived one-time keys. Matches are CANDIDATES (1-byte viewTag ⇒ ~1/256 false positives) - the caller’s note-commitment recompute confirms ownership. Malformed / off-curve announcements are non-matches (skipped), never fatal; throws only on the caller’s own inputs (keys, mismatched array lengths).
send
Announce a payment to recipient (K, V)[r, R, viewTag, spendingPubKey]. Throws on malformed / off-curve recipient keys (an unspendable announcement must never be produced).
sha256_bigint
sha256BigInt: raw 256-bit decimal inputs -> decimal digest (no field reduction).
sign
EdDSA-Poseidon signature [R8.x, R8.y, S] (sign).
sign_with_scalar
Curvy-compatible direct-scalar signature [R8.x, R8.y, S] from a canonical BabyJubjub subgroup scalar and canonical BN254 field message.
verify_merkle_proof
Verify a packed conventional inclusion proof without reimplementing Poseidon/path ordering in JavaScript.
verify_scalar_signature
Verify a scalar-native Curvy signature. Malformed or non-canonical boundary values throw; a well-formed but invalid signature returns false.
version
viewer_scan
Viewer scan (view key v + recipient spend pub K, no spend key): the same sparse candidate list, spending PUBLIC keys only.