A deposit to a wormhole address is spent when its nullifier, poseidon2(poseidon2(salt || secret || transfer_count)), is in Wormhole::UsedNullifiers. Working out a wormhole balance means computing one for each deposit. That needs the address's secret, which never leaves WASM. wormholeNullifiers(mnemonic, password, account, branch, start, addresses, first, count) returns them for a run of addresses and a run of transfer counts. The BIP39 seed is stretched once per call; 40 addresses x 256 counts takes 194 ms in node. A call is capped at 100,000 nullifiers. This is ported onto qp-poseidon-core, not qp-wormhole-circuit, which would bring plonky2 into the WASM. The circuit crate is a dev-dependency only, as the reference: a known-answer test compares the port with Nullifier::from_preimage across secrets at and above the Goldilocks-prime limb edge and transfer counts across both 32-bit limbs, and asserts that enough cases were actually compared rather than skipped. The doc comments say to check nullifiers against a local copy of the spent set, never by key: exits publish nullifiers, so a lookup names the exit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
48 lines
1.9 KiB
TOML
48 lines
1.9 KiB
TOML
# Quantus post-quantum crypto, compiled to WASM for the browser.
|
|
#
|
|
# Deliberately a separate crate from `wasm-crypto` rather than more files inside
|
|
# it: that package is built with `nightly-2022-06-24` (see scripts/rust-version.sh)
|
|
# against a 2019-era dependency set, and the ML-DSA crates use inline `const {}`
|
|
# blocks that need Rust >= 1.79. The two cannot share a Cargo graph, and bumping
|
|
# the older one would mean rewriting upstream's sr25519/ed25519 build — which is
|
|
# the thing we most want to leave alone so rebases stay boring. See quantus/wasm#1.
|
|
|
|
[package]
|
|
authors = ["Quantus Network Developers <hello@quantus.com>"]
|
|
description = "WASM bindings to the Quantus chain's post-quantum crypto crates."
|
|
edition = "2021"
|
|
license = "Apache-2.0"
|
|
name = "quantus_crypto"
|
|
publish = false
|
|
repository = "https://git.lair.cafe/quantus/wasm"
|
|
resolver = "2"
|
|
version = "0.0.0"
|
|
|
|
[lib]
|
|
crate-type = ["cdylib", "rlib"]
|
|
|
|
[dependencies]
|
|
# The crates the runtime itself uses. Versions match quantus-apps/quantus_sdk's
|
|
# rust bridge, which is the other non-Rust consumer of exactly this surface.
|
|
qp-poseidon-core = "3.1.0"
|
|
qp-rusty-crystals-dilithium = { version = "4.1.1", default-features = false, features = ["ml-dsa-65", "ml-dsa-87"] }
|
|
qp-rusty-crystals-hdwallet = { version = "4.1.1", default-features = false, features = ["ml-dsa-65", "ml-dsa-87"] }
|
|
wasm-bindgen = "0.2"
|
|
|
|
[dev-dependencies]
|
|
# The chain's own nullifier, for known-answer tests only. It pulls in plonky2,
|
|
# which has no place in the shipped WASM: the port in rs/hdwallet.rs has to
|
|
# agree with it, and these tests are how that is shown rather than asserted.
|
|
qp-wormhole-circuit = { version = "=4.3.0", default-features = false, features = ["std"] }
|
|
qp-zk-circuits-common = { version = "=4.3.0" }
|
|
|
|
[profile.release]
|
|
codegen-units = 1
|
|
debug = false
|
|
debug-assertions = false
|
|
incremental = false
|
|
lto = true
|
|
opt-level = "z"
|
|
panic = "abort"
|
|
rpath = false
|