Skip to content

October 5–12, 2026

← Developer Updates

This update covers verified engineering progress during the previous seven days. Work in private repositories is summarized without private links or implementation identities; links to public changes appear directly beside the summaries they support.

Reworked Exu’s WebAssembly task runner around a bounded worker pool and same-origin worker files, and corrected task handling that a new test suite exposed.

  • Ran tasks in one bounded worker pool per module instead of a new worker for every task, which had cost 7-21 ms per small operation with no limit. (PR #22)
  • Loaded each sandbox worker from a module file instead of a Blob URL, so pages that allow only same-origin workers could load it without the wallet extension’s build-time workaround. (PR #21)
  • Corrected the task settlement, abort and module-source problems that the new test suite found, including an unhandled rejection that ended the process on Deno and Node. (PR #20)
  • Added 34 end-to-end test cases that checked the same expected behaviour on Deno, Bun, Chromium, Firefox and WebKit, covering settlement, aborts, fresh instances and memory copies. (PR #19)

Added tests across Dusk’s cryptography crates for the gaps that mutation testing found in their test suites.

Added a note to the BEP20 bridge guide that Dusk-to-BSC bridge processing was temporarily taking around 10 hours instead of one, as a security measure. (PR #156)

Strengthened Merkle tree validation, cut the Poseidon Merkle opening circuit by a third, and prepared dusk-merkle 0.6.0 and poseidon-merkle 0.11.0.

  • Bumped poseidon-merkle to 0.11.0 and finalized its changelog; 0.10.0 was withdrawn, so that number could not be reused. (PR #151)
  • Bumped dusk-merkle from 0.6.0-rc.0 to 0.6.0 and finalized its changelog. (PR #150)
  • Bounded the checks on archived trees so validating one recursed at most 63 levels, with byte-level tests for each check. (PR #148)
  • Rejected tree shapes whose capacity overflows at compile time, at no runtime cost. (PR #147)
  • Moved poseidon-merkle to PLONK 0.24 and Poseidon 0.44, cutting the opening gadget from 17,153 to 11,458 constraints at height 17. (PR #146)
  • Updated the curve library in dusk-merkle’s tests to 0.16, keeping the existing hash output. (PR #145)
  • Corrected the Merkle tests so each one checked what it claimed to check. (PR #141)

Hardened JubJub Schnorr signatures and multisignatures, moved the circuit gadgets to PLONK 0.24, and prepared version 0.7.0.

  • Bumped the version from 0.7.0-rc.0 to 0.7.0 and finalized its changelog. (PR #103)
  • Derived both multisignature round-one nonces from the signer’s key, the participant list and the message, and rejected round-one state reused for a different message or key list. (PR #101)
  • Wiped the buffers used to derive signing nonces and reduced nonces modulo the JubJub order so they spanned the full scalar range; signatures verified as before. (PR #100)
  • Added a test showing the fixed-generator gadgets reject non-canonical responses, which PLONK 0.24 constrains, and documented it; gate counts were unchanged. (PR #98)
  • Rejected the identity point for every public key, nonce point and generator in the three signature gadgets, matching native verification, for one gate per point. (PR #97)
  • Moved to PLONK 0.24 and its related libraries, with the signature gadgets taking keys and generators proven to be in the prime-order subgroup. (PR #96)
  • Rejected multisignatures whose participant key list repeats a key, in signing, share verification, combining and key aggregation. (PR #93)

Strengthened JubJub ElGamal encryption to require valid prime-order points for ciphertexts and circuit inputs, and prepared version 0.6.0 on PLONK 0.24.

  • Bumped the version to 0.6.0, finalized its changelog and corrected an older comparison link. (PR #43)
  • Documented that the 64-bit encryption and decryption circuit gadgets accept any valid prime-order point that encodes the value, which cannot change the encrypted value. (PR #42)
  • Constrained the nonce to a canonical JubJub scalar in the encryption gadgets when a custom generator is used, at a cost of 69 gates per call. (PR #41)
  • Made encryption return an error for a ciphertext part outside the prime-order subgroup or an identity shared key, matching the checks applied when an encryption is rebuilt from bytes. (PR #40)
  • Changed the zero-knowledge gadgets to take points proven to be in the prime-order subgroup, as PLONK 0.24 requires, and checked the mapped point when encrypting a 64-bit value. (PR #39)

Added error-returning Poseidon hash functions, cut 146 gates from each truncated hash output, and prepared version 0.44.0 on PLONK 0.24.

  • Bumped the version to 0.44.0 and finalized its changelog; 0.42.0 and 0.43.0 were withdrawn, so those numbers could not be reused. (PR #307)
  • Shortened hash outputs inside circuits with a purpose-built step, keeping the low 250 bits and using 146 fewer gates per output. (PR #306)
  • Moved to PLONK 0.24, SAFE 0.4 and curve library 0.16; truncated hash gadget outputs became bound to the hash, so circuits using them needed new verifier keys. (PR #305)
  • Added error-returning versions of the hash finalize and digest functions. (PR #301)

Hardened PLONK’s handling of archived proofs, keys and compressed circuits, made fixed-base multiplication take the same steps for every scalar, and prepared version 0.24.0.

  • Computed the two independent pairing inputs of proof verification in parallel on builds with the standard library, while other builds kept the sequential path; the verification maths, proof format and API were unchanged. (PR #1000)

  • Bumped the version to 0.24.0 and finalized its changelog; 0.23.0 was withdrawn, so that number could not be reused. (PR #1013)

  • Moved to curve library 0.16 and JubJub 0.16, keeping the minus-one constant identical and pinning it with a test. (PR #1012)

  • Corrected a soundness-test check so it also detected circuits that started with all-zero gates. (PR #1009)

  • Rejected compressed circuit files with extra bytes after the compressed data. (PR #1007)

  • Made code-quality warnings fail CI, including checks for the embedded and WebAssembly contract builds. (PR #1002)

  • Removed the msgpacker library from compressed-circuit encoding, leaving PLONK with one fewer outside dependency. (PR #1005)

  • Rewrote fixed-base multiplication so its steps did not vary with the scalar’s bits; witnesses, circuits and proofs were unchanged. (PR #993)

  • Listed the prover key’s fifteen value pairs once and generated the save, load, size and check code from that list, replacing seven hand-written copies. (PR #999)

  • Documented a step in PLONK’s polynomial division and added a test at the edge of its evaluation domain. (PR #997)

  • Applied the byte decoders’ rules to checked archive decoding, so archived proofs and keys with non-canonical or out-of-subgroup values were rejected; the archive layout was unchanged. (PR #985)

  • Made the custom-gate method private to the library, because a gate appended from outside set no selector and enforced nothing. (PR #990)

Standardized the changelog guidance across Dusk’s open-source crates, so entries list only changes visible to a crate’s users and follow one format.

Updated SAFE’s test dependencies to curve library 0.16 and JubJub 0.16 and bumped the version to 0.4.0; the library code was unchanged. (PR #42)

Updated the BLS signature library to curve library 0.16, redacted secret keys from debug output, and prepared version 0.7.0.

  • Bumped the version to 0.7.0 and finalized its changelog; it is a breaking version because its public API exposes curve library 0.16 types. (PR #54)
  • Moved to curve library 0.16, selecting the existing hashing construction, so signatures were unchanged. (PR #53)
  • Replaced the debug output of a secret key with a fixed redacted label, so a logged key showed that label instead of the secret value. (PR #51)

Hardened the JubJub curve library with stricter decoding, removed a way to write non-canonical values, and prepared version 0.16.0 on curve library 0.16.

  • Bumped the version to 0.16.0 and finalized its changelog; the curve library update and the indexing removal made it a breaking version. (PR #187)
  • Added opt-in strict decoding of archived points, checking canonical encoding and, for subgroup points, subgroup membership. (PR #172)
  • Removed mutable indexing of scalars, which let any caller overwrite their internals with non-canonical values; read-only indexing was kept. (PR #186)
  • Bounded hex decoding of points and scalars to their fixed size, checking the length first; a new test showed a 1 MiB string was rejected without being copied. (PR #185)
  • Moved to curve library 0.16 and added a regression test for canonical archive values; arithmetic was unchanged. (PR #175)
  • Added clippy checks to CI, including the no_std and WebAssembly builds, fixed the warnings they found, and moved the lint exceptions for upstream code onto the exact items. (PR #182, PR #180)

Hardened the BLS12-381 curve library to keep scalars canonical and return zero instead of panicking on invalid pairings, and prepared version 0.16.0.

  • Bumped the version to 0.16.0 and finalized its changelog; the scalar change made it a breaking version. (PR #201)
  • Changed the final pairing step to return zero instead of panicking for points outside the prime-order subgroup; results for valid inputs were unchanged. (PR #199)
  • Made the internal parts of a scalar private to the library, so outside code could not build a scalar from unchecked values. (PR #200)

Strengthened bridge history checks for more dependable cross-chain accounting.

Improved how search engines index Dusk website articles.

Expanded Piecrust contract-call and event controls so the node can refuse unsupported large calls early and price emitted event data separately.

  • Added a check that tells the node whether a contract uses the newer host-backed interface, so an oversized call to an older contract can be refused before any fee is spent; an unreleased call mechanism it replaces was removed.
  • Added configurable per-byte pricing for contract events and optional limits on the events each call may emit, so a node can price event data separately from stored data and fail an oversized emission during execution.

Optimized private-transaction proof verification in Rusk and strengthened node responsiveness under heavy load.

  • Cached the four Phoenix proof verifiers that never change, so each private-transaction check reused them instead of rebuilding them, which cut the time each check took.

Strengthened wallet cache consistency checks for more dependable balances.

Added large contract calls to the Rusk protocol, so one transaction can carry up to 320 KiB of call arguments to contracts on the newer interface.

  • Added large calls: a call too big for the transfer contract’s buffer is signed over a compact message and delivered to its target. The schedule keeps the feature off on mainnet and testnet and on for local development networks.

← Back to Developer Updates