Beveiligingsarchitectuur

Algoritmen die u kunt wisselen zonder opnieuw te bouwen.

De geschiedenis van de cryptografie is een geschiedenis van gebroken algoritmen. Paramant is zo gebouwd dat een volgende doorbraak Paramant niet breekt: de relay bevat de post-quantumalgoritmen van NIST, en de keuze ligt niet vast in de code. Standaard laadt hij er twee, ML-KEM-768 en ML-DSA-65, en dat is wat /v2/capabilities vandaag teruggeeft.

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)

IDAlgoritmeNIST-categorieStatus
0x0001ML-KEM-5121alleen in modus extended
0x0002ML-KEM-7683geladen (standaard, core)
0x0003ML-KEM-10245alleen in modus extended

ML-DSA-handtekeningen (FIPS 204)

IDAlgoritmeNIST-categorieStatus
0x0000noneanoniemgeldig (geen handtekening)
0x0001ML-DSA-44cat 2alleen in modus extended
0x0002ML-DSA-65cat 3geladen (standaard, core)
0x0003ML-DSA-87cat 5alleen in modus extended

Falcon-handtekeningen (FIPS 206)

IDAlgoritmeNIST-categorieStatus
0x0100Falcon-512cat 1alleen in modus extended (compact, snel)
0x0101Falcon-1024cat 5alleen in modus extended (compact, snel)

SLH-DSA-handtekeningen (FIPS 205, stateless en hash-gebaseerd)

IDAlgoritmeNIST-categorieStatus
0x0200SLH-DSA-SHA2-128scat 1alleen in modus extended · traag ondertekenen
0x0201SLH-DSA-SHA2-128fcat 1alleen in modus extended
0x0202SLH-DSA-SHA2-192scat 3alleen in modus extended · traag ondertekenen
0x0203SLH-DSA-SHA2-192fcat 3alleen in modus extended
0x0204SLH-DSA-SHA2-256scat 5alleen in modus extended · traag ondertekenen
0x0205SLH-DSA-SHA2-256fcat 5alleen in modus extended
0x0206SLH-DSA-SHAKE-128scat 1alleen in modus extended · traag ondertekenen
0x0207SLH-DSA-SHAKE-128fcat 1alleen in modus extended
0x0208SLH-DSA-SHAKE-192scat 3alleen in modus extended · traag ondertekenen
0x0209SLH-DSA-SHAKE-192fcat 3alleen in modus extended
0x020ASLH-DSA-SHAKE-256scat 5alleen in modus extended · traag ondertekenen
0x020BSLH-DSA-SHAKE-256fcat 5alleen 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.

Stap 1

Schrijf de implementatie

Een klein bestand dat de bibliotheek omhult. Voorbeelden staan in relay/crypto/impls/ in de repository.

Stap 2

Registreer onder een ID

Eén regel in relay/crypto/bootstrap.js: registerSig(0x0300, myImpl).

Stap 3

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:

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