0.1.0 â€Ē Published 1 month ago

@noble/post-quantum v0.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 month ago

noble-post-quantum

Auditable & minimal JS implementation of public-key post-quantum cryptography.

  • 🔒 Auditable
  • ðŸ”ŧ Tree-shaking-friendly: use only what's necessary, other code won't be included
  • ðŸĶū ML-KEM & CRYSTALS-Kyber: lattice-based kem
  • 🔋 ML-DSA & CRYSTALS-Dilithium: lattice-based signatures
  • 🐈 SLH-DSA & SPHINCS+: hash-based signatures
  • 📄 FIPS-203, FIPS-204, FIPS-205 drafts
  • ðŸŠķ 2000 lines for all algorithms

Check out What should I use section for benchmarks and algorithm selection guidance. For discussions, questions and support, visit GitHub Discussions section of the repository.

This library belongs to noble cryptography

noble cryptography — high-security, easily auditable set of contained cryptographic libraries and tools.

Usage

npm install @noble/post-quantum

We support all major platforms and runtimes. For Deno, ensure to use npm specifier. For React Native, you may need a polyfill for getRandomValues. A standalone file noble-post-quantum.js is also available.

// import * from '@noble/post-quantum'; // Error: use sub-imports, to ensure small app size
import { ml_kem768, kyber768 } from '@noble/post-quantum/ml-kem';
// import { ml_kem768, kyber768 } from 'npm:@noble/post-quantum@0.1.0/ml-kem'; // Deno

What should I use?

SpeedKey sizeSig sizeCreated inPopularized inPost-quantum?
RSANormal256B - 2KB256B - 2KB1970s1990sNo
ECCNormal32 - 256B48 - 128B1980s2010sNo
KyberFast1.6 - 31KB1KB1990s2020sYes
DilithiumNormal1.3 - 2.5KB2.5 - 4.5KB1990s2020sYes
SPHINCSSlow32 - 128B17 - 50KB1970s2020sYes

Speed (higher is better):

OPs/secKeygenSigningVerificationShared secret
ECC ed2551910270511010501470
Kyber-51230502090
Dilithium-2580170550
SPHINCS-128f2008140

tl;dr: ECC + ML-KEM for key agreement, SLH-DSA for pq signatures.

It's recommended to use SPHINCS, which is built on top of older, conservative primitives.

Kyber and Dilithium are lattice-based, so they're less "proven". There's some chance of advancement, which will break this algorithm class.

FIPS wants to release final standards in 2024. Until then, they provide no test vectors, meaning implementations could be producing invalid output. Moreover, if you'll use non-FIPS versions, or even FIPS versions today, it's possible the final spec will be incompatible, and you'll be stuck with old implementations. Similar to what happened to Keccak and SHA-3.

Symmetrical algorithms like AES and ChaCha (available in noble-ciphers) suffer less from quantum computers. For AES, simply update from AES-128 to AES-256.

ML-KEM / Kyber shared secrets

import { ml_kem512, ml_kem768, ml_kem1024 } from '@noble/post-quantum/ml-kem';
// import { kyber512, kyber768, kyber1024 } from '@noble/post-quantum/ml-kem';
// import { kyber512_90s, kyber768_90s, kyber1024_90s } from '@noble/post-quantum/ml-kem';
const aliceKeys = ml_kem768.keygen();
const alicePub = aliceKeys.publicKey;
const { cipherText, sharedSecret: bobShared } = ml_kem768.encapsulate(alicePub);
const aliceShared = ml_kem768.decapsulate(cipherText, aliceKeys.secretKey); // [Alice] decrypts sharedSecret from Bob
// aliceShared == bobShared

Lattice-based key encapsulation mechanism. See official site, repo, spec.

Key encapsulation is similar to DH / ECDH (think X25519), with important differences:

  • We can't verify if it was "Bob" who've sent the shared secret. In ECDH, it's always verified
  • It is probabalistic and relies on quality of randomness (CSPRNG). ECDH doesn't (to this extent).
  • Kyber decapsulation never throws an error, even when shared secret was encrypted by a different public key. It will just return a different shared secret

There are some concerns with regards to security: see djb blog and mailing list.

Three versions are provided:

  1. Kyber
  2. Kyber-90s, using algorithms from 1990s
  3. ML-KEM aka FIPS-203
// Alice generates keys
const aliceKeys = kyber1024.keygen(); // [Alice] generates key pair (secret and public key)
const alicePub = aliceKeys.publicKey; // [Alice] sends public key to Bob (somehow)
// aliceKeys.secretKey never leaves [Alice] system and unknown to other parties

// Bob creates cipherText for Alice
// [Bob] generates shared secret for Alice publicKey
const { cipherText, sharedSecret: bobShared } = kyber1024.encapsulate(alicePub);
// bobShared never leaves [Bob] system and unknown to other parties

// Alice gets cipherText from Bob
// [Alice] decrypts sharedSecret from Bob
const aliceShared = kyber1024.decapsulate(cipherText, aliceKeys.secretKey);

// Now, both Alice and Both have same sharedSecret key without exchanging in plainText
deepStrictEqual(aliceShared, bobShared);

// Warning: Can be MITM-ed
const carolKeys = kyber1024.keygen();
const carolShared = kyber1024.decapsulate(cipherText, carolKeys.secretKey); // No error!
notDeepStrictEqual(aliceShared, carolShared); // Different key!

ML-DSA / Dilithium signatures

import { ml_dsa44, ml_dsa65, ml_dsa87 } from '@noble/post-quantum/ml-dsa';
// import { dilithium_v30, dilithium_v31 } from '@noble/post-quantum/ml-dsa';
// import { dilithium_v30_aes, dilithium_v31_aes } from '@noble/post-quantum/ml-dsa';
const aliceKeys = ml_dsa65.keygen();
const msg = new Uint8Array(1);
const sig = ml_dsa65.sign(aliceKeys.secretKey, msg);
const isValid = ml_dsa65.verify(aliceKeys.publicKey, msg, sig)

Lattice-based digital signature algorithm. See official site, repo. Dilithium has similar internals to Kyber, but their keys and params are different.

Three versions are provided:

  1. Dilithium v3.0, v3.0 AES
  2. Dilithium v3.1, v3.1 AES
  3. ML-DSA aka FIPS-204

SLH-DSA / SPHINCS+ signatures

import { slh_dsa_sha2_128f as sph } from '@noble/post-quantum/slh-dsa';
// import { sphincs_shake_128f_simple } from '@noble/post-quantum/slh-dsa';
// import { sphincs_sha2_128f_simple } from '@noble/post-quantum/slh-dsa';
// Full list of imports can be seen below in "FIPS-205" section details
const aliceKeys = sph.keygen();
const msg = new Uint8Array(1);
const sig = sph.sign(aliceKeys.secretKey, msg);
const isValid = sph.verify(aliceKeys.publicKey, msg, sig);

Hash-based digital signature algorithm. See official site. We implement spec v3.1 with latest FIPS-205 changes. It's compatible with the latest version in the official repo. Some wasm libraries use older specs.

Three versions are provided:

  1. SHAKE256-based
  2. SHA2-based
  3. SLH-DSA aka FIPS-205

The pattern for exported name is:

sphincs_{HASH}_{BITS}{SIZE}_{KIND}

where
  HASH: shake | sha2
  BITS: 128 | 192 | 256
  SIZE: f | s (full, short)
  KIND: simple | robust

// Examples
sphincs_shake_128f_simple
sphincs_sha2_192s_robust

All imports:

import {
  sphincs_shake_128f_simple,
  sphincs_shake_128f_robust,
  sphincs_shake_128s_simple,
  sphincs_shake_128s_robust,
  sphincs_shake_192f_simple,
  sphincs_shake_192f_robust,
  sphincs_shake_192s_simple,
  sphincs_shake_192s_robust,
  sphincs_shake_256f_simple,
  sphincs_shake_256f_robust,
  sphincs_shake_256s_simple,
  sphincs_shake_256s_robust,
} from '@noble/post-quantum/slh-dsa';

import {
  sphincs_sha2_128f_simple,
  sphincs_sha2_128f_robust,
  sphincs_sha2_128s_simple,
  sphincs_sha2_128s_robust,
  sphincs_sha2_192f_simple,
  sphincs_sha2_192f_robust,
  sphincs_sha2_192s_simple,
  sphincs_sha2_192s_robust,
  sphincs_sha2_256f_simple,
  sphincs_sha2_256f_robust,
  sphincs_sha2_256s_simple,
  sphincs_sha2_256s_robust,
} from '@noble/post-quantum/slh-dsa';

import {
  slh_dsa_sha2_128f,
  slh_dsa_sha2_128s,
  slh_dsa_sha2_192f,
  slh_dsa_sha2_192s,
  slh_dsa_sha2_256f,
  slh_dsa_sha2_256s,
} from '@noble/post-quantum/slh-dsa';

Security

The library has not been independently audited yet.

If you see anything unusual: investigate and report.

Speed

To summarize, noble is the fastest JS implementation of post-quantum algorithms.

Check out What should I use table for now.

Contributing & testing

  1. Clone the repository
  2. npm install to install build dependencies like TypeScript
  3. npm run build to compile TypeScript code
  4. npm run test will execute all main tests

Resources

Check out paulmillr.com/noble for useful resources, articles, documentation and demos related to the library.

License

The MIT License (MIT)

Copyright (c) 2024 Paul Miller (https://paulmillr.com)

See LICENSE file.