
Post-Quantum Readiness
Document version: Session 44 | March 2026 Applies to: All SimpleGo Hardware Classes Copyright: 2025-2026 Sascha Daemgen, IT and More Systems, Recklinghausen License: AGPL-3.0 (Software) | CERN-OHL-W-2.0 (Hardware)
Why Post-Quantum Matters for a Messaging Device
Quantum computers capable of breaking current public-key cryptography (RSA, ECDH, X25519, X448) do not exist today. However, the "harvest now, decrypt later" threat is real: an adversary can record encrypted traffic today and store it until quantum computers become capable of breaking the key exchange, then retroactively decrypt all stored messages.
For a secure messaging device, this matters more than for most applications. Messages may contain information that remains sensitive for decades. If a journalist's source communications are recorded today, the source's identity could be exposed years from now when quantum decryption becomes feasible. SimpleGo's post-quantum readiness ensures that even retroactive quantum attacks cannot compromise message content.
SimpleGo currently uses X448 for the Double Ratchet key exchange (Layer 1) and X25519 for the NaCl cryptobox layers (Layers 2 and 3). Both are elliptic-curve algorithms vulnerable to Shor's algorithm on a sufficiently large quantum computer. The symmetric encryption (AES-256-GCM for Layer 1, XSalsa20-Poly1305 for Layers 2 and 3) is already quantum-resistant: Grover's algorithm reduces AES-256's security to approximately 128 bits against quantum attack, which remains computationally infeasible.
The fix is adding a post-quantum key encapsulation mechanism (KEM) to the key exchange, creating a hybrid scheme where both the classical and post-quantum algorithms must be broken to compromise the session.
SimpleX Protocol's Hybrid Approach
SimpleX Chat implemented hybrid post-quantum key exchange in version 5.6 (March 2024). Their approach combines classical X25519 with Streamlined NTRU Prime (sntrup761) in the Double Ratchet algorithm's ratchet step. The shared secrets from both algorithms are combined via HKDF to derive the ratchet chain key. If either algorithm is broken, the other still protects the session.
Critical protocol compatibility finding: SimpleX Chat uses sntrup761, NOT CRYSTALS-Kyber / ML-KEM. These are different post-quantum algorithms with different properties. For SimpleGo to maintain protocol compatibility with SimpleX Chat (enabling encrypted communication between SimpleGo devices and the SimpleX Chat app), SimpleGo must implement sntrup761.
sntrup761 vs ML-KEM Comparison
| Property | sntrup761 | ML-KEM-768 (Kyber) |
|---|---|---|
| Type | NTRU lattice KEM | Module-LWE KEM |
| Standardization | NIST Round 3 alternate, no FIPS standard | FIPS 203 (August 2024) |
| Public key size | 1,158 bytes | 1,184 bytes |
| Ciphertext size | 1,039 bytes | 1,088 bytes |
| Shared secret | 32 bytes | 32 bytes |
| Security level | Conservative, ~128-bit post-quantum | NIST Level 3 (~192-bit post-quantum) |
| Patent status | Patent-free by design | NIST IPR agreements |
| Used by | SimpleX Chat, OpenSSH, WireGuard | Chrome TLS, AWS, Signal (under evaluation) |
| ESP32 implementation | Not published (would need porting) | Published (fsegatz/kybesp32, ggtxz/MLKEM-on-ESP32) |
SimpleX's reasoning for sntrup761
SimpleX chose sntrup761 for several reasons documented in their v5.6 blog post. First, conservative security assumptions: NTRU has been studied for over 25 years, longer than any other lattice scheme. Second, patent freedom: the designers (Bernstein, Chuengsatiansup, Lange) explicitly designed it to avoid patent claims. Third, established deployment: OpenSSH has used sntrup761 as its default post-quantum hybrid since version 9.0 (2022). Fourth, audited implementation: the C reference code is well-studied and compact.
Feasibility on ESP32 Hardware
Published ML-KEM (Kyber) Benchmarks
The most detailed published benchmark for ESP32 is by Segatz et al. (arXiv:2503.10207, March 2025), using the ESP32-S3-DevKitC-1 at 160 MHz with ESP-IDF 5.0, Kyber-512 90s variant:
| Operation | Single-core, SW only | Dual-core + HW accel | At 240 MHz (estimated) |
|---|---|---|---|
| Key Generation | ~15.2 ms | ~8.8 ms | ~5.9 ms |
| Encapsulation | ~17.1 ms | ~9.3 ms | ~6.2 ms |
| Decapsulation | ~17.1 ms | ~10.1 ms | ~6.7 ms |
| Full exchange | ~32.3 ms | ~18.1 ms | ~12.1 ms |
The hardware acceleration uses the ESP32-S3's SHA accelerator (for the 90s variant's SHA-256/512 operations) and runs NTT polynomial multiplication across both cores via FreeRTOS task pinning. The dual-core optimization provides a 1.72x speedup.
A separate study (ggtxz/MLKEM-on-ESP32) demonstrates ML-KEM on ESP32 in a complete secure communication architecture with AES-CTR and HMAC-SHA-256, confirming real-world integration feasibility.
sntrup761 Feasibility Estimate
No published ESP32 sntrup761 benchmark exists. However, sntrup761 is computationally simpler than Kyber in several respects: it does not require Number Theoretic Transform (NTT), its core operations are integer polynomial multiplication and modular arithmetic, and the reference C implementation is self-contained (~3,000 lines, no external dependencies beyond a hash function).
Based on ARM Cortex-M4 benchmarks (the closest comparable architecture with published numbers), sntrup761 key generation takes approximately 1.5 million cycles, encapsulation approximately 1.1 million cycles, and decapsulation approximately 1.5 million cycles. At the ESP32-S3's 240 MHz clock rate, this translates to approximately 6-7 ms per operation, comparable to optimized Kyber. The ESP32-P4's 400 MHz RISC-V cores would reduce this to approximately 4 ms per operation.
Memory Requirements
| Algorithm | Public Key | Ciphertext | Secret Key | Working Memory |
|---|---|---|---|---|
| sntrup761 | 1,158 bytes | 1,039 bytes | 1,763 bytes | ~10-15 KB stack |
| ML-KEM-768 | 1,184 bytes | 1,088 bytes | 2,400 bytes | ~10-15 KB stack |
| X25519 (current) | 32 bytes | N/A | 32 bytes | ~1 KB stack |
| X448 (current) | 56 bytes | N/A | 56 bytes | ~2 KB stack |
Both post-quantum algorithms require approximately 10-15 KB of stack during computation. On the ESP32-S3 with 512 KB SRAM and 8 MB PSRAM, this is easily accommodated. The ratchet task (smp_app_task) runs on a 16 KB stack in internal SRAM - the PQ computation fits within this allocation.
Fitting in the 16 KB SMP Transport Block
The SMP protocol hard limit is 16,384 bytes per transport block, with approximately 15,530 bytes of effective payload after framing overhead. A hybrid key exchange message must fit within this limit:
| Component | Size |
|---|---|
| X448 public key | 56 bytes |
| sntrup761 ciphertext | 1,039 bytes |
| sntrup761 public key | 1,158 bytes |
| Double Ratchet header | ~100 bytes |
| JSON wrapper overhead | ~200 bytes |
| Total | ~2,553 bytes |
This uses approximately 16.4% of the available payload - comfortably within limits even with content padding to the full 16 KB block. There is no need for message chunking or XFTP fallback for the key exchange.
The Protocol Compatibility Decision
SimpleGo must make a strategic decision about post-quantum algorithm choice:
Option A: Implement sntrup761 (SimpleX compatible)
This is the option that maintains full protocol compatibility with SimpleX Chat. A SimpleGo device running sntrup761 can negotiate post-quantum hybrid key exchange with any SimpleX Chat app that has PQ enabled (v5.6+). The disadvantage is that no published ESP32 implementation exists - SimpleGo would need to port the C reference implementation to ESP-IDF, which is feasible but requires testing and optimization work.
Option B: Implement ML-KEM-768 (FIPS 203 standard)
This follows the NIST standard and has published ESP32 implementations ready to integrate. The disadvantage is protocol incompatibility with SimpleX Chat's PQ implementation. SimpleGo would need to negotiate PQ capability during the SMP handshake and fall back to classical-only when communicating with SimpleX Chat.
Option C: Implement both (maximum flexibility)
Implement sntrup761 for SimpleX Chat compatibility and ML-KEM-768 for future standards compliance. Use sntrup761 when the peer is a SimpleX Chat app, ML-KEM-768 when the peer is another SimpleGo device or a future protocol version. This is the most complex option but provides maximum flexibility.
Recommendation
Option A (sntrup761) is recommended for the initial implementation. Protocol compatibility with SimpleX Chat is a core product requirement. The reference C implementation is compact, well-audited, and patent-free. Once working, adding ML-KEM-768 as an additional option (Option C) can be done later without breaking anything.
This decision should be confirmed with Evgeny Poberezkin before implementation begins, as he may have insights about planned protocol changes or preferences for the hardware implementation. Per the established rule: search past conversations before asking Evgeny any question.
Architecture: Where PQ Integrates
Post-quantum key exchange integrates into a single file: protocol/smp_ratchet.c. The Double Ratchet's DH ratchet step currently performs X448 key agreement. The hybrid extension adds a KEM encapsulation/decapsulation alongside the X448 operation, then combines both shared secrets via HKDF:
Current (classical only):
shared_secret = X448_DH(my_private, their_public)
chain_key = HKDF(shared_secret, ...)
Hybrid (with PQ):
classical_secret = X448_DH(my_private, their_public)
pq_secret = sntrup761_decaps(their_ciphertext, my_pq_secret_key)
combined_secret = HKDF(classical_secret || pq_secret, ...)
chain_key = HKDF(combined_secret, ...)
The has_kem flag in the SMP protocol version negotiation indicates whether the peer supports PQ. If the peer does not support PQ, the ratchet falls back to classical X448 only. This backward compatibility is built into the SimpleX protocol design.
No eFuse blocks consumed
Post-quantum activation is a pure software change. It does not consume any eFuse blocks, does not require flash encryption, and does not require Secure Boot. It works in all four security modes (Open, Vault, Fortress, Bunker) and on both hardware platforms (ESP32-S3 and ESP32-P4).
SD card encryption is already quantum-resistant
The SD card chat history is encrypted with AES-256-GCM, which provides 128-bit security against Grover's algorithm. This is already quantum-resistant. No changes needed for the storage layer.
What We Can Honestly Claim
Verifiable claim: "Post-quantum key exchange has been independently demonstrated to run on ESP32 hardware with acceptable performance (under 15 ms per key exchange). SimpleGo's architecture is designed to support hybrid classical + post-quantum key exchange in a future firmware update. The SMP transport block size (16 KB) accommodates post-quantum ciphertext with room to spare. No hardware changes are required."
What we cannot claim: "SimpleGo is quantum-resistant." It is not, today. The X448 and X25519 key exchanges in the current firmware are vulnerable to quantum attack. The claim is readiness, not resistance. The distinction matters.
Timeline claim: No specific date. Post-quantum activation depends on completing the HMAC vault (Pillar 1) and runtime memory protection (Pillar 2) first, as documented in ARCHITECTURE_AND_SECURITY.md: "SEC-06: requires SEC-01 and SEC-02 first." This sequencing is correct because quantum-resistant key exchange is useless if the resulting keys are stored in plaintext flash or leaked from RAM.
References
| Source | Description |
|---|---|
| FIPS 203 | NIST ML-KEM (CRYSTALS-Kyber) standard, August 2024 |
| SimpleX Chat v5.6 blog | Hybrid PQ implementation: X25519 + sntrup761 |
| arXiv:2503.10207 | Segatz et al.: Kyber-512 90s on ESP32, 8.8-10.1 ms with HW accel |
| github.com/fsegatz/kybesp32 | ESP-IDF Kyber implementation, dual-core optimized |
| github.com/ggtxz/MLKEM-on-ESP32 | ML-KEM in complete ESP32 communication architecture |
| ntruprime.cr.yp.to | sntrup761 specification and reference implementation |
| OpenSSH 9.0 release notes | sntrup761 as default PQ hybrid |
| NIST SP 800-227 | Recommendations for Key Encapsulation Mechanisms (ML-KEM usage guidance) |
SimpleGo - IT and More Systems, Recklinghausen First native C implementation of the SimpleX Messaging Protocol AGPL-3.0 (Software) | CERN-OHL-W-2.0 (Hardware)