Releases: de-otio/crypto-envelope
v0.3.0 — first stable on the 0.3.x line
First stable release on the 0.3.x line. Promotes 0.3.0-alpha.1 to GA and
adds a constant-time-comparison hardening change. Wire format byte-identical
to 0.2.x — vectors decrypt both directions.
Installs as @de-otio/crypto-envelope@latest.
Highlights (new in 0.3.0)
constantTimeEqualhardening — split into platform-specific files.
Node path now delegates tonode:crypto.timingSafeEqual(C primitive)
instead of a pure-JS loop, eliminating V8-JIT not-contractually-constant-time
risk on Node. Browser path keeps the audited XOR-accumulate fallback.
Runtime behaviour identical at the API boundary.- Bundler-smoke test asserts the browser-field swap is a static
guarantee: nonode:cryptoimport ortimingSafeEqualreference in
browser bundles.
Carried forward from 0.3.0-alpha.1
See the v0.3.0-alpha.1 release notes for full detail. Highlights:
- Genuine browser/WebCrypto-only portability (
Bufferglobal eliminated) - Typed error taxonomy with partitioning-oracle defense
rewrapEnvelopeMessageCounter integration (AES-256-GCM nonce cap)- Envelope-level test vectors (59 files,
./test-vectorssubpath export) - Wire-format specification docs
- AES-GCM parity in envelope-layer tests
- README quick-start fix
Compatibility
- chaoskb: zero breaking changes vs 0.3.0-alpha.1 and 0.2.x.
- Wire format: identical bytes; 0.3.0 envelopes decrypt under 0.2.x and vice versa.
Stats
- 652 tests across 23 files
- biome + tsc clean
- 80 KB of pinned vectors in the published tarball
- npm Trusted Publishing + sigstore provenance attestation
Install: `npm install @de-otio/crypto-envelope@latest`
v0.3.0-alpha.1 — v1.0 readiness blockers
Closes the v1.0-readiness blockers identified in the 2026-04-25 design audit. Wire format unchanged from 0.2.x — base64 output is byte-identical, vectors decrypt both directions.
Highlights
- Genuine browser/WebCrypto-only portability —
Bufferglobal eliminated from all production crypto paths; newtest/browser-portability.test.tsproves the library runs withglobalThis.Buffer = undefined. Previously a documented but empirically-broken claim. - Typed error taxonomy with partitioning-oracle defense — new
EnvelopeErrorhierarchy (AuthenticationFailedError,UnsupportedAlgorithmError,UnsupportedVersionError,MalformedEnvelopeError,TruncatedCiphertextError). Wrong-key, wrong-commit, tampered-ciphertext, tampered-AAD, and tampered-commitment all throw byte-identical error messages. rewrapEnvelopeMessageCounter integration — optional 4th parameter; AES-256-GCM bulk rotation now enforces the 2³² nonce cap. 3-arg sync form unchanged for backward compat.- Envelope-level test vectors — 59 deterministic vector files at
test/vectors/envelope-{v1,v2}/. New./test-vectorssubpath export so downstream forks can verify interop.tools/regen-vectors.tsreproduces them byte-for-byte. - Wire-format specification docs —
doc/envelope-spec.md,doc/crypto.md,doc/tier-upgrade.md,doc/mistakes-prevented.md. A third party can reimplement v1 and v2 from the spec alone. - AES-GCM parity in envelope-layer tests + cross-version (v1↔v2) tamper coverage.
- README quick-start fix —
deriveContentKeyandderiveCommitKeynow exported from the main entry; a new test runs each README snippet verbatim.
Compatibility
- chaoskb: zero breaking changes. Old
try { ... } catch (e) { ... }patterns still catch the new typed errors.rewrapEnvelope's 3-arg signature unchanged. - Wire format: identical bytes; 0.3.0 vectors decrypt under 0.2.x and vice versa.
Stats
- 652 tests across 23 files (was 423 across 18 in 0.2.0-alpha.2)
- biome + tsc clean
- 80 KB of pinned vectors added to the published tarball
Install: `npm install @de-otio/crypto-envelope@alpha`
v0.2.0-alpha.2 — rewrapEnvelope primitive
Adds rewrapEnvelope(oldEnv, oldMaster, newMaster) primitive for master-key rotation. Preserves id/ts/alg/kid; regenerates nonce/ct/tag/commitment. Supports v1 and v2 envelopes.
Consumed by @de-otio/keyring@0.1.0-alpha.2's KeyRing.rotate() orchestration layer.
See CHANGELOG.md for full details.
v0.2.0-alpha.1 — AES-256-GCM + passphrase-KDF + browser SecureBuffer
Plan-02 Phases I–IV. Package now runs on any WebCrypto-compliant runtime (Node ≥22, modern browsers, Deno ≥2, Bun ≥1, Cloudflare Workers, Vercel Edge).
Highlights
- AES-256-GCM as a second AEAD alongside XChaCha20-Poly1305.
EnvelopeClient.forAesGcmInterop()factory for the safer call-site. 2³² per-key message hard cap enforced viaMessageCounter+NonceBudgetExceeded. - Unified passphrase-KDF via
deriveMasterKeyFromPassphrase. Argon2id (OWASP 2023 second-tier) mandated default; PBKDF2-SHA256 as a compatibility-only fallback with a 1,000,000 iteration floor and a first-use warning. MasterKeybranded type prevents passphrase-derived bytes from being handed to an AEAD primitive as a CEK without an explicit unbranding cast.- Browser
SecureBufferstrict-by-default. Constructing one requires{ insecureMemory: true }. - Runtime portability.
node:cryptogone — switched toglobalThis.crypto.getRandomValues+ pure-JS constant-time compare.
Breaking (pre-1.0 alpha)
EnvelopeClient.encrypt/decryptare now async.- Primitive-level
aeadEncrypt/aeadDecrypttake an explicitalgparameter.
Install
npm install @de-otio/crypto-envelope@alpha
See CHANGELOG.md.
v0.1.0-alpha.1 — envelope layer bootstrap
First pre-release of @de-otio/crypto-envelope.
Install with:
npm install @de-otio/crypto-envelope@alphaWhat's in the box
EnvelopeClient— high-level encrypt/decrypt with HKDF-derived content and commit keys held in mlock'dSecureBuffers, default v2 (CBOR) wire format.- Low-level API:
encryptV1/decryptV1,serializeV1/serializeV2/deserializeauto-detect,upgradeToV2/downgradeToV1. - Primitives under the
./primitivessubpath:aeadEncrypt/aeadDecrypt(XChaCha20-Poly1305),deriveKey+ namedderiveContentKey/deriveCommitKey,computeCommitment/verifyCommitment,deriveFromPassphrase(Argon2id). - Support:
canonicalJson,generateBlobId,SecureBuffer,constructAAD.
What it protects against
Nonce reuse, skipped AAD, partitioning-oracle attacks (key-committing AEAD), silent serialisation drift (RFC 8785 + verify-after-encrypt), weak KDF parameters (Argon2id at OWASP-2023 second-tier), timing attacks (constant-time compare), keys in swap/crash dumps (SecureBuffer), Math.random for keys (CSPRNG-only), silent decryption failure (throw-or-succeed semantics).
Test vectors
- RFC 8785 canonicalisation behavioural fixtures
- RFC 5869 Appendix A.1 HKDF-SHA256
- RFC 4231 §4.3 HMAC-SHA256
draft-irtf-cfrg-xchacha§A.3.1 XChaCha20-Poly1305 KAT (decrypt path)- Argon2id cross-implementation KAT against libsodium's
crypto_pwhash
Status caveats
- Pre-release. The wire format is mutable between
0.xminors.@latestis deliberately unused until chaoskb and trellis ship production releases against this package. - Tiered key management (
KeyRing, SSH-wrap, passphrase unlock, OS keychain) is out of scope — will land as a separate@de-otio/keyringpackage. - Node 20+ only.
sodium-nativeis a native addon; non-Node runtimes (Deno, Bun, browsers) are not supported in this line.
Full notes in CHANGELOG.md.