#inst values, and so signed envelopes' timestamps, no longer depend
on the JVM's default locale. Before, under a locale with non-Latin
digits (for example ar-EG), cedn wrote #inst digits in that script,
so signatures made on such a machine verified nowhere else.java.sql.Date/Time in a payload now fail with cedn's
:cedn/unsupported-type instead of a raw exception.:sodium provider), the stack the C code used is
wiped with sodium_stackzero, as libsodium's memory docs recommend.
About 0.2 µs per operation. No API change.Sessions on vault handles (docs/08-sessions-on-handles-plan.md).
signet.session keeps its secrets in the vault. The chaining key,
handshake key, transport keys and ephemerals are vault session entries,
in the vault of the local static key; a state holds only handles and
public values, so printing it shows nothing secret. Under the :sodium
provider they stay in libsodium's guarded memory.initiator / responder take a vault handle as the local static
key, and the peer as a public key or a kid (::unknown-peer if it cannot
be resolved). Key records still work, deprecated; their session secrets
go to the :vault option's vault (default :default).write-message! / read-message! destroys the secrets
only the consumed state needed; a failed or racing call destroys what it
created, so a forged message leaves nothing behind.:local-static, :local-ephemeral.initiator / responder draw a random session id (documented as
impure: a read of the random generator).secret-split, secret HKDF salt).session/close!: destroys every secret of a session from any of its
states (even the first); any later use throws ::session-closed.session/with-conclave: closes the session when the block exits,
also on an exception. A clj-kondo lint-as export ships with the jar.vault/session-entry-count: how many session secrets a vault holds,
to monitor sessions that were never closed.handles, not exportable: ::not-exportable), impl/split-material.:sodium provider moves byte material it adopts into guarded
memory, so it only ever holds secrets.ssh/import-keypair!: imports an OpenSSH Ed25519 private key file
into a vault and returns a handle; the seed must give the file's public
key (:public-key-mismatch otherwise).Secret-carrying key records are deprecated in favour of vault handles.
Nothing is removed; the functions below carry ^{:deprecated "0.9.0"}
(clj-kondo warns) and a docstring pointer to the replacement:
key/signing-keypair, key/signing-keypair! → vault/generate-signing-key!
/ vault/import-signing-key! (secp256k1 has no vault equivalent yet)key/encryption-keypair, key/encryption-keypair! →
vault/generate-encryption-key! / vault/import-encryption-key!key/signing-private-key, key/encryption-private-key,
key/private-key → a vault handlekey/raw-shared-secret → signet.shared/shared-key!ssh/read-private-key, ssh/load-keypair, ssh/load-keypair! →
ssh/import-keypair!Key-record inputs to sign, box, chain and session keep working. Public-key records and functions are not deprecated.
signet.session is now wire-compatible with Noise. The handshake
mixed the prologue into the transcript hash after the static public
keys; the Noise spec (§5.3) mixes it first. Handshake messages
therefore matched no other Noise_KK_25519_ChaChaPoly_SHA256
implementation. Breaking: a 0.9.0 peer cannot complete a handshake
with a 0.8.0 or earlier peer (the first message fails authentication).
Transport messages were not affected.test/signet/noise_vectors_test.clj), on every backend.Secrets by reference: code holds vault handles, never secret bytes
(docs/07-secret-handles-design.md, decisions 7–16).
signet.vault:
KeyHandle records naming a key and its vault; a vault registry with
:default.lookup and register-public-key!,
handle and handles.generate-signing-key!,
generate-encryption-key!.import-signing-key! and import-encryption-key! (they wipe the
caller's array); export-secret (requires
{:i-understand :exposes-secret}); destroy!.sign, public-key, algorithm.default-signing-key,
set-default-signing-key!, ensure-default-signing-key! (race-safe).:memory (heap, inside the vault, lent copies wiped) and
:sodium (signet.vault.sodium, on nacljc 0.2.0 secrets in libsodium
guarded memory; derived secrets stay there). default-provider picks
:sodium on the libsodium backend.sign/sign and sign-edn take handles. box
takes a handle sender; unbox takes a handle, a set of handles, or a
vault id. chain/extend takes a handle root.:proof is a vault handle;
chain/export-token (sendable form, needs the acknowledgement),
chain/import-token! (refuses a mismatched proof), chain/discard!;
close destroys the proof.signet.shared:
shared-key!: both parties derive the same key and kid with no
exchange.seal and open: directional, key-committing, with a per-message salt.mac and verify-mac?: directional.key/set-default-signing-keypair!, key/set-default-encryption-keypair!,
key/default-signing-keypair, key/default-encryption-keypair,
key/clear-defaults!, key/ensure-default-signing-keypair!.
sign/sign-edn! and key-less chain/extend use
vault/ensure-default-signing-key! / vault/default-signing-key.:proof is a handle, not the seed. Use
export-token to send one.bb check-not-released, run by test:jar, refuses to install a version
already on Clojars. It prevents a local build shadowing a published jar
in ~/.m2.Dependency update only; no API or behaviour change.
cedn/check,
cedn.error/throw-*, with the old names deprecated), so the canonical
bytes, and therefore signatures, are unchanged. signet uses none of the
renamed functions.These two should have been released before signet 0.7.0; 0.7.1 catches up.
The first release on Clojars (com.github.franks42/signet). Earlier
versions were git tags only. There are breaking changes from 0.6.0; see
"Changed" below and the README's "Compatibility".
signet.impl.sodium, through
nacljc 0.1.0), selected with
-Dsignet.backend=sodium or SIGNET_BACKEND=sodium. It is
byte-identical to the JCA backend (a parity check runs in CI), and the
full suite also passes on babashka.signet.encryption): self-describing EDN boxes with
directional keys (a box cannot be reflected), a per-message HKDF salt
(safe random nonces at any volume), optional kid slots and an
authenticated :aad slot. unbox never throws on malformed input.
Design: docs/06-box-v2-design.md.key/signing-keypair!, key/encryption-keypair!,
ssh/load-keypair!. Also key/ensure-default-signing-keypair! and
sign/sign-edn!.:d "<redacted>", never secret bytes.signing-keypair,
encryption-keypair, signing-public-key, signing-private-key,
encryption-public-key, encryption-private-key, public-key,
private-key, hex->kid, raw-shared-secret, ssh/load-keypair) no
longer register keys. Only functions ending in ! write the key store or
the defaults.set-default-signing-keypair! or
ensure-default-signing-keypair!.sign/sign-edn always takes a key. The key-less arity is now
sign/sign-edn!.session/write-message and session/read-message are now
write-message! and read-message!, since they consume their state.::stale-session-state, so a nonce is never reused and a replayed
message is refused.verify-edn and chain/verify never throw, count
expiry against :valid?, and take :signer or :root for
:verified?, and :now for deterministic expiry. The raw signature
check is now :signature-valid?.key/lookup and key/kid no longer register anything.dh is for static keys and edh for ephemeral ones; mixing them up
throws.key/as-public-key, as-encryption-public-key and
as-encryption-private-key (added in 0.7.0 snapshots; use the now-pure
public-key, encryption-public-key, encryption-private-key).read-public-key and read-private-key refuse anything but an
unencrypted Ed25519 key, with ::bad-ssh-key and a :reason.ssh-rsa line or a passphrase-protected key was parsed
into a wrong key without error.assert, which can be compiled out, is replaced by ex-info.:type: for example
::no-private-key, ::sealed, ::no-default-signing-keypair,
::authentication-failed, ::wrong-message-phase.::authentication-failed
on every backend.! means the call writes state that outlives it. Impure reads are
documented, not banged, and ! never means "may throw". Docstrings state
Impure: …, Throws … and Never throws …. See CLAUDE.md.
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 |