Codync
A free, open-source 1:1 alternative to Grok Bot and Muse. Message Claude Code, Codex, Cursor and 40+ coding agents as persistent bots from your iPhone, Mac or Linux desktop. Group chats, threads, appr
Post-quantum cryptography for JS/TS in 30 minutes
Translation pending
Developer toolsGitHub @jeloerccOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
Post-quantum cryptography SDK for JS/TS — ML-KEM-768 and ML-DSA-65 (FIPS 203/204) with safe defaults. Docs: https://jeloercc.github.io/pqc-sdk/
Taken from the repository README
Loading the full README.
Read the full README ↗Post-quantum cryptography for JS/TS — hybrid encryption, digital signatures, streaming, and native AI-agent tool support via MCP and LangChain. Implements ML-KEM (FIPS 203) and ML-DSA (FIPS 204), tested against NIST ACVP vectors. Not FIPS 140-3 / CMVP validated — conformance is a published self-assessment. Safe defaults. Zero configuration.
Classical public-key cryptography (RSA, ECDH, ECDSA) is broken in polynomial time by a sufficiently large quantum computer running Shor's algorithm. One does not exist yet — but harvest-now, decrypt-later attacks are already occurring: adversaries store encrypted traffic today to decrypt it once a capable quantum computer exists. For any data that needs to stay secret for more than a few years, the migration window is now, not when the threat materialises.
NIST finalised three post-quantum standards in 2024:
| Standard | Algorithm family | What it replaces |
|---|---|---|
| FIPS 203 | ML-KEM (lattice-based KEM) | RSA / ECDH key exchange |
| FIPS 204 | ML-DSA (lattice-based signatures) | ECDSA / RSA signatures |
| FIPS 205 | SLH-DSA (hash-based signatures) | Long-lived roots of trust |
This SDK implements FIPS 203 and FIPS 204 in pure TypeScript, with a
clause-by-clause self-assessment against both standards, 6 closed
NONCONFORMING findings, and tests against NIST ACVP known-answer vectors for
every parameter set. SLH-DSA (FIPS 205) is deliberately not implemented — see
SLH-DSA scope decision.
┌─────────────────────────────────────────────────────────────────────┐
│ AI Agent Layer │
│ │
│ ┌──────────────────────┐ ┌──────────────────────────────┐ │
│ │ @pqc-sdk/mcp-server │ │ @pqc-sdk/langchain │ │
│ │ (MCP stdio server) │ │ (LangChain StructuredTools) │ │
│ │ │ │ │ │
│ │ Claude Desktop │ │ LangGraph agents │ │
│ │ Cursor / Continue │ │ OpenAI tool-calling │ │
│ │ Custom MCP hosts │ │ Anthropic tool-use │ │
│ └──────────┬───────────┘ └─────────────┬────────────────┘ │
└─────────────│─────────────────────────────────│────────────────────┘
│ │
└──────────────┬──────────────────┘
│ calls
┌────────────────────────────▼────────────────────────────────────────┐
│ @pqc-sdk/core │
│ │
│ pqc.keys.generate() pqc.encrypt() pqc.sign() │
│ pqc.keys.serialize() pqc.decrypt() pqc.verify() │
│ encryptStream() collectDecryptStream() │
│ │
│ ┌────────────────────┐ ┌───────────────────┐ │
│ │ ML-KEM-512/768/ │ │ ML-DSA-44/65/87 │ │
│ │ 1024 (FIPS 203) │ │ (FIPS 204) │ │
│ │ + X-Wing hybrid │ │ │ │
│ └────────────────────┘ └───────────────────┘ │
│ │
│ Primitives: vendored @noble/post-quantum 0.7.1 + @noble/ciphers │
└────────────────────────────────────────────────────────────────────┘
│
┌─────────────▼─────────────────┐
│ @pqc-sdk/cli │
│ pqc init / keygen / │
│ encrypt / decrypt / audit │
└───────────────────────────────┘
This SDK ships first-class support for AI agents. Both integrations expose the same operations: list algorithms, generate keys, encrypt, decrypt, sign, verify.
Secret keys never pass through the model context. Tool arguments and
results become part of the conversation, so no tool accepts or returns secret
key material: the model refers to secret keys by keyId, and the keys stay in
a keystore (MCP) or in your own storage (LangChain). Signing is off unless you
enable it.
The Model Context Protocol lets any compatible AI host call PQC operations as native tool calls — no custom wiring, no API server, just a local stdio process.
npm install -g @pqc-sdk/mcp-server
Claude Desktop — add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"pqc": {
"command": "pqc-mcp",
"env": { "PQC_KEYSTORE_DIR": "/Users/me/.local/share/my-agent/pqc-keys" }
}
}
}
Cursor / Continue — add the same block to your editor's MCP config.
PQC_KEYSTORE_DIR must be a directory dedicated to the agent: the model can
use every key in it. Details, permissions and key import:
packages/mcp-server.
Once connected, the model can call:
Tool call: pqc_keygen { "algorithm": "x-wing" }
→ { "keyId": "x-wing-3f9a1c2b7d4e", "algorithm": "x-wing", "publicToken": "pqcv1.x-wing.public.…" }
Tool call: pqc_encrypt { "publicToken": "pqcv1.x-wing.public.…", "plaintext": "hello" }
→ { "ciphertextHex": "0202…" }
Tool call: pqc_decrypt { "keyId": "x-wing-3f9a1c2b7d4e", "ciphertextHex": "0202…" }
→ { "encoding": "utf8", "plaintext": "hello" }
Tool call: pqc_verify { "message": "doc", "signatureHex": "b9e1…", "publicToken": "pqcv1.ml-dsa-65.public.…" }
→ { "verified": true }
Tool inventory:
| Tool | Input | Output |
|---|---|---|
pqc_algorithms | (none) | { supported[], fips[] } |
pqc_keygen | algorithm (optional, default x-wing) | { keyId, algorithm, publicToken } |
pqc_list_keys | (none) — MCP only | { keys[] } — keyId, algorithm, publicToken each |
pqc_encrypt | publicToken + exactly one of plaintext / plaintextBase64 | { ciphertextHex } |
pqc_decrypt | keyId, ciphertextHex | { encoding: "utf8", plaintext } or { encoding: "base64", plaintextBase64 } |
pqc_sign | keyId, message — only when signing is enabled | { signatureHex } |
pqc_verify | message, signatureHex, publicToken | { verified } |
pqc_decrypt returns plaintext to the model: whatever it decrypts, it reads.
Give the agent only keys whose data it may see.
npm install @pqc-sdk/langchain @pqc-sdk/core
import { createReactAgent } from '@langchain/langgraph/prebuilt';
import type { SecretKey } from '@pqc-sdk/core';
import { createPqcTools } from '@pqc-sdk/langchain';
// Demo only: an in-memory Map loses every key when the process restarts, and
// anything encrypted to those keys can then never be decrypted. Use durable
// storage (a secrets manager, a KMS-wrapped database) in real deployments.
const vault = new Map<string, SecretKey>();
const tools = createPqcTools({
resolveSecretKey: async (keyId) => {
const key = vault.get(keyId);
if (!key) throw new Error(`unknown key ${keyId}`);
return key;
},
onSecretKey: (keyId, secretKey) => {
vault.set(keyId, secretKey);
},
});
const agent = createReactAgent({ llm: model, tools });
The tools carry the same names and contracts as the MCP server above; the
package performs no I/O, so key storage stays under your control — and so does
durability: keys kept only in memory are gone after a restart, along with the
ability to decrypt anything encrypted to them. Details:
packages/langchain.
The MPC/a2a-protocol.md specification describes a
protocol for two AI agents to establish a post-quantum-secured communication
channel using ML-KEM (key encapsulation) and ML-DSA (identity attestation).
The full set of design documents is in MPC/.
npm install @pqc-sdk/core
import { createReadStream } from 'node:fs';
import { pqc } from '@pqc-sdk/core';
// ── Hybrid encryption (X-Wing default) ────────────────────────────────────
const pair = await pqc.keys.generate(); // X-Wing by default
const ciphertext = await pqc.encrypt('secret', pair.publicKey);
const plaintext = await pqc.decrypt(ciphertext, pair.secretKey);
// ── Digital signatures (ML-DSA-65) ────────────────────────────────────────
const signer = await pqc.keys.generate({ algorithm: 'ml-dsa-65' });
const signature = await pqc.sign('document', signer.secretKey);
const valid = await pqc.verify('document', signature, signer.publicKey);
// ── Pure FIPS 203 (ML-KEM-768), when FIPS scope dominates ─────────────────
const fipsPair = await pqc.keys.generate({ algorithm: 'ml-kem-768' });
// ── Streaming encryption (large files) — key first, then the source ───────
const encrypted = pqc.encryptStream(pair.publicKey, createReadStream('large-file.bin'));
// collectDecryptStream buffers the whole plaintext and throws on any tampering;
// see the streaming guide for incremental decryptStream on huge payloads.
const decrypted = await pqc.collectDecryptStream(pair.secretKey, encrypted);
Or bootstrap a whole project with the CLI:
npx @pqc-sdk/cli init
# Creates config, dev keys, .gitignore, and example.ts in ~5 seconds
Full documentation → jeloercc.github.io/pqc-sdk
| Package | What it does |
|---|---|
@pqc-sdk/core | The SDK — encryption, signatures, key handling, streaming. Node 20+, Deno, Workers, RN. |
@pqc-sdk/cli | pqc init / keygen / encrypt / decrypt / audit — dev scaffolding and file-level crypto. |
@pqc-sdk/mcp-server | MCP stdio server — PQC tools for any MCP host; secret keys stay in a local keystore. |
@pqc-sdk/langchain | LangChain / LangGraph tools via createPqcTools; keys stay in your own storage. |
All passing in CI · 90 %+ coverage on core
Encryption / Key Exchange
─────────────────────────────────────────────────────────────────
x-wing X25519 + ML-KEM-768 + AES-256-GCM ← default
ml-kem-512 FIPS 203 §4 (security category 1)
ml-kem-768 FIPS 203 §4 (security category 3) ← FIPS-only
ml-kem-1024 FIPS 203 §4 (security category 5)
Signatures
─────────────────────────────────────────────────────────────────
ml-dsa-44 FIPS 204 §5 (security category 2)
ml-dsa-65 FIPS 204 §5 (security category 3) ← recommended
ml-dsa-87 FIPS 204 §5 (security category 5)
Why X-Wing by default? A break in either the classical (X25519) or
post-quantum (ML-KEM-768) component still leaves the other standing — the same
reasoning behind TLS X25519MLKEM768, Signal's PQXDH, and the BSI/ANSSI
hybrid recommendations. Use ml-kem-768 when FIPS certification scope or
binary size dominate.
Read this before evaluating whether to trust this SDK.
We never implement cryptographic primitives from scratch. ML-KEM and ML-DSA
are @noble/post-quantum
0.7.1, vendored into packages/core/src/vendor/ with documented FIPS 203/204
corrections (each listed in the file header and tested by its own regression
suite); AES-GCM is @noble/ciphers,
used as published. The risk we carry is those corrections plus the layer
around the primitives: envelope format, key serialization, nonce derivation,
fail-closed parsing.
| Layer | How it is verified |
|---|---|
| Primitive correctness | NIST ACVP vectors for ML-KEM-512/768/1024 and ML-DSA-44/65/87, plus X-Wing Appendix C — nist-vectors.test.ts |
| Wire format stability | Golden vectors for every envelope version (v1, v2, streaming) — regenerated only behind an acknowledged breaking change — golden-vectors.test.ts |
| Parser hostility | Fuzzing of keys.deserialize against arbitrary and hostile input — always fails closed — deserialize-fuzz.test.ts |
| Roundtrip + tamper | Property-based tests (fast-check): decrypt(encrypt(x)) === x, any single-byte tamper fails closed — properties.test.ts |
| Streaming envelope | Mutation matrix tampering every region independently — truncation, reorder, duplication, cross-stream splice — stream-mutations.test.ts |
| Format specification | Normative byte layout — docs/serialization-format.md |
| Security review | Pre-launch findings + source-level review — docs/AUDIT-2026-06.md |
| Runtime claims | Node, Deno, Workers, Hermes, physical Android device — ✅ only after the real roundtrip ran — |
What these reviews are not. The audit docs are internal, AI-assisted reviews — not an independent third-party cryptographic audit. There are no constant-time guarantees in JavaScript, and no memory zeroization of secrets (no reliable JS primitive exists). Full threat model: SECURITY.md.
docs/compliance/ carries a clause-by-clause self-assessment against all
three PQC standards. Each matrix quotes normative text verbatim, assigns a
status from a closed vocabulary (CONFORMING, NONCONFORMING, INDETERMINATE,
NOT APPLICABLE), and cites a named, executed test as evidence — never a
narrative claim alone.
FIPS-203-MATRIX.md — 21 requirements, ML-KEM-512/768/1024FIPS-204-MATRIX.md — 22 requirements, ML-DSA-44/65/87FIPS-205-MATRIX.md — 21 requirements, all NOT APPLICABLE (SLH-DSA not implemented)| ID | Finding | Fix |
|---|---|---|
| F203-19 | Floating-point in Compress_d — JS / is IEEE-754 double; FIPS 203 forbids it | Integer-only bit-shift arithmetic, verified bit-exact over all 36,619 (q,d) pairs |
| F204-13 | Floating-point in Decompose / Power2Round / HINT_M | Integer-only BigInt/bit-shift, verified over all 8,380,417 values of Z_q |
| F203-18 | Branch-based implicit-reject — secret flag visible in control flow | Byte-wise arithmetic mask; both candidate secrets computed unconditionally |
| F204-10 | Missing zeroization on ML-DSA verify path — 9 intermediates leaked | try/finally with cleanBytes on every exit path |
| F203-11 | RBG failure misattributed as INVALID_KEY | Dedicated RBG_FAILURE error code, checked before the generic handler |
| F204-08 | Wrong-length public key throws instead of returning false | Length check moved inside the try block |
Three of these (F203-11/18/19) were first closed for ml-kem-768, then found
still open on the x-wing path — different scope, caught and fixed separately.
Not claimed: This is self-assessment, not CMVP validation. ACVP vectors passing is assurance evidence, not proof of every clause — the floating-point findings above passed KATs the entire time the requirement was breached.
ML-DSA-65 is the recommended signature algorithm. SLH-DSA (FIPS 205) is
deliberately excluded — see
FIPS-205-MATRIX.md for the full
rationale. Short version:
If you need SLH-DSA for a regulatory mandate, you likely need a CMVP-validated module. Open an issue if you have a concrete use case.
packages/
core/ @pqc-sdk/core — crypto SDK (ESM + CJS, TypeScript)
cli/ @pqc-sdk/cli — CLI tool
mcp-server/ @pqc-sdk/mcp-server — MCP stdio server for AI agents
langchain/ @pqc-sdk/langchain — LangChain/LangGraph tool wrappers
apps/
docs/ @pqc-sdk/docs — VitePress documentation site
examples/ node · deno · cloudflare-workers · hermes-standalone
docs/ serialization format · compliance matrices · audit reports
MPC/ agent integration specs (MCP, LangChain, A2A, tool schemas)
Build order (Turborepo): core → cli / mcp-server / langchain (parallel) → docs
See CONTRIBUTING.md to run the repo locally.
Breaking in 0.8.0:
pqc.keys.generate()with no arguments now returns an X-Wing hybrid pair, not pure ML-KEM-768. Read migrating to 0.8.0 before upgrading if you depend on the old default.
| Interop | CIRCL (Go) cross-check for ML-DSA and X-Wing shared secrets — interop-circl.test.ts |