Skip to main content

One post tagged with "quantum-computing"

View All Tags

Introducing Quantum-Resistant Encryption in JavaScript

· 6 min read
xoron
positive-intentions

⚠️ NOTE: This is an experimental implementation for testing purposes. Post-quantum cryptography is an active area of research. While ML-KEM is a NIST standard, this JavaScript implementation has not undergone formal security audits. Use responsibly.

We're excited to announce that our P2P messaging application now supports quantum-resistant encryption using ML-KEM (CRYSTALS-Kyber), a NIST-standardized post-quantum key encapsulation mechanism. This addition brings quantum-resistant security to our cascading cipher system, providing protection against future quantum computing attacks.

What is Post-Quantum Cryptography?

Quantum computers pose a significant threat to current public-key cryptography. While quantum computers are still in early stages, they could eventually break widely used algorithms like RSA, ECC (Elliptic Curve Cryptography), and Diffie-Hellman using Shor's algorithm. Quantum-resistant cryptography uses mathematical problems that quantum computers struggle to solve.

Current Vulnerabilities

🔴 Vulnerable to Quantum Attacks:

  • RSA (Shor's algorithm)
  • Elliptic Curve Cryptography (Shor's algorithm)
  • Diffie-Hellman key exchange (Shor's algorithm)

🟢 Quantum-Resistant:

  • AES-256 (Grover's algorithm only reduces to AES-128 equivalent)
  • SHA-256/SHA-3 (quantum advantage limited)
  • ML-KEM (CRYSTALS-Kyber) - Lattice-based KEM
  • ML-DSA (CRYSTALS-Dilithium) - Lattice-based signatures

The ML-KEM (CRYSTALS-Kyber) Standard

ML-KEM (Modular Lattice-based Key Encapsulation Mechanism) is one of the first post-quantum algorithms standardized by NIST in 2024. It's designed as a key encapsulation mechanism (KEM) rather than direct encryption, making it ideal for establishing shared secrets between parties.

📚 Learn More:

Key Properties:

  • ⚡ Fast: ~30-50ms for key encapsulation/decapsulation
  • 📦 Compact: 1184-byte public keys, 1088-byte encapsulated keys
  • 🔒 Security: Based on Learning With Errors (LWE) problem
  • 🎯 Standard: NIST FIPS 203 compliant
  • 🌐 Pure JavaScript: No native dependencies

Integration with Cascading Cipher

The ML-KEM implementation is integrated as a cipher layer in our cascading cipher architecture:

import {
CascadingCipherManager,
MLSCipherLayer,
SignalCipherLayer,
AESCipherLayer,
MLKEMCipherLayer, // New post-quantum layer
} from 'cryptography/CascadingCipher';

How It Works

ML-KEM functions as a key exchange layer in the encryption cascade:

Encryption Flow:

  1. ML-KEM Layer: Receiver's public key → encapsulated shared key
  2. Signal Layer: Double Ratchet adds forward secrecy
  3. MLS Group Layer: Group messaging support
  4. AES Layer: Fast symmetric encryption

Why This Approach?

Defense in Depth:

  • ML-KEM protects against quantum attacks
  • Signal Protocol provides forward secrecy
  • MLS enables group messaging
  • AES adds fast symmetric encryption

Each layer provides independent protection. If ML-KEM is broken, other layers still protect data.

Implementation Details

ML-KEM Cipher Layer Architecture

The MLKEMCipherLayer class implements the standard CipherLayer interface:

class MLKEMCipherLayer implements CipherLayer {
readonly name = "ML-KEM-768";
readonly version = "1.0.0";

async encrypt(data: Uint8Array, keys: MLKEMKeys): Promise<EncryptedPayload>;
async decrypt(payload: EncryptedPayload, keys: MLKEMKeys): Promise<Uint8Array>;
}

Key Properties

  • Public Key Size: 1184 bytes (for KEM-768 parameter set)
  • Private Key Size: 64 bytes
  • Encapsulated Key: 1088 bytes
  • Shared Secret: 32-64 bytes (used as AES key material)

Security Features

✅ Zeroization:

  • All sensitive buffers are cleared after use
  • Shared secrets, private keys, IVs are zeroized

✅ Timing Attack Protection:

  • Constant-time key validation
  • No early returns in validation logic

✅ IV Reuse Protection:

  • Tracks used IVs per public key
  • Random IV generation with collision detection

✅ Input Validation:

  • Maximum plaintext size: 10MB (prevents DoS)
  • Strict parameter size checks

Example Usage

import { MlKem768 } from '@hpke/ml-kem';
import { MLKEMCipherLayer } from 'cryptography/CascadingCipher';

// Generate ML-KEM key pair
const kem = new MlKem768();
const keyPair = await kem.generateKeyPair();

// Create cipher layer
const layer = new MLKEMCipherLayer();

// Encrypt plaintext
const plaintext = new TextEncoder().encode('Quantum-secure message!');
const encrypted = await layer.encrypt(plaintext, {
publicKey: keyPair.publicKey
});

// Decrypt
const decrypted = await layer.decrypt(encrypted, {
privateKey: keyPair.privateKey
});

console.log(new TextDecoder().decode(decrypted)); // "Quantum-secure message!"

Module Federation Integration

The cryptography module is exposed via module federation for import in the P2P application:

// cryptography/webpack.config.js
module.exports = {
// Module federation config
name: 'cryptography',
exposes: {
'./CascadingCipher': './src/crypto/CascadingCipher/index.ts',
'./MLKEMUtils': './src/crypto/MLKEMUtils.ts',
// ... other exports
}
};

The P2P app imports via remote:

// p2p/webpack.config.js
module.exports = {
remotes: {
cryptography: 'cryptography@http://localhost:8083/remoteEntry.js'
}
};

Storybook Examples

Interactive Storybook stories demonstrate ML-KEM functionality:

  • MLKEMBeginnerTutorial.stories.js - Step-by-step ML-KEM basics
  • MLKEMDemo.stories.js - Real encryption/decryption examples
  • MLKEMTimingTests.stories.js - Performance benchmarks

Try the Live Demo:

Examples available at:

Performance Characteristics

Encryption Benchmarks:

  • Key Generation: ~10-15ms
  • Encapsulation: ~15-25ms
  • Decapsulation: ~15-25ms
  • Total Operation: ~30-50ms

Overhead Analysis:

  • Message Size: Adds ~1100 bytes (encapsulated key + IV + salt)
  • Processing Time: +30-50ms compared to classical-only encryption
  • Memory: Minimal (key material cached)

Comparison: Classical vs Post-Quantum

PropertyClassical (ECDH)Post-Quantum (ML-KEM)
Key Size32-65 bytes1184 bytes
Ciphertext32-65 bytes1088 bytes
Computation~5-10ms~30-50ms
Quantum Security❌ Vulnerable✅ Resistant
Standard StatusLegacyNIST-approved

Security Considerations

Current Status

✅ Implemented:

  • ML-KEM-768 key pair generation
  • Key encapsulation/decapsulation
  • Integration with cascading cipher
  • Security hardening (zeroization, timing protection)

⚠️ Limitations:

  • JavaScript implementation (not FIPS 140-2 validated)
  • No formal security audit
  • Experimental/educational use only
  • Performance overhead vs classical algorithms

Recommendations

✅ Suitable For:

  • Long-term confidential data storage
  • Future-proofing sensitive communications
  • Experimental/educational projects
  • Low-volume secure messaging

❌ Not Recommended For:

  • Production without formal security review
  • High-performance applications
  • Regulatory compliance without validation

Future Roadmap

Planned Enhancements:

  1. ML-DSA Integration - Post-quantum digital signatures
  2. Hybrid Key Exchange - Combine classical + post-quantum
  3. FIPS 140-2 Validation - Formal certification
  4. WASM Optimization - Improve performance
  5. Multiple Parameter Sets - Support KEM-512/1024 variants
  6. Self-Certified Public Keys - Simplified identity verification

Conclusion

The addition of ML-KEM post-quantum cryptography brings quantum-resistant security to our P2P messaging platform. By integrating it within the cascading cipher architecture, we provide defense-in-depth protection against both classical and quantum attacks.

While this implementation is still experimental, it demonstrates that building quantum-resistant applications in JavaScript is feasible. As quantum computing capabilities evolve, having quantum-resistant layers in place positions the project for long-term security.

Resources