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

@enclave-technologies/pqc-primitives

v0.1.1

Published

NIST Category 5 post-quantum primitives (ML-KEM-1024, ML-DSA-87, AES-256-GCM, SHAKE256) via WASM — algorithm API only

Downloads

360

Readme

enclave-pqc-primitives

NIST-aligned post-quantum cryptographic primitives for Enclave product SDKs. Licensed under Apache-2.0.

This is the foundational (tier-1) crate and the npm package @enclave-technologies/pqc-primitives (WASM bindings). Product SDKs (Auth, Sign, Verify, Messaging, …) build on top of it. This package stays algorithm-only — no sessions, envelopes, tokens, or credentials.

This crate implements NIST Category 5 exclusively (ML-KEM-1024 / ML-DSA-87), satisfying CNSA 2.0's algorithm requirements for national security systems. This is an architectural choice, not a certification — FIPS 140-3 module validation and any NSS accreditation remain separate, unstarted processes.

Algorithm suite (ENCLAVE_PQ_SUITE_v1)

Category 5 only — there is no Category 3 parameter set and no suite-selection API.

| Role | Algorithm | Standard | Implementation | |------|-----------|----------|----------------| | Key encapsulation | ML-KEM-1024 | FIPS 203 | RustCrypto ml-kem | | Signatures | ML-DSA-87 | FIPS 204 | RustCrypto ml-dsa | | Bulk AEAD | AES-256-GCM | FIPS 197 / SP 800-38D | RustCrypto aes-gcm | | Hash / XOF | SHAKE256 | FIPS 202 | RustCrypto sha3 | | Labeled KDF | enclave-kdf-v1 | SHAKE256 domain-separated | this crate | | Password → key | Argon2id | RFC 9106 (classical) | RustCrypto argon2 |

enclave-kdf-v1 is for high-entropy input (shared secrets, etc.). Argon2id (pwhash) is for human passwords: deliberately slow and memory-hard so stolen ciphertext resists offline guessing. Do not substitute one for the other, and do not lower OWASP baseline params for login latency without treating that as a direct security tradeoff.

Argon2id is classical and outside the Category 5 / CNSA 2.0 suite table — it fills the password → key gap alongside those primitives.

Encoding sizes (FIPS)

| | Public key | Secret (expanded) | Seed | Ciphertext / signature | |--|------------|-------------------|------|------------------------| | ML-KEM-1024 | 1568 | 3168 | 64 | ciphertext 1568; shared secret 32 | | ML-DSA-87 | 2592 | 4896 | 32 | signature 4627 |

Layout

src/                 Rust primitives (kem, sig, aead, hash, kdf, pwhash, provider, self_test, usage)
bindings/wasm/       wasm-bindgen façade (algorithm names only)
js/                  TS helpers / constants (source of truth for sizes)
scripts/build-wasm.mjs
dist/{bundler,nodejs,web}/   wasm-pack outputs + JS façade
tests/               Round-trips, CAST coverage, AES/SHAKE KATs

Rust usage

use enclave_pqc_primitives::{aead, kdf, kem, pwhash, run_self_tests, sig, SoftwareProvider, CryptoProvider};

run_self_tests()?; // optional CAST at startup (includes Argon2id KAT)

let kem_kp = kem::generate_keypair()?; // includes PCT
let enc = kem::encapsulate(&kem_kp.keypair.public_key)?;
let shared = kem::decapsulate(&enc.encapsulation.ciphertext, &kem_kp.keypair.secret_key)?;
let aes_key = kdf::labeled_kdf("aes-256-gcm-key", &shared.shared_secret, 32)?;

// Human password → AEAD key (OWASP Argon2id baseline; intentionally slow):
let salt = pwhash::generate_salt()?;
let pw_key = pwhash::pwhash_derive_key(b"user-passphrase", &salt.salt, &pwhash::RECOMMENDED_PARAMS)?;

let nonce = [0u8; aead::NONCE_BYTES]; // caller must ensure uniqueness
let sealed = aead::encrypt(&aes_key.key, &nonce, b"hello", b"aad")?;

let sig_kp = sig::generate_keypair()?; // includes PCT
let signature = sig::sign(&sig_kp.keypair.secret_key, b"message")?;
sig::verify(&sig_kp.keypair.public_key, b"message", &signature.signature)?;

// Same operations via the substitution seam (SoftwareProvider is not FIPS-validated):
let provider = SoftwareProvider;
let _ = provider.kem_generate_keypair()?;
# Ok::<(), enclave_pqc_primitives::Error>(())

Each operation returns a [CryptoUsageRecord] (algorithm, suite_id, operation, crate_version) for CBOM / audit attach points. Persistence and telemetry belong in Encrypt / product layers — not this crate.

JavaScript / TypeScript (@enclave-technologies/pqc-primitives)

WASM façade over the same Category 5 Rust core. Algorithm-namespaced only (kem* / sig* / aead* / …) — no product concepts.

Install / build

# Requires: rustup target wasm32-unknown-unknown, wasm-pack (auto-installed)
npm install
npm run build
npm test

Multi-runtime exports

| Consumer | Import condition / path | |----------|-------------------------| | Node / Vitest | import … from "@enclave-technologies/pqc-primitives"dist/nodejs | | Next.js / webpack / Vite | "browser"dist/bundler | | Deno / raw ESM | "./web" or "deno"dist/web |

import {
  KEM, SIG, AEAD, HASH, KDF_LABEL_PREFIX, PWHASH,
  kemGenerateKeypair, kemEncapsulate, kemDecapsulate,
  sigGenerateKeypair, sigSign, sigSignWithContext, sigVerify,
  aeadEncrypt, aeadDecrypt,
  labeledKdf, labeledKdf32, shake256, zeroize,
  pwhashDeriveKey, generateSalt, RECOMMENDED_PARAMS,
  runSelfTests, getLastUsageRecord,
  isPairwiseConsistencyFailure, isSelfTestFailure,
} from "@enclave-technologies/pqc-primitives";

await runSelfTests();
const kp = kemGenerateKeypair(); // PCT inside; seed-form secretKey (64 B)
const usage = getLastUsageRecord(); // { algorithm, suiteId, operation, crateVersion }

Keygen returns the preferred seed secret-key form (KEM.SECRET_KEY_SEED_BYTES / SIG.SECRET_KEY_SEED_BYTES). FIPS expanded sizes are SECRET_KEY_BYTES (3168 / 4896) via kemExpandedSecretKey / sigExpandedSecretKey.

Typed failures use err.name:

  • PairwiseConsistencyFailureError — PCT failed in keygen
  • SelfTestFailureError — CAST failed in runSelfTests

Errors otherwise throw greppable prefixes: InvalidLength:, InvalidEncoding:, AeadFailure:, SignatureInvalid:, InvalidParameter:.

Secret zeroization (important)

Rust zeroizes secret keys on Drop inside WASM. Bytes copied into a JS Uint8Array are not cleared by the GC. Call zeroize(secretKey) when finished with long-lived secrets.

Dependencies (pinned)

| Crate | Role | Provenance | |-------|------|------------| | ml-kem =0.3.2 | ML-KEM-1024 | RustCrypto | | ml-dsa =0.1.1 | ML-DSA-87 | RustCrypto | | aes-gcm =0.10.3 | AES-256-GCM | RustCrypto | | sha3 =0.10.8 | SHAKE256 | RustCrypto | | argon2 =0.5.3 | Argon2id (password → key) | RustCrypto | | getrandom =0.2.17 | CSPRNG for salts / (via ML-*) | RustCrypto adjacent | | zeroize =1.8.1 | Secret wipe-on-drop | RustCrypto |

Flagged dependencies

| Crate | Where | Why flagged | |-------|-------|-------------| | serde / serde_json | dev-only | reserved for future NIST ACVP JSON fixtures | | wasm-bindgen / js-sys / getrandom/js | bindings/wasm only | JS interop — not used by native Rust consumers |

Running tests

cargo test
cargo clippy --workspace --all-targets -- -D warnings

License

Licensed under the Apache License, Version 2.0.