npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@shieldfive/crypto

v1.0.1

Published

Client-side post-quantum hybrid encryption for cloud storage. The cryptographic core of ShieldFive.

Readme

@shieldfive/crypto

Post-quantum-hybrid client-side encryption with a self-describing, cipher-suite-agile on-disk format. The cryptographic core of ShieldFive, released as a standalone library.

npm License Tests npm provenance OpenSSF Scorecard Status

Status & honest scope

This library is at 1.0.0. The v1 wire format is frozen — files written today will decrypt on every future v1 release — and the public TypeScript API is stable under semantic versioning, with one exception stated in Status: the ./vault entry point is experimental. 1.0.0 means the API is stable, not that the code has been audited. Those are two separate axes and we track them separately (see Status).

Audit status: this library has not received a paid third-party cryptographic audit, and 1.0.0 will not claim one. It has had an internal multi-agent review (findings fixed) and publishes reproducible positive and adversarial test vectors; an external audit is on the roadmap (we are pursuing grant-funded options). Status states exactly what has and has not been reviewed, and what you can verify yourself without trusting us.

The design choices documented in spec/ are deliberate and reviewable. The implementation is covered by 298 passing tests including truncation, reordering, splice, and tampering detection across all four suites. That is enough for internal dogfooding and for building on with eyes open. It is not enough to claim "most secure crypto library" — that claim requires external review this library has not yet received.

When this library says it avoids a parallel cryptographic implementation, that scope is the file-content cipher suites. The keyring/envelope layer that wraps content keys is built directly on WebCrypto AES-GCM and HMAC (via crypto.subtle), not on a second hand-rolled implementation.

Design positions

This library makes specific design choices that differ from existing open-source client-side encryption libraries in the encrypted-cloud-storage space. The table below summarizes those positions; each row links to the spec section that documents the choice.

| Property | This library | Proton OpenPGP.js | Internxt SDK | MEGA SDK | | ------------------------------------------ | :----------: | :---------------: | :----------: | :------: | | Post-quantum hybrid by default | ✅ | ⚠️ | ⚠️ | ❌ | | ML-KEM-1024 (NIST PQC level 5) | ✅ | ❌ | ❌ (Kyber-512) | ❌ | | Self-describing on-disk file format | ✅ | ✅ | ⚠️ | ⚠️ | | Cipher-suite agile (one byte selects) | ✅ | ⚠️ | ❌ | ❌ | | Truncation detection bound to AEAD | ✅ | ✅ | ❌ | ❌ | | Cross-file splice prevention (file_id via HKDF salt) | ✅ | ✅ | ❌ | ❌ | | Streaming AEAD with random-access chunks | ✅ | ⚠️ | ✅ | ✅ | | WebCrypto-only path (no WASM required) | ✅ | ❌ | ❌ | ❌ | | Apache 2.0 (patent grant) | ✅ | ⚠️ (LGPL) | ⚠️ | ⚠️ |

⚠️ = partial or feature-flagged. See spec/threat-model.md for the comparison methodology and source citations. Proton OpenPGP.js added optional post-quantum (ML-KEM + ECC hybrid) support via OpenPGP v6 in May 2026 (proton.me/blog/introducing-post-quantum-encryption); it is opt-in, not default — hence ⚠️ rather than ✅ in the table. Comparison cells reflect publicly available specifications and audit reports as of 2026-05-18 and will be updated as upstreams change.

Quick start

npm install @shieldfive/crypto
# Optional, only if you use suites 0x02 or 0x03:
npm install libsodium-wrappers-sumo

Encrypt a file with the post-quantum hybrid suite (default)

import {
  encryptBlob,
  decryptBlob,
  generateMlKemKeypair,
} from '@shieldfive/crypto/pq-hybrid-v1'

// Recipient generates a long-lived ML-KEM-1024 keypair (typically derived
// from their master secret — see deriveMlKemKeypair).
const { publicKey, secretKey } = generateMlKemKeypair()

// A classical envelope key (e.g. the user's vault key, 32 bytes).
const envelopeKey = crypto.getRandomValues(new Uint8Array(32))

// Encrypt
const file = new File([myData], 'document.pdf')
const result = await encryptBlob({
  blob: file,
  recipientPublicKey: publicKey,
  envelopeKey,
})

// Upload result.blob to your storage backend. It is self-describing.

// Later, decrypt
const plaintext = await decryptBlob({
  blob: result.blob,
  recipientSecretKey: secretKey,
  envelopeKey,
})

Encrypt with the WebCrypto-only suite (no WASM dependency)

Use aes-gcm-v2 — the current AES-GCM write path (also WASM-free). The aes-gcm-v1 subpath is decrypt-only for files written before v2 existed; don't write new files with it.

import { encryptBlob, decryptBlob } from '@shieldfive/crypto/aes-gcm-v2'

const result = await encryptBlob({ blob: file })
// result.contentKey is your 32-byte fresh per-file key — store it wrapped
// under your envelope key.

const plaintext = await decryptBlob({
  blob: result.blob,
  contentKey: result.contentKey,
})

Auto-routing decryptor

If you accept files written by any v1 suite and don't know which in advance:

import { autoDecryptBlob } from '@shieldfive/crypto'

const plaintext = await autoDecryptBlob({
  blob: encryptedBlob,
  contentKey,           // for aes-gcm-v1 / xchacha-v1
  recipientSecretKey,   // for pq-hybrid-v1
  envelopeKey,          // for pq-hybrid-v1
})

Reading legacy v0 files

The pre-v1 ShieldFive production format is supported read-only:

import { decryptV0 } from '@shieldfive/crypto/legacy-v0'

const plaintext = await decryptV0({
  blob: legacyBlob,
  contentKey,
  noncePrefix,    // 4 bytes, from the database
  chunkSize,      // 5 * 1024 * 1024 typically
})

There is no encryptV0. New writes must use a v1 suite.

Decrypting an exported ShieldFive backup

A ShieldFive user can export their account at any time and decrypt the resulting bundle offline using this library plus the small Node script that ships at shieldfive.com/export. The recipe walks the key hierarchy (master password → user key → root key → folder keys → per-file content keys), re-derives the ML-KEM-1024 secret for Suite 0x03 files deterministically from the root key (per spec/key-derivation.md), and feeds each blob into autoDecryptBlob here.

The recipe lives at shieldfive.com/export and the script ships in this repository as examples/decrypt-one.mjs, kept in lock-step with the API surface; this library is the decryption primitive the script depends on. If you want to reproduce the path from first principles (with no ShieldFive code in the loop), spec/format-v1.md and spec/key-derivation.md together describe everything needed.

File format

The complete v1 wire format is documented in spec/format-v1.md. The short version:

header := magic(5)           = "SF5\x01\x00"
       || suite(1)            = 0x01 | 0x02 | 0x03 | 0x04
       || flags(1)            = 0x00 (reserved)
       || file_id(16)         = random per-file
       || chunk_size(4)       = uint32 BE
       || total_chunks(8)     = uint64 BE
       || plaintext_size(8)   = uint64 BE
       || suite_payload_len(2)
       || suite_payload(variable)
       || header_mac(32)      = HMAC-SHA-256, keyed from content key

chunk_i := length_prefix(4) || AEAD-ciphertext-with-tag

Every chunk's AEAD authenticator binds the chunk index, total chunk count, and final-chunk flag. The file_id is NOT part of the AAD; cross-file splice resistance is structural, coming from the suite-specific chunk-key and nonce-prefix derivations that mix file_id in as the HKDF salt/IKM. Together these make truncation, reordering, and cross-file splicing detectable by the AEAD rather than by application-layer hashes.

Cipher suites

| ID | Name | Default | Notes | | ---- | ----------------------------------- | ------- | -------------------------------------- | | 0x01 | aes-256-gcm-v1 | | WebCrypto-only, hardware-accelerated | | 0x02 | xchacha20-poly1305-v1 | | libsodium, 192-bit nonces | | 0x03 | pq-hybrid-xchacha-mlkem1024-v1 | ✅ | XChaCha20-Poly1305 + ML-KEM-1024 hybrid | | 0x04 | aes-256-gcm-v2 | | WebCrypto-only, 8-byte nonce prefix |

Suite 0x04 is the current AES-GCM write path: identical to 0x01 except the 12-byte GCM IV uses an 8-byte file-derived nonce prefix and a 4-byte counter (rather than 4 + 8), widening the cross-file IV-collision margin. 0x01 remains defined for reading files written before 0x04 existed. See spec/format-v1.md for the per-suite derivations.

ML-KEM-1024 is FIPS 203 (NIST PQC standard, security level 5). Files encrypted with suite 0x03 remain confidential against an adversary who breaks either the classical or the post-quantum primitive — only a break of both compromises the file.

Threat model

Documented at length in spec/threat-model.md. The short summary: this library protects file confidentiality and integrity against an honest-but-curious server, an active network adversary, and a "harvest now, decrypt later" quantum adversary. It does not protect against malicious client delivery, endpoint compromise, side channels in the host crypto runtime, or metadata leakage at the storage layer. Those are addressed by the host application, not the crypto layer.

Performance

Benchmarks live in bench/throughput.ts. Run them on your hardware:

npx tsx bench/throughput.ts

Throughput depends heavily on CPU model, AES-NI availability, and Node version. The PQ KEM is a constant per-file cost (~ML-KEM-1024 keygen + encapsulation latency), independent of file size. Streaming chunk throughput tracks the underlying classical AEAD.

We do not publish reference numbers here because numbers without source hardware are misleading; numbers with source hardware get cherry-picked. Run the benchmark on your target hardware and report what you see.

Building from source

npm install
npm test
npm run build   # emits dist/

Requires Node 20+.

Status

1.0.0 — API stable, format frozen. This section tracks two independent axes; please don't conflate them.

API stability. The v1 wire format is frozen — files written today decrypt on every future v1 release. The public TypeScript API is stable under semantic versioning: a breaking change requires a major-version bump. The release candidate ran from 1.0.0-rc.1 (2026-07-14) to 1.0.0-rc.6 with additions and fixes only; no existing signature was removed or changed. 1.0.0 does not mean "audited."

Experimental: @shieldfive/crypto/vault. The vault entry point (key-chain wraps, name envelopes, agent-grant wraps and upload proofs, added in rc.5/rc.6) is not covered by the semver guarantee until it is declared stable in a later minor release: its API may change in a minor version. The formats it reads and writes are the ones the ShieldFive web app already stores, specified in spec/vault-formats.md, and any change to them will be called out in this changelog.

Audit status (scoped to v1.0.0). @shieldfive/crypto has not had a paid third-party security audit. The novel part of the design — the post-quantum-hybrid KEM combiner K = HKDF-SHA-256(classical_share ‖ ml_kem_share, salt = file_id) (see spec/key-derivation.md) — uses the same concatenation-KDF hybrid pattern as X-Wing and HPKE, but has not yet received external cryptographic review. An external audit is on the roadmap (grant-funded options are being pursued) and is not a prerequisite for the 1.0.0 release. When an audit lands it will be cited here with the firm, the date, and the exact commit/version reviewed — and this notice stays in place for any version that predates that review.

What you can verify without trusting us:

npm audit signatures   # npm provenance: tarball ↔ this source commit + CI run
npm test               # 298 tests incl. deterministic KATs + adversarial vectors

The tests/vectors/ directory publishes reproducible vectors any independent implementation can check against: positive known-answer vectors (vectors.json) that a conforming implementation must reproduce bit-for-bit, and negative / adversarial vectors (adversarial-vectors.json) — tampered files a conforming decoder MUST reject (bad magic, suite confusion, header/chunk tampering, reordering, truncation, cross-file splice), each self-checked against this implementation at generation time.

Plus a published threat model with explicit non-goals, a complete wire-format spec, and reproducible test vectors any independent implementation can check against.

License

Apache 2.0. The Apache 2.0 patent grant is important for a crypto library; we chose it over MIT for that reason.

Reporting vulnerabilities

See SECURITY.md. Coordinate with us at [email protected] (see SECURITY.md for the encrypted-channel process). 72-hour acknowledgement, 30-day target patch window for high-severity issues. Researchers acting in good faith are protected under the safe-harbor clause.

Acknowledgements

  • @noble/post-quantum by Paul Miller — clean, minimal ML-KEM-1024 (FIPS 203) implementation. ShieldFive pins ^0.6.0, which resolves to the 0.6.1 release. Upstream completed a maintainer self-audit at 0.6.1 in April 2026 (see the "Security" section of the upstream README) and has not been independently audited by an external firm. ShieldFive's PQ-hybrid construction on top of the library — the HKDF-SHA-256 combiner that mixes the classical and ML-KEM shares — has also not received an independent external audit. A third-party audit of the ShieldFive layer is on the roadmap (see Status); it is tracked separately from, and is not a prerequisite for, the 1.0.0 API-stability milestone.
  • libsodium — XChaCha20-Poly1305 and XSalsa20-Poly1305 secretbox.
  • The NIST PQC competition and FIPS 203 authors.

— Cho Garcia, maintainer