From the review docs/review-2026-09-26.md. No API change.
indcpa_enc alone has about 12 KB of
locals), so X-Wing operations now wipe 64 KiB (about 0.6 µs); the others
keep 16 KiB.xwing-encapsulate opens no
secret but produces one, and 0.3.1 wiped only after operations that
opened a secret. So did xwing-decapsulate with a byte-array seed. Both
now always wipe.with-secret: when the body
throws and destroying the secret fails too (a call on another thread
still uses it), the body's exception is rethrown, with the destroy error
attached as suppressed on the JVM. Internally, a failed close no longer
leaves the other secrets open or skips the stack wipe.release-check requires a dated heading, ## X.Y.Z (YYYY-MM-DD);
before, ## X.Y.Z (unreleased) passed.Pure., Impure: <what it reads or writes>, and
Throws ex-info {:type ::x} when … listing every :type. Functions that
take a key in a byte array or a secret say: pure for byte arrays; with a
secret, impure: reads it.need-xwing! (private) is now check-xwing and returns the function:
it writes nothing, so it has no !.bb test:signet now runs signet's own suite in ../signet (JVM, parity,
bb) with nacljc replaced by this checkout. The shim that stood in for
signet's backend (integration/) is gone: it implemented signet's old
16-function contract, and signet has had its own libsodium backend since
0.7.0.secret-destroy! crashes the JVM (a use after
free, SIGSEGV), unlike a read outside a call (InternalError on macOS);
README, secret-destroy! and test:secrets said otherwise.
test:secrets writes the JVM's crash logs to target/.Secret fields are internal (a comment on the deftype).sodium_stackzero over 16 KiB below the caller,
as recommended in libsodium's "Securing memory allocations" docs. C code
copies secret values into registers and stack frames while it runs.
About 0.2 µs per operation; operations on byte arrays skip it. No API
change.For signet 0.9.0's sessions, whose chaining key and transport keys stay in guarded memory.
secret-split: new secrets holding consecutive parts of a secret,
e.g. (secret-split s64 [32 32]). The lengths must be positive and add
up to the secret's size. The bytes are copied inside guarded memory
(sodium_memzero, then sodium_add onto the zeroed part, since
libsodium has no memcpy and ffi/copy goes through a JS buffer on nbb).
The source is unchanged. If a part cannot be allocated, the parts
already made are freed.hkdf-sha-256 accepts a secret salt. The result is a secret if the
ikm or the salt is one (before, only a secret ikm gave a secret). Byte
inputs behave exactly as in 0.2.0.secret-random, secret-import! (copies, then wipes the caller's
array), secret-export (requires {:i-understand :exposes-secret}),
secret-destroy!, with-secret, secret?, secret-length,
secret-destroyed?.sodium_malloc memory (guard pages, canaries,
mlock). It is no-access except during a call using it, then
read-only. It is safe to share between threads. It prints as
#nacljc/secret{:bytes n} and is not a map.ed25519->x25519-secret-key, HKDF output.aegis256-encrypt and aegis256-decrypt,
with a 32-byte nonce and a 32-byte tag. Checked against the RFC's test
vectors natively and in libsodium.js (WASM on Node, headless Chrome).xwing-public-key,
xwing-encapsulate, xwing-decapsulate. Shared secrets are always
secrets. Checked against the X-Wing test vectors. On an older libsodium
only these functions fail, with ::unsupported-by-libsodium.bb test:secrets: in child processes on bb, the JVM and nbb, reading a
secret's memory outside a call or after destroy faults.na/with-secret lints as let.First release. Before this, nacljc was a research repo named sodium.cljc.
nacljc.core, each name saying its algorithm:
ed25519-public-key, ed25519-sign, ed25519-verify?.ed25519->x25519-public-key,
ed25519->x25519-secret-key.x25519, x25519-public-key.chacha20-poly1305-encrypt, chacha20-poly1305-decrypt.hkdf-sha-256, hmac-sha-256,
sha-256.random-bytes, memzero!, constant-time-equal?,
libsodium-version, minimum-libsodium-version.::bad-input or ::bad-length. Error data never
includes contents.sodium_memzero before release, on
success and on error.::auth-failed,
::low-order-point, ::invalid-public-key, ::call-failed.NACLJC_LIBSODIUM, or on the JVM and bb the -Dnacljc.libsodium
property, selects exactly one library.libsodium.so.26, .23 and
.so on Linux.::library-not-found (listing the paths tried),
::not-libsodium, ::libsodium-too-old (below 1.0.19).org.babashka/ffi), babashka
1.13.220+ (the dynamically linked build on Linux), and nbb 1.6.213+ on
Node 26+. On nbb, Int8Array and Uint8Array inputs are accepted.Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |