01Wat crypto-agility echt betekent
Kenmerken in de header, geen algoritmen vastgelegd in de code.
Elke blob draagt een header die aangeeft met welke algoritmen hij is
gemaakt: een KEM_ID van 2 bytes en een SIG_ID
van 2 bytes, beschermd tegen wijziging via GCM AAD. De client kiest. De
relay controleert. Beide kanten stemmen af via het capabilities-endpoint.
Geen verborgen standaardwaarden, geen gegok naar het protocol.
02Het wire format (v1)
Een vaste header van 10 bytes, daarna velden van wisselende lengte met een lengteprefix.
MAGIC 4 bytes PQHB VERSION 1 byte 0x01 KEM_ID 2 bytes uint16 BE SIG_ID 2 bytes uint16 BE (0x0000 = anoniem) FLAGS 1 byte gereserveerd voor latere functies
Daarna volgen velden van wisselende lengte met een lengteprefix: KEM-ciphertext, publieke sleutel van de afzender, optionele handtekening, AES-256-GCM-nonce + ciphertext, opvulblok. Volledige specificatie: docs/wire-format-v1.md.
03Wie maakt, wie controleert
De relay raakt de indeling van de bytes nooit aan.
Een client die v1 ondersteunt, maakt een blob met de KEM- en SIG-ID's van zijn keuze. De relay controleert de header en weigert niet-ondersteunde combinaties met HTTP 415. De relay slaat de blob letterlijk op en levert hem byte voor byte uit. Zo blijft zero knowledge behouden: de relay raakt de indeling van de bytes nooit aan. De client van de ontvanger ontsleutelt met de algoritmen die in de header staan.
Nog niet elke client maakt vandaag v1. Onderdeel 06 hieronder geeft per officiële client de precieze stand. De twee SDK's (sdk-py 3.0.0, sdk-js 3.0.0) maken v1 met echte ML-KEM en ML-DSA. De WASM-brug van de webapp maakt nog een hybride indeling van vóór v1, en twee extensies vallen op dit moment terug op een pad aan de serverkant terwijl hun versleuteling aan de clientkant wordt afgemaakt. We houden de stand van de migratie openlijk bij in plaats van eroverheen te praten.
04Wat er ondersteund wordt, en wat er geladen is
3 KEMs en 17 signature-algoritmen in de code, samen FIPS 203, 204, 205 en 206. Onze relays draaien de standaardmodus core, die er twee laadt: ML-KEM-768 en ML-DSA-65.
KEM-register (FIPS 203, ML-KEM)
| ID | Algoritme | NIST-categorie | Status |
|---|---|---|---|
| 0x0001 | ML-KEM-512 | 1 | alleen in modus extended |
| 0x0002 | ML-KEM-768 | 3 | geladen (standaard, core) |
| 0x0003 | ML-KEM-1024 | 5 | alleen in modus extended |
ML-DSA-handtekeningen (FIPS 204)
| ID | Algoritme | NIST-categorie | Status |
|---|---|---|---|
| 0x0000 | none | anoniem | geldig (geen handtekening) |
| 0x0001 | ML-DSA-44 | cat 2 | alleen in modus extended |
| 0x0002 | ML-DSA-65 | cat 3 | geladen (standaard, core) |
| 0x0003 | ML-DSA-87 | cat 5 | alleen in modus extended |
Falcon-handtekeningen (FIPS 206)
| ID | Algoritme | NIST-categorie | Status |
|---|---|---|---|
| 0x0100 | Falcon-512 | cat 1 | alleen in modus extended (compact, snel) |
| 0x0101 | Falcon-1024 | cat 5 | alleen in modus extended (compact, snel) |
SLH-DSA-handtekeningen (FIPS 205, stateless en hash-gebaseerd)
| ID | Algoritme | NIST-categorie | Status |
|---|---|---|---|
| 0x0200 | SLH-DSA-SHA2-128s | cat 1 | alleen in modus extended · traag ondertekenen |
| 0x0201 | SLH-DSA-SHA2-128f | cat 1 | alleen in modus extended |
| 0x0202 | SLH-DSA-SHA2-192s | cat 3 | alleen in modus extended · traag ondertekenen |
| 0x0203 | SLH-DSA-SHA2-192f | cat 3 | alleen in modus extended |
| 0x0204 | SLH-DSA-SHA2-256s | cat 5 | alleen in modus extended · traag ondertekenen |
| 0x0205 | SLH-DSA-SHA2-256f | cat 5 | alleen in modus extended |
| 0x0206 | SLH-DSA-SHAKE-128s | cat 1 | alleen in modus extended · traag ondertekenen |
| 0x0207 | SLH-DSA-SHAKE-128f | cat 1 | alleen in modus extended |
| 0x0208 | SLH-DSA-SHAKE-192s | cat 3 | alleen in modus extended · traag ondertekenen |
| 0x0209 | SLH-DSA-SHAKE-192f | cat 3 | alleen in modus extended |
| 0x020A | SLH-DSA-SHAKE-256s | cat 5 | alleen in modus extended · traag ondertekenen |
| 0x020B | SLH-DSA-SHAKE-256f | cat 5 | alleen in modus extended |
De trage varianten hebben kleinere handtekeningen (~8 tot 30 KB), maar ondertekenen duurt enkele seconden. De snelle varianten ondertekenen in minder dan een seconde, met grotere handtekeningen (17 tot 50 KB). Kies op basis van wat voor uw toepassing zwaarder weegt: bandbreedte of wachttijd.
Totaal: 3 KEM's en 17 handtekeningalgoritmen in de code. De standaardmodus core laadt ML-KEM-768 en ML-DSA-65, en die draaien onze relays; een zelf gehoste relay met CRYPTO_MODE=extended laadt ze allemaal.
05Controleer het zelf
Het live capabilities-endpoint is de bron van waarheid.
curl https://paramant.app/v2/capabilities
Wat onze relays vandaag antwoorden (modus core). Een relay in de modus extended noemt 21 vermeldingen:
{
"wire_version": 1,
"kem": [
{ "id": 2, "name": "ML-KEM-768", "loaded": true }
],
"sig": [
{ "id": 0, "name": "none", "loaded": true },
{ "id": 2, "name": "ML-DSA-65", "loaded": true }
]
}
Wat de relay aankondigt, is wat hij accepteert. Blobs met een algoritme-ID dat niet is aangekondigd, worden geweigerd met HTTP 415 UnsupportedAlgorithm, voordat er ook maar één byte wordt opgeslagen.
06Implementaties per client
Stand per client. Nagekeken in de broncode, niet aangenomen.
De relay accepteert wire format v1 van elke client die het maakt. De tabel hieronder geeft eerlijk de stand van elke officiële client die we vandaag leveren.
| Client | Standaard-KEM | Standaard-SIG | Wire format | Status |
|---|---|---|---|---|
| sdk-py 3.0.0 | ML-KEM-768 | ML-DSA-65 | v1 | live |
| sdk-js 3.0.0 | ML-KEM-768 | ML-DSA-65 | v1 | live |
| ParaShare (webapp) | ML-KEM-768 + ECDH P-256 | n/a | hybride, van vóór v1 | migratie naar v1 loopt |
| Send (browser-encrypted link) | n/a | n/a | AES-256-GCM, sleutel in het URL-fragment | bewust geen binding aan een identiteit |
| Chromium extension | n/a | n/a | AES-256-GCM, sleutel in het URL-fragment | in de client, geen binding aan een identiteit |
| Outlook add-in | n/a | n/a | AES-256-GCM, sleutel in het URL-fragment | in de client, geen binding aan een identiteit |
Hybride van vóór v1: de WASM-brug van de webapp draait al ML-KEM-768 + ECDH
P-256 + AES-256-GCM in de client, maar de indeling van de blob is ouder
dan de v1-header hierboven. Na de migratie naar v1 kan dezelfde WASM
KEM- en SIG-ID's afstemmen via /v2/capabilities.
De extensies versleutelen wel op uw eigen computer, maar niet met de
hybride methode hierboven: extensions/shared/paramant-core.js
maakt met Web Crypto een AES-256-GCM-sleutel en zet die in het
URL-fragment, precies zoals bij de in de browser versleutelde link. Er is
geen sleuteluitwisseling en dus geen binding aan een ontvanger: iedereen
bij wie de link terechtkomt, kan het bestand openen. Zie een upload via
een extensie daarom als een verzegelde link, niet als een end-to-end
overdracht aan een bepaalde persoon.
07Een algoritme toevoegen
Drie stappen. Geen schemawijzigingen, geen gevolgen voor blobs die onderweg zijn.
Schrijf de implementatie
Een klein bestand dat de bibliotheek omhult. Voorbeelden staan in
relay/crypto/impls/ in de repository.
Registreer onder een ID
Eén regel in relay/crypto/bootstrap.js:
registerSig(0x0300, myImpl).
Uitrollen
Bestaande blobs worden ongewijzigd ontsleuteld. Clients kiezen zelf
voor het nieuwe algoritme via /v2/capabilities.
Volledige referentie: github.com/Apolloccrypt/paramant-relay/blob/main/docs/wire-format-v1.md.
08Wat er nog niet gebouwd is
Het eerlijke verschil tussen het headerformaat en wat we leveren.
De byte FLAGS houdt ruimte vrij voor opties die we nu nog niet leveren:
- Hybride KEMs (twee KEMs in één blob, als extra verdedigingslaag)
- Blobs voor meerdere ontvangers
- Gecomprimeerde inhoud
- Forward secrecy via tijdelijke sleutels per sessie
De architectuur houdt hier rekening mee, maar ze zijn nog niet
aangesloten. Zodra ze er zijn, worden de bits in FLAGS
gezet en blijft het wire format op versie 1.
Controleer het register zelf
Het capabilities-endpoint is live en vraagt geen inlog. Het noemt elk algoritme-ID dat de relay accepteert, plus prestatie-aanwijzingen voor de SLH-DSA-varianten die traag ondertekenen. De specificatie van het wire format op GitHub beschrijft de indeling van de header volledig.
/v2/capabilities Specificatie wire format v1