Protocolos Criptográficos Pós-Quânticos

Proposal 169
Aberto
Author zzz, orignal, drzed, eyedeekay
Created 2025-01-21
Last Updated 2025-06-12
Target Version 0.9.80

Visão Geral

Embora a pesquisa e competição por criptografia pós-quântica (PQ) adequada tenham estado em andamento por uma década, as escolhas não se tornaram claras até recentemente.

Começamos a analisar as implicações da criptografia PQ em 2022 zzz.i2p.

Os padrões TLS adicionaram suporte para criptografia híbrida nos últimos dois anos e agora é usado para uma porção significativa do tráfego criptografado na internet devido ao suporte no Chrome e Firefox Cloudflare.

O NIST finalizou e publicou recentemente os algoritmos recomendados para criptografia pós-quântica NIST. Várias bibliotecas de criptografia comuns agora suportam os padrões NIST ou irão lançar suporte em um futuro próximo.

Tanto Cloudflare quanto NIST recomendam que a migração comece imediatamente. Veja também o FAQ PQ da NSA de 2022 NSA. O I2P deve ser líder em segurança e criptografia. Agora é o momento de implementar os algoritmos recomendados. Usando nosso sistema flexível de tipos de criptografia e tipos de assinatura, adicionaremos tipos para criptografia híbrida, e para assinaturas PQ e híbridas.

Objetivos

  • Selecionar algoritmos resistentes ao PQ
  • Adicionar algoritmos apenas PQ e híbridos aos protocolos I2P onde apropriado
  • Definir múltiplas variantes
  • Selecionar as melhores variantes após implementação, testes, análise e pesquisa
  • Adicionar suporte incrementalmente e com compatibilidade retroativa

Não-Objetivos

  • Não altere protocolos de criptografia unidirecional (Noise N)
  • Não abandone o SHA256, não ameaçado a curto prazo por PQ
  • Não selecione as variantes preferidas finais neste momento

Modelo de Ameaças

  • Routers no OBEP ou IBGW, possivelmente em conluio, armazenando mensagens garlic para descriptografia posterior (forward secrecy)
  • Observadores de rede armazenando mensagens de transporte para descriptografia posterior (forward secrecy)
  • Participantes da rede falsificando assinaturas para RI, LS, streaming, datagramas, ou outras estruturas

Protocolos Afetados

Modificaremos os seguintes protocolos, aproximadamente na ordem de desenvolvimento. A implementação geral provavelmente será do final de 2025 até meados de 2027. Consulte a seção Prioridades e Implementação abaixo para detalhes.

Protocol / FeatureStatus
Hybrid MLKEM Ratchet and LSApproved 2026-06; beta target 2025-08; release target 2025-11
Hybrid MLKEM NTCP2Some details to be finalized
Hybrid MLKEM SSU2Some details to be finalized
MLDSA SigTypes 12-14Proposal is stable but may not be finalized until 2026
MLDSA DestsTested on live net, requires net upgrade for floodfill support
Hybrid SigTypes 15-17Preliminary
Hybrid Dests

Design

Daremos suporte aos padrões NIST FIPS 203 e 204 FIPS 203 FIPS 204 que são baseados em, mas NÃO compatíveis com, CRYSTALS-Kyber e CRYSTALS-Dilithium (versões 3.1, 3 e anteriores).

Key Exchange

Ofereceremos suporte ao intercâmbio híbrido de chaves nos seguintes protocolos:

ProtoNoise TypeSupport PQ only?Support Hybrid?
NTCP2XKnoyes
SSU2XKnoyes
RatchetIKnoyes
TBMNnono
NetDBNnono
PQ KEM fornece apenas chaves efêmeras e não suporta diretamente handshakes de chave estática como Noise XK e IK.

Noise N não usa uma troca de chaves bidirecional e, portanto, não é adequado para criptografia híbrida.

Portanto, suportaremos apenas criptografia híbrida, para NTCP2, SSU2 e Ratchet. Definiremos as três variantes ML-KEM como em FIPS 203, para um total de 3 novos tipos de criptografia. Os tipos híbridos serão definidos apenas em combinação com X25519.

Os novos tipos de criptografia são:

TypeCode
MLKEM512_X255195
MLKEM768_X255196
MLKEM1024_X255197
O overhead será substancial. Os tamanhos típicos de mensagem 1 e 2 (para XK e IK) atualmente são de cerca de 100 bytes (antes de qualquer payload adicional). Isso aumentará de 8x a 15x dependendo do algoritmo.

Signatures

Apoiaremos assinaturas PQ e híbridas nas seguintes estruturas:

TypeSupport PQ only?Support Hybrid?
RouterInfoyesyes
LeaseSetyesyes
Streaming SYN/SYNACK/Closeyesyes
Repliable Datagramsyesyes
Datagram2 (prop. 163)yesyes
I2CP create session msgyesyes
SU3 filesyesyes
X.509 certificatesyesyes
Java keystoresyesyes
Portanto, suportaremos tanto assinaturas apenas PQ quanto híbridas. Definiremos as três variantes ML-DSA conforme em FIPS 204, três variantes híbridas com Ed25519, e três variantes apenas PQ com prehash apenas para arquivos SU3, totalizando 9 novos tipos de assinatura. Tipos híbridos serão definidos apenas em combinação com Ed25519. Usaremos o ML-DSA padrão, NÃO as variantes pre-hash (HashML-DSA), exceto para arquivos SU3.

Usaremos a variante de assinatura “hedged” ou randomizada, não a variante “determinística”, conforme definido em FIPS 204 seção 3.4. Isso garante que cada assinatura seja diferente, mesmo quando sobre os mesmos dados, e fornece proteção adicional contra ataques de canal lateral. Consulte a seção de notas de implementação abaixo para detalhes adicionais sobre as escolhas de algoritmo, incluindo codificação e contexto.

Os novos tipos de assinatura são:

TypeCode
MLDSA4412
MLDSA6513
MLDSA8714
MLDSA44_EdDSA_SHA512_Ed2551915
MLDSA65_EdDSA_SHA512_Ed2551916
MLDSA87_EdDSA_SHA512_Ed2551917
MLDSA44ph18
MLDSA65ph19
MLDSA87ph20
Certificados X.509 e outras codificações DER usarão as estruturas compostas e OIDs definidos em IETF draft.

O overhead será substancial. Os tamanhos típicos de destino Ed25519 e identidade de router são 391 bytes. Estes aumentarão de 3,5x a 6,8x dependendo do algoritmo. As assinaturas Ed25519 são de 64 bytes. Estas aumentarão de 38x a 76x dependendo do algoritmo. RouterInfo assinado típico, LeaseSet, datagramas respondíveis e mensagens de streaming assinadas são cerca de 1KB. Estes aumentarão de 3x a 8x dependendo do algoritmo.

Como os novos tipos de identidade de destino e router não conterão preenchimento, eles não serão compressíveis. Os tamanhos de destinos e identidades de router que são comprimidos com gzip durante o trânsito aumentarão de 12x a 38x, dependendo do algoritmo.

Para Destinations, os novos tipos de assinatura são suportados com todos os tipos de criptografia no leaseset. Defina o tipo de criptografia no certificado de chave como NONE (255).

Para RouterIdentities, o tipo de criptografia ElGamal está obsoleto. Os novos tipos de assinatura são suportados apenas com criptografia X25519 (tipo 4). Os novos tipos de criptografia serão indicados nos RouterAddresses. O tipo de criptografia no certificado de chave continuará sendo tipo 4.

New Crypto Required

  • ML-KEM (anteriormente CRYSTALS-Kyber) FIPS 203
  • ML-DSA (anteriormente CRYSTALS-Dilithium) FIPS 204
  • SHA3-128 (anteriormente Keccak-256) FIPS 202 Usado apenas para SHAKE128
  • SHA3-256 (anteriormente Keccak-512) FIPS 202
  • SHAKE128 e SHAKE256 (extensões XOF para SHA3-128 e SHA3-256) FIPS 202

Vetores de teste para SHA3-256, SHAKE128, e SHAKE256 estão em NIST.

Note que a biblioteca Java bouncycastle suporta todos os itens acima. O suporte da biblioteca C++ está no OpenSSL 3.5 OpenSSL.

Alternatives

Não ofereceremos suporte para FIPS 205 (Sphincs+), é muito mais lento e maior que ML-DSA. Não ofereceremos suporte para o próximo FIPS206 (Falcon), ainda não foi padronizado. Não ofereceremos suporte para NTRU ou outros candidatos PQ que não foram padronizados pelo NIST.

Rosenpass

Existe alguma pesquisa paper sobre adaptar o Wireguard (IK) para criptografia PQ pura, mas há várias questões em aberto nesse artigo. Posteriormente, essa abordagem foi implementada como Rosenpass Rosenpass whitepaper para Wireguard PQ.

O Rosenpass usa um handshake similar ao Noise KK com chaves estáticas pré-compartilhadas Classic McEliece 460896 (500 KB cada) e chaves efêmeras Kyber-512 (essencialmente MLKEM-512). Como os textos cifrados Classic McEliece têm apenas 188 bytes, e as chaves públicas e textos cifrados Kyber-512 são razoáveis, ambas as mensagens de handshake cabem em uma MTU UDP padrão. A chave compartilhada de saída (osk) do handshake PQ KK é usada como a chave pré-compartilhada de entrada (psk) para o handshake Wireguard IK padrão. Então há dois handshakes completos no total, um PQ puro e um X25519 puro.

Não podemos fazer nada disso para substituir nossos handshakes XK e IK porque:

  • Não podemos fazer KK, Bob não tem a chave estática de Alice
  • Chaves estáticas de 500KB são grandes demais
  • Não queremos uma viagem de ida e volta extra

Há muitas informações boas no whitepaper, e nós iremos analisá-lo para obter ideias e inspiração. TODO.

Specification

Troca de Chaves

Atualize as seções e tabelas no documento de estruturas comuns /en/docs/spec/common-structures/ da seguinte forma:

Assinaturas

Os novos tipos de Chave Pública são:

TypePublic Key LengthSinceUsage
MLKEM512_X25519320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM768_X25519320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM1024_X25519320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM5128000.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM76811840.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM102415680.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM512_CT7680.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM768_CT10880.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM1024_CT15680.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
NONE00.9.xxSee proposal 169, for destinations with PQ sig types only, not for RIs or Leasesets
As chaves públicas híbridas são a chave X25519. As chaves públicas KEM são a chave PQ efêmera enviada de Alice para Bob. A codificação e a ordem de bytes são definidas em FIPS 203.

As chaves MLKEM*_CT não são realmente chaves públicas, elas são o “ciphertext” enviado de Bob para Alice no handshake Noise. Elas são listadas aqui para completude.

Combinações Legais

Os novos tipos de Chave Privada são:

TypePrivate Key LengthSinceUsage
MLKEM512_X25519320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM768_X25519320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM1024_X25519320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM51216320.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM76824000.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
MLKEM102431680.9.xxSee proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
Chaves privadas híbridas são as chaves X25519. Chaves privadas KEM são apenas para Alice. A codificação KEM e a ordem de bytes são definidas em FIPS 203.

Nova Criptografia Necessária

Os novos tipos de Chaves Públicas de Assinatura são:

TypeLength (bytes)SinceUsage
MLDSA4413120.9.xxSee proposal 169
MLDSA6519520.9.xxSee proposal 169
MLDSA8725920.9.xxSee proposal 169
MLDSA44_EdDSA_SHA512_Ed2551913440.9.xxSee proposal 169
MLDSA65_EdDSA_SHA512_Ed2551919840.9.xxSee proposal 169
MLDSA87_EdDSA_SHA512_Ed2551926240.9.xxSee proposal 169
MLDSA44ph13440.9.xxOnly for SU3 files, not for netdb structures
MLDSA65ph19840.9.xxOnly for SU3 files, not for netdb structures
MLDSA87ph26240.9.xxOnly for SU3 files, not for netdb structures
As chaves públicas de assinatura híbrida são a chave Ed25519 seguida pela chave PQ, conforme em IETF draft. A codificação e ordem de bytes são definidas em FIPS 204.

Alternativas

Os novos tipos de Chave Privada de Assinatura são:

TypeLength (bytes)SinceUsage
MLDSA4425600.9.xxSee proposal 169
MLDSA6540320.9.xxSee proposal 169
MLDSA8748960.9.xxSee proposal 169
MLDSA44_EdDSA_SHA512_Ed2551925920.9.xxSee proposal 169
MLDSA65_EdDSA_SHA512_Ed2551940640.9.xxSee proposal 169
MLDSA87_EdDSA_SHA512_Ed2551949280.9.xxSee proposal 169
MLDSA44ph25920.9.xxOnly for SU3 files, not for netdb structures. See proposal 169
MLDSA65ph40640.9.xxOnly for SU3 files, not for netdb structures. See proposal 169
MLDSA87ph49280.9.xxOnly for SU3 files, not for netdb structures. See proposal 169
As chaves privadas de assinatura híbridas são a chave Ed25519 seguida pela chave PQ, como em IETF draft. A codificação e ordem dos bytes são definidas em FIPS 204.

Rosenpass

Os novos tipos de Signature são:

TypeLength (bytes)SinceUsage
MLDSA4424200.9.xxSee proposal 169
MLDSA6533090.9.xxSee proposal 169
MLDSA8746270.9.xxSee proposal 169
MLDSA44_EdDSA_SHA512_Ed2551924840.9.xxSee proposal 169
MLDSA65_EdDSA_SHA512_Ed2551933730.9.xxSee proposal 169
MLDSA87_EdDSA_SHA512_Ed2551946910.9.xxSee proposal 169
MLDSA44ph24840.9.xxOnly for SU3 files, not for netdb structures. See proposal 169
MLDSA65ph33730.9.xxOnly for SU3 files, not for netdb structures. See proposal 169
MLDSA87ph46910.9.xxOnly for SU3 files, not for netdb structures. See proposal 169
As assinaturas híbridas são a assinatura Ed25519 seguida pela assinatura PQ, como em IETF draft. As assinaturas híbridas são verificadas verificando ambas as assinaturas, e falhando se qualquer uma delas falhar. A codificação e ordem de bytes são definidas em FIPS 204.

Key Certificates

Os novos tipos de Signing Public Key são:

TypeType CodeTotal Public Key LengthSinceUsage
MLDSA441213120.9.xxSee proposal 169
MLDSA651319520.9.xxSee proposal 169
MLDSA871425920.9.xxSee proposal 169
MLDSA44_EdDSA_SHA512_Ed255191513440.9.xxSee proposal 169
MLDSA65_EdDSA_SHA512_Ed255191619840.9.xxSee proposal 169
MLDSA87_EdDSA_SHA512_Ed255191726240.9.xxSee proposal 169
MLDSA44ph18n/a0.9.xxOnly for SU3 files
MLDSA65ph19n/a0.9.xxOnly for SU3 files
MLDSA87ph20n/a0.9.xxOnly for SU3 files
Os novos tipos de Chave Pública Crypto são:
TypeType CodeTotal Public Key LengthSinceUsage
MLKEM512_X255195320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM768_X255196320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
MLKEM1024_X255197320.9.xxSee proposal 169, for Leasesets only, not for RIs or Destinations
NONE25500.9.xxSee proposal 169
Os tipos de chave híbrida NUNCA são incluídos em certificados de chave; apenas em leasesets.

Para destinos com tipos de assinatura Hybrid ou PQ, use NONE (tipo 255) para o tipo de criptografia, mas não há chave criptográfica, e toda a seção principal de 384 bytes é para a chave de assinatura.

Estruturas Comuns

Aqui estão os comprimentos para os novos tipos de Destination. O tipo Enc para todos é NONE (tipo 255) e o comprimento da chave de criptografia é tratado como 0. Toda a seção de 384 bytes é usada para a primeira parte da chave pública de assinatura. NOTA: Isso é diferente da especificação para os tipos de assinatura ECDSA_SHA512_P521 e RSA, onde mantivemos a chave ElGamal de 256 bytes no destination mesmo ela não sendo usada.

Sem padding. O comprimento total é 7 + comprimento total da chave. O comprimento do certificado de chave é 4 + comprimento excedente da chave.

Exemplo de fluxo de bytes de destino de 1319 bytes para MLDSA44:

skey[0:383] 5 (932 » 8) (932 & 0xff) 00 12 00 255 skey[384:1311]

TypeType CodeTotal Public Key LengthMainExcessTotal Dest Length
MLDSA441213123849281319
MLDSA6513195238415681959
MLDSA8714259238422082599
MLDSA44_EdDSA_SHA512_Ed255191513443849601351
MLDSA65_EdDSA_SHA512_Ed2551916198438416001991
MLDSA87_EdDSA_SHA512_Ed2551917262438422402631

PublicKey

Aqui estão os comprimentos para os novos tipos de Destination. O tipo Enc para todos é X25519 (tipo 4). Toda a seção de 352 bytes após a chave pública X25519 é usada para a primeira parte da chave pública de assinatura. Sem padding. O comprimento total é 39 + comprimento total da chave. O comprimento do certificado da chave é 4 + comprimento excessivo da chave.

Exemplo de fluxo de bytes de identidade de router de 1351 bytes para MLDSA44:

enckey[0:31] skey[0:351] 5 (960 » 8) (960 & 0xff) 00 12 00 4 skey[352:1311]

TypeType CodeTotal Public Key LengthMainExcessTotal RouterIdent Length
MLDSA441213123529601351
MLDSA6513195235216001991
MLDSA8714259235222402631
MLDSA44_EdDSA_SHA512_Ed255191513443529921383
MLDSA65_EdDSA_SHA512_Ed2551916198435216322023
MLDSA87_EdDSA_SHA512_Ed2551917262435222722663

ChavePrivada

Os handshakes usam padrões de handshake do Noise Protocol.

O seguinte mapeamento de letras é usado:

  • e = chave efêmera única
  • s = chave estática
  • p = payload da mensagem
  • e1 = chave PQ efêmera única, enviada de Alice para Bob
  • ekem1 = o texto cifrado KEM, enviado de Bob para Alice

As seguintes modificações para XK e IK para sigilo direto híbrido (hfs) são conforme especificado em Noise HFS spec seção 5:

XK:                       XKhfs:
  <- s                      <- s
  ...                       ...
  -> e, es, p               -> e, es, e1, p
  <- e, ee, p               <- e, ee, ekem1, p
  -> s, se                  -> s, se
  <- p                      <- p
  p ->                      p ->


  IK:                       IKhfs:
  <- s                      <- s
  ...                       ...
  -> e, es, s, ss, p       -> e, es, e1, s, ss, p
  <- tag, e, ee, se, p     <- tag, e, ee, ekem1, se, p
  <- p                     <- p
  p ->                     p ->

  e1 and ekem1 are encrypted. See pattern definitions below.
  NOTE: e1 and ekem1 are different sizes (unlike X25519)

O padrão e1 é definido da seguinte forma, conforme especificado na seção 4 de Noise HFS spec:

For Alice:
  (encap_key, decap_key) = PQ_KEYGEN()

  // EncryptAndHash(encap_key)
  ciphertext = ENCRYPT(k, n, encap_key, ad)
  n++
  MixHash(ciphertext)

  For Bob:

  // DecryptAndHash(ciphertext)
  encap_key = DECRYPT(k, n, ciphertext, ad)
  n++
  MixHash(ciphertext)

O padrão ekem1 é definido como segue, conforme especificado na seção 4 de Noise HFS spec:

For Bob:

  (kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)

  // EncryptAndHash(kem_ciphertext)
  ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)
  MixHash(ciphertext)

  // MixKey
  MixKey(kem_shared_key)


  For Alice:

  // DecryptAndHash(ciphertext)
  kem_ciphertext = DECRYPT(k, n, ciphertext, ad)
  MixHash(ciphertext)

  // MixKey
  kem_shared_key = DECAPS(kem_ciphertext, decap_key)
  MixKey(kem_shared_key)

SigningPublicKey

Issues

  • Devemos mudar a função hash do handshake? Veja comparison. SHA256 não é vulnerável a PQ, mas se queremos atualizar nossa função hash, agora é o momento, enquanto estamos mudando outras coisas. A proposta atual do IETF SSH IETF draft é usar MLKEM768 com SHA256, e MLKEM1024 com SHA384. Esta proposta inclui uma discussão sobre as considerações de segurança.
  • Devemos parar de enviar dados de ratchet 0-RTT (além do leaseSet)?
  • Devemos mudar o ratchet de IK para XK se não enviarmos dados 0-RTT?

Overview

Esta seção aplica-se tanto aos protocolos IK quanto XK.

O handshake híbrido é definido em Noise HFS spec. A primeira mensagem, de Alice para Bob, contém e1, a chave de encapsulamento, antes da carga útil da mensagem. Isso é tratado como uma chave estática adicional; chame EncryptAndHash() nela (como Alice) ou DecryptAndHash() (como Bob). Em seguida, processe a carga útil da mensagem como de costume.

A segunda mensagem, de Bob para Alice, contém ekem1, o texto cifrado, antes da carga útil da mensagem. Isso é tratado como uma chave estática adicional; chame EncryptAndHash() nela (como Bob) ou DecryptAndHash() (como Alice). Em seguida, calcule a kem_shared_key e chame MixKey(kem_shared_key). Depois, processe a carga útil da mensagem normalmente.

Defined ML-KEM Operations

Definimos as seguintes funções correspondentes aos blocos de construção criptográficos utilizados conforme definido em FIPS 203.

(encap_key, decap_key) = PQ_KEYGEN()

Alice creates the encapsulation and decapsulation keys
The encapsulation key is sent in message 1.
encap_key and decap_key sizes vary based on ML-KEM variant.

(ciphertext, kem_shared_key) = ENCAPS(encap_key)

Bob calculates the ciphertext and shared key,
using the ciphertext received in message 1.
The ciphertext is sent in message 2.
ciphertext size varies based on ML-KEM variant.
The kem_shared_key is always 32 bytes.

kem_shared_key = DECAPS(ciphertext, decap_key)

Alice calculates the shared key,
using the ciphertext received in message 2.
The kem_shared_key is always 32 bytes.

Observe que tanto a encap_key quanto o ciphertext são criptografados dentro de blocos ChaCha/Poly nas mensagens 1 e 2 do handshake Noise. Eles serão descriptografados como parte do processo de handshake.

A kem_shared_key é misturada na chave de encadeamento com MixHash(). Veja abaixo para detalhes.

Alice KDF for Message 1

Para XK: Após o padrão de mensagem ’es’ e antes do payload, adicione:

OU

Para IK: Após o padrão de mensagem ’es’ e antes do padrão de mensagem ’s’, adicionar:

This is the "e1" message pattern:
  (encap_key, decap_key) = PQ_KEYGEN()

  // EncryptAndHash(encap_key)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  ciphertext = ENCRYPT(k, n, encap_key, ad)
  n++

  // MixHash(ciphertext)
  h = SHA256(h || ciphertext)


  End of "e1" message pattern.

  NOTE: For the next section (payload for XK or static key for IK),
  the keydata and chain key remain the same,
  and n now equals 1 (instead of 0 for non-hybrid).

Bob KDF for Message 1

Para XK: Após o padrão de mensagem ’es’ e antes da carga útil, adicione:

OU

Para IK: Após o padrão de mensagem ’es’ e antes do padrão de mensagem ’s’, adicione:

This is the "e1" message pattern:

  // DecryptAndHash(encap_key_section)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  encap_key = DECRYPT(k, n, encap_key_section, ad)
  n++

  // MixHash(encap_key_section)
  h = SHA256(h || encap_key_section)

  End of "e1" message pattern.

  NOTE: For the next section (payload for XK or static key for IK),
  the keydata and chain key remain the same,
  and n now equals 1 (instead of 0 for non-hybrid).

Bob KDF for Message 2

Para XK: Após o padrão de mensagem ’ee’ e antes do payload, adicionar:

OU

Para IK: Após o padrão de mensagem ’ee’ e antes do padrão de mensagem ‘se’, adicione:

This is the "ekem1" message pattern:

  (kem_ciphertext, kem_shared_key) = ENCAPS(encap_key)

  // EncryptAndHash(kem_ciphertext)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  ciphertext = ENCRYPT(k, n, kem_ciphertext, ad)

  // MixHash(ciphertext)
  h = SHA256(h || ciphertext)

  // MixKey(kem_shared_key)
  keydata = HKDF(chainKey, kem_shared_key, "", 64)
  chainKey = keydata[0:31]

  End of "ekem1" message pattern.

Alice KDF for Message 2

Após o padrão de mensagem ’ee’ (e antes do padrão de mensagem ‘ss’ para IK), adicione:

This is the "ekem1" message pattern:

  // DecryptAndHash(kem_ciphertext_section)
  // AEAD parameters
  k = keydata[32:63]
  n = 0
  ad = h
  kem_ciphertext = DECRYPT(k, n, kem_ciphertext_section, ad)

  // MixHash(kem_ciphertext_section)
  h = SHA256(h || kem_ciphertext_section)

  // MixKey(kem_shared_key)
  kem_shared_key = DECAPS(kem_ciphertext, decap_key)
  keydata = HKDF(chainKey, kem_shared_key, "", 64)
  chainKey = keydata[0:31]

  End of "ekem1" message pattern.

KDF for Message 3 (XK only)

inalterado

KDF for split()

inalterado

SigningPrivateKey

Atualize a especificação ECIES-Ratchet /en/docs/spec/ecies/ da seguinte forma:

Noise identifiers

  • “Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256”
  • “Noise_IKhfselg2_25519+MLKEM768_ChaChaPoly_SHA256”
  • “Noise_IKhfselg2_25519+MLKEM1024_ChaChaPoly_SHA256”

1b) New session format (with binding)

Alterações: O ratchet atual continha a chave estática na primeira seção ChaCha, e o payload na segunda seção. Com ML-KEM, agora existem três seções. A primeira seção contém a chave pública PQ criptografada. A segunda seção contém a chave estática. A terceira seção contém o payload.

Formato criptografado:

+----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   New Session Ephemeral Public Key    |
  +             32 bytes                  +
  |     Encoded with Elligator2           |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +           ML-KEM encap_key            +
  |       ChaCha20 encrypted data         |
  +      (see table below for length)     +
  |                                       |
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +    (MAC) for encap_key Section        +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +           X25519 Static Key           +
  |       ChaCha20 encrypted data         |
  +             32 bytes                  +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +    (MAC) for Static Key Section       +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +            Payload Section            +
  |       ChaCha20 encrypted data         |
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +         (MAC) for Payload Section     +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+

Formato descriptografado:

Payload Part 1:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +       ML-KEM encap_key                +
  |                                       |
  +      (see table below for length)     +
  |                                       |
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  Payload Part 2:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +       X25519 Static Key               +
  |                                       |
  +      (32 bytes)                       +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+

  Payload Part 3:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +            Payload Section            +
  |                                       |
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+

Tamanhos:

TypeType CodeX lenMsg 1 lenMsg 1 Enc lenMsg 1 Dec lenPQ key lenpl len
X2551943296+pl64+plplpl
MLKEM512_X25519532912+pl880+pl800+pl800pl
MLKEM768_X255196321296+pl1360+pl1184+pl1184pl
MLKEM1024_X255197321680+pl1648+pl1568+pl1568pl
Note que o payload deve conter um bloco DateTime, portanto o tamanho mínimo do payload é 7. Os tamanhos mínimos da mensagem 1 podem ser calculados adequadamente.

1g) New Session Reply format

Alterações: O ratchet atual tem um payload vazio para a primeira seção ChaCha, e o payload na segunda seção. Com ML-KEM, agora há três seções. A primeira seção contém o texto cifrado PQ encriptado. A segunda seção tem um payload vazio. A terceira seção contém o payload.

Formato criptografado:

+----+----+----+----+----+----+----+----+
  |       Session Tag   8 bytes           |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Ephemeral Public Key           +
  |                                       |
  +            32 bytes                   +
  |     Encoded with Elligator2           |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  | ChaCha20 encrypted ML-KEM ciphertext  |
  +      (see table below for length)     +
  ~                                       ~
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +  (MAC) for ciphertext Section         +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +  (MAC) for key Section (no data)      +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +            Payload Section            +
  |       ChaCha20 encrypted data         |
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |  Poly1305 Message Authentication Code |
  +         (MAC) for Payload Section     +
  |             16 bytes                  |
  +----+----+----+----+----+----+----+----+

Formato descriptografado:

Payload Part 1:


  +----+----+----+----+----+----+----+----+
  |                                       |
  +       ML-KEM ciphertext               +
  |                                       |
  +      (see table below for length)     +
  |                                       |
  ~                                       ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  Payload Part 2:

  empty

  Payload Part 3:

  +----+----+----+----+----+----+----+----+
  |                                       |
  +            Payload Section            +
  |                                       |
  ~                                       ~
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+

Tamanhos:

TypeType CodeY lenMsg 2 lenMsg 2 Enc lenMsg 2 Dec lenPQ CT lenopt len
X2551943272+pl32+plplpl
MLKEM512_X25519532856+pl816+pl768+pl768pl
MLKEM768_X255196321176+pl1136+pl1088+pl1088pl
MLKEM1024_X255197321656+pl1616+pl1568+pl1568pl
Note que embora a mensagem 2 normalmente tenha um payload diferente de zero, a especificação ratchet /en/docs/spec/ecies/ não o exige, então o tamanho mínimo do payload é 0. Os tamanhos mínimos da mensagem 2 podem ser calculados adequadamente.

Assinatura

Atualize a especificação NTCP2 /en/docs/spec/ntcp2/ da seguinte forma:

Noise identifiers

  • “Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM512_ChaChaPoly_SHA256”
  • “Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM768_ChaChaPoly_SHA256”
  • “Noise_XKhfsaesobfse+hs2+hs3_25519+MLKEM1024_ChaChaPoly_SHA256”

1) SessionRequest

Alterações: O NTCP2 atual contém apenas as opções na seção ChaCha. Com ML-KEM, a seção ChaCha também conterá a chave pública PQ criptografada.

Conteúdo bruto:

+----+----+----+----+----+----+----+----+
  |                                       |
  +        obfuscated with RH_B           +
  |       AES-CBC-256 encrypted X         |
  +             (32 bytes)                +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaChaPoly frame (MLKEM)            |
  +      (see table below for length)     +
  |   k defined in KDF for message 1      |
  +   n = 0                               +
  |   see KDF for associated data         |
  ~   n = 0                               ~
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   ChaChaPoly frame (options)          |
  +         32 bytes                      +
  |   k defined in KDF for message 1      |
  +   n = 0                               +
  |   see KDF for associated data         |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  ~         padding (optional)            ~
  |     length defined in options block   |
  +----+----+----+----+----+----+----+----+

  Same as before except add a second ChaChaPoly frame

Dados não criptografados (tag de autenticação Poly1305 não mostrada):

+----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |                   X                   |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |           ML-KEM encap_key            |
  +      (see table below for length)     +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |               options                 |
  +              (16 bytes)               +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  +         padding (optional)            +
  |     length defined in options block   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

Tamanhos:

TypeType CodeX lenMsg 1 lenMsg 1 Enc lenMsg 1 Dec lenPQ key lenopt len
X2551943264+pad321616
MLKEM512_X25519532880+pad84881680016
MLKEM768_X255196321264+pad12321200118416
MLKEM1024_X255197321648+pad16161584156816
Nota: Os códigos de tipo são apenas para uso interno. Os routers permanecerão do tipo 4, e o suporte será indicado nos endereços do router.

2) SessionCreated

Alterações: O NTCP2 atual contém apenas as opções na seção ChaCha. Com ML-KEM, a seção ChaCha também conterá a chave pública PQ criptografada.

Conteúdo bruto:

+----+----+----+----+----+----+----+----+
  |                                       |
  +        obfuscated with RH_B           +
  |       AES-CBC-256 encrypted Y         |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaChaPoly frame (MLKEM)            |
  +   Encrypted and authenticated data    +
  -      (see table below for length)     -
  +   k defined in KDF for message 2      +
  |   n = 0; see KDF for associated data  |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaChaPoly frame (options)          |
  +   Encrypted and authenticated data    +
  -           32 bytes                    -
  +   k defined in KDF for message 2      +
  |   n = 0; see KDF for associated data  |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  +         padding (optional)            +
  |     length defined in options block   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

  Same as before except add a second ChaChaPoly frame

Dados não criptografados (tag de autenticação Poly1305 não mostrada):

+----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |                  Y                    |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |           ML-KEM Ciphertext           |
  +      (see table below for length)     +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |               options                 |
  +              (16 bytes)               +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     unencrypted authenticated         |
  +         padding (optional)            +
  |     length defined in options block   |
  ~               .   .   .               ~
  |                                       |
  +----+----+----+----+----+----+----+----+

Tamanhos:

TypeType CodeY lenMsg 2 lenMsg 2 Enc lenMsg 2 Dec lenPQ CT lenopt len
X2551943264+pad321616
MLKEM512_X25519532848+pad81678476816
MLKEM768_X255196321136+pad11041104108816
MLKEM1024_X255197321616+pad15841584156816
Nota: Os códigos de tipo são apenas para uso interno. Os routers permanecerão tipo 4, e o suporte será indicado nos endereços do router.

3) SessionConfirmed

Inalterado

Key Derivation Function (KDF) (for data phase)

Inalterado

Certificados de Chave

Atualize a especificação SSU2 /en/docs/spec/ssu2/ da seguinte forma:

Noise identifiers

  • “Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM512_ChaChaPoly_SHA256”
  • “Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM768_ChaChaPoly_SHA256”
  • “Noise_XKhfschaobfse+hs1+hs2+hs3_25519+MLKEM1024_ChaChaPoly_SHA256”

Long Header

O cabeçalho longo tem 32 bytes. É usado antes de uma sessão ser criada, para Token Request, SessionRequest, SessionCreated e Retry. Também é usado para mensagens Peer Test e Hole Punch fora de sessão.

TODO: Poderíamos usar internamente o campo de versão e usar 3 para MLKEM512 e 4 para MLKEM768. Fazemos isso apenas para os tipos 0 e 1 ou para todos os 6 tipos?

Antes da criptografia do cabeçalho:


+----+----+----+----+----+----+----+----+
  |      Destination Connection ID        |
  +----+----+----+----+----+----+----+----+
  |   Packet Number   |type| ver| id |flag|
  +----+----+----+----+----+----+----+----+
  |        Source Connection ID           |
  +----+----+----+----+----+----+----+----+
  |                 Token                 |
  +----+----+----+----+----+----+----+----+

  Destination Connection ID :: 8 bytes, unsigned big endian integer

  Packet Number :: 4 bytes, unsigned big endian integer

  type :: The message type = 0, 1, 7, 9, 10, or 11

  ver :: The protocol version, equal to 2
         TODO We could internally use the version field and use 3 for MLKEM512 and 4 for MLKEM768.

  id :: 1 byte, the network ID (currently 2, except for test networks)

  flag :: 1 byte, unused, set to 0 for future compatibility

  Source Connection ID :: 8 bytes, unsigned big endian integer

  Token :: 8 bytes, unsigned big endian integer

Short Header

inalterado

SessionRequest (Type 0)

Mudanças: O SSU2 atual contém apenas os dados do bloco na seção ChaCha. Com ML-KEM, a seção ChaCha também conterá a chave pública PQ criptografada.

Conteúdo bruto:

+----+----+----+----+----+----+----+----+
  |  Long Header bytes 0-15, ChaCha20     |
  +  encrypted with Bob intro key         +
  |    See Header Encryption KDF          |
  +----+----+----+----+----+----+----+----+
  |  Long Header bytes 16-31, ChaCha20    |
  +  encrypted with Bob intro key n=0     +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +       X, ChaCha20 encrypted           +
  |       with Bob intro key n=0          |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   ChaCha20 encrypted data (MLKEM)     |
  +          (length varies)              +
  |  k defined in KDF for Session Request |
  +  n = 0                                +
  |  see KDF for associated data          |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |   ChaCha20 encrypted data (payload)   |
  +          (length varies)              +
  |  k defined in KDF for Session Request |
  +  n = 0                                +
  |  see KDF for associated data          |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Poly1305 MAC (16 bytes)        +
  |                                       |
  +----+----+----+----+----+----+----+----+

Dados não criptografados (tag de autenticação Poly1305 não mostrada):

+----+----+----+----+----+----+----+----+
  |      Destination Connection ID        |
  +----+----+----+----+----+----+----+----+
  |   Packet Number   |type| ver| id |flag|
  +----+----+----+----+----+----+----+----+
  |        Source Connection ID           |
  +----+----+----+----+----+----+----+----+
  |                 Token                 |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |                   X                   |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |           ML-KEM encap_key            |
  +      (see table below for length)     +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     Noise payload (block data)        |
  +          (length varies)              +
  |     see below for allowed blocks      |
  +----+----+----+----+----+----+----+----+

Tamanhos, não incluindo overhead de IP:

TypeType CodeX lenMsg 1 lenMsg 1 Enc lenMsg 1 Dec lenPQ key lenpl len
X2551943280+pl16+plplpl
MLKEM512_X25519532896+pl832+pl800+pl800pl
MLKEM768_X255196321280+pl1216+pl1184+pl1184pl
MLKEM1024_X255197n/atoo big
Nota: Os códigos de tipo são apenas para uso interno. Os routers permanecerão como tipo 4, e o suporte será indicado nos endereços do router.

MTU mínimo para MLKEM768_X25519: Cerca de 1316 para IPv4 e 1336 para IPv6.

SessionCreated (Type 1)

Alterações: O SSU2 atual contém apenas os dados do bloco na seção ChaCha. Com ML-KEM, a seção ChaCha também conterá a chave pública PQ criptografada.

Conteúdo bruto:

+----+----+----+----+----+----+----+----+
  |  Long Header bytes 0-15, ChaCha20     |
  +  encrypted with Bob intro key and     +
  | derived key, see Header Encryption KDF|
  +----+----+----+----+----+----+----+----+
  |  Long Header bytes 16-31, ChaCha20    |
  +  encrypted with derived key n=0       +
  |  See Header Encryption KDF            |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +       Y, ChaCha20 encrypted           +
  |       with derived key n=0            |
  +              (32 bytes)               +
  |       See Header Encryption KDF       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaCha20 data (MLKEM)               |
  +   Encrypted and authenticated data    +
  |  length varies                        |
  +  k defined in KDF for Session Created +
  |  n = 0; see KDF for associated data   |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |   ChaCha20 data (payload)             |
  +   Encrypted and authenticated data    +
  |  length varies                        |
  +  k defined in KDF for Session Created +
  |  n = 0; see KDF for associated data   |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +        Poly1305 MAC (16 bytes)        +
  |                                       |
  +----+----+----+----+----+----+----+----+

Dados não criptografados (tag de autenticação Poly1305 não mostrada):

+----+----+----+----+----+----+----+----+
  |      Destination Connection ID        |
  +----+----+----+----+----+----+----+----+
  |   Packet Number   |type| ver| id |flag|
  +----+----+----+----+----+----+----+----+
  |        Source Connection ID           |
  +----+----+----+----+----+----+----+----+
  |                 Token                 |
  +----+----+----+----+----+----+----+----+
  |                                       |
  +                                       +
  |                  Y                    |
  +              (32 bytes)               +
  |                                       |
  +                                       +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |           ML-KEM Ciphertext           |
  +      (see table below for length)     +
  |                                       |
  +----+----+----+----+----+----+----+----+
  |     Noise payload (block data)        |
  +          (length varies)              +
  |      see below for allowed blocks     |
  +----+----+----+----+----+----+----+----+

Tamanhos, não incluindo overhead de IP:

TypeType CodeY lenMsg 2 lenMsg 2 Enc lenMsg 2 Dec lenPQ CT lenpl len
X2551943280+pl16+plplpl
MLKEM512_X25519532864+pl800+pl768+pl768pl
MLKEM768_X255196321184+pl1118+pl1088+pl1088pl
MLKEM1024_X255197n/atoo big
Nota: Os códigos de tipo são apenas para uso interno. Os routers permanecerão tipo 4, e o suporte será indicado nos endereços do router.

MTU mínimo para MLKEM768_X25519: Aproximadamente 1316 para IPv4 e 1336 para IPv6.

SessionConfirmed (Type 2)

inalterado

KDF for data phase

inalterado

Problemas

Blocos Relay, blocos Peer Test e mensagens Peer Test contêm todas assinaturas. Infelizmente, assinaturas PQ são maiores que o MTU. Não existe atualmente nenhum mecanismo para fragmentar blocos Relay ou Peer Test ou mensagens através de múltiplos pacotes UDP. O protocolo deve ser estendido para suportar fragmentação. Isso será feito em uma proposta separada a ser determinada. Até que isso seja concluído, Relay e Peer Test não serão suportados.

Visão Geral

Poderíamos usar internamente o campo de versão e usar 3 para MLKEM512 e 4 para MLKEM768.

Para as mensagens 1 e 2, MLKEM768 aumentaria os tamanhos de pacote além do MTU mínimo de 1280. Provavelmente simplesmente não seria suportado para essa conexão se o MTU fosse muito baixo.

Para as mensagens 1 e 2, MLKEM1024 aumentaria o tamanho dos pacotes além do MTU máximo de 1500. Isso exigiria fragmentar as mensagens 1 e 2, e seria uma grande complicação. Provavelmente não faremos isso.

Relay e Peer Test: Veja acima

Tamanhos de destino

TODO: Existe uma forma mais eficiente de definir assinatura/verificação para evitar copiar a assinatura?

Tamanhos de RouterIdent

TODO

IETF draft seção 8.1 proíbe HashML-DSA em certificados X.509 e não atribui OIDs para HashML-DSA, devido a complexidades de implementação e segurança reduzida.

Para assinaturas somente PQ de arquivos SU3, use os OIDs definidos em IETF draft das variantes não-prehash para os certificados. Não definimos assinaturas híbridas de arquivos SU3, porque talvez tenhamos que fazer hash dos arquivos duas vezes (embora HashML-DSA e X2559 usem a mesma função hash SHA512). Além disso, concatenar duas chaves e assinaturas em um certificado X.509 seria completamente fora do padrão.

Note que não permitimos assinatura Ed25519 de arquivos SU3, e embora tenhamos definido assinatura Ed25519ph, nunca concordamos com um OID para isso, ou o utilizamos.

Os tipos de assinatura normais são proibidos para arquivos SU3; use as variantes ph (prehash).

Padrões de Handshake

O novo tamanho máximo do Destination será 2599 (3468 em base 64).

Atualizar outros documentos que fornecem orientação sobre tamanhos de Destination, incluindo:

  • SAMv3
  • Bittorrent
  • Diretrizes para desenvolvedores
  • Nomenclatura / catálogo de endereços / servidores de redirecionamento
  • Outros documentos

Overhead Analysis

KDF do Handshake Noise

Aumento de tamanho (bytes):

TypePubkey (Msg 1)Cipertext (Msg 2)
MLKEM512_X25519+816+784
MLKEM768_X25519+1200+1104
MLKEM1024_X25519+1584+1584
Velocidade:

Velocidades conforme reportado por Cloudflare:

TypeRelative speed
X25519 DH/keygenbaseline
MLKEM5122.25x faster
MLKEM7681.5x faster
MLKEM10241x (same)
XK4x DH (keygen + 3 DH)
MLKEM512_X255194x DH + 2x PQ (keygen + enc/dec) = 4.9x DH = 22% slower
MLKEM768_X255194x DH + 2x PQ (keygen + enc/dec) = 5.3x DH = 32% slower
MLKEM1024_X255194x DH + 2x PQ (keygen + enc/dec) = 6x DH = 50% slower
Resultados preliminares de teste em Java:
TypeRelative DH/encapsDH/decapskeygen
X25519baselinebaselinebaseline
MLKEM51229x faster22x faster17x faster
MLKEM76817x faster14x faster9x faster
MLKEM102412x faster10x faster6x faster

Signatures

Tamanho:

Tamanhos típicos de chave, assinatura, RIdent, Dest ou aumentos de tamanho (Ed25519 incluído para referência) assumindo tipo de criptografia X25519 para RIs. Tamanho adicionado para um Router Info, LeaseSet, datagramas respondíveis, e cada um dos dois pacotes streaming (SYN e SYN ACK) listados. Destinations e Leasesets atuais contêm preenchimento repetido e são compressíveis em trânsito. Novos tipos não contêm preenchimento e não serão compressíveis, resultando em um aumento de tamanho muito maior em trânsito. Veja a seção de design acima.

TypePubkeySigKey+SigRIdentDestRInfoLS/Streaming/Datagram (each msg)
EdDSA_SHA512_Ed25519326496391391baselinebaseline
MLDSA4413122420373213511319+3316+3284
MLDSA6519523309526119911959+5668+5636
MLDSA8725924627721926312599+7072+7040
MLDSA44_EdDSA_SHA512_Ed2551913442484382813831351+3412+3380
MLDSA65_EdDSA_SHA512_Ed2551919843373535720231991+5668+5636
MLDSA87_EdDSA_SHA512_Ed2551926244691731526632631+7488+7456
Velocidade:

Velocidades conforme reportado por Cloudflare:

TypeRelative speed signverify
EdDSA_SHA512_Ed25519baselinebaseline
MLDSA445x slower2x faster
MLDSA65??????
MLDSA87??????
Resultados preliminares de teste em Java:
TypeRelative speed signverifykeygen
EdDSA_SHA512_Ed25519baselinebaselinebaseline
MLDSA444.6x slower1.7x faster2.6x faster
MLDSA658.1x slowersame1.5x faster
MLDSA8711.1x slower1.5x slowersame

Security Analysis

As categorias de segurança NIST estão resumidas no NIST presentation slide 10. Critérios preliminares: Nossa categoria mínima de segurança NIST deve ser 2 para protocolos híbridos e 3 para PQ-only.

CategoryAs Secure As
1AES128
2SHA256
3AES192
4SHA384
5AES256

Handshakes

Todos estes são protocolos híbridos. Provavelmente é preciso preferir MLKEM768; MLKEM512 não é seguro o suficiente.

Categorias de segurança NIST FIPS 203:

AlgorithmSecurity Category
MLKEM5121
MLKEM7683
MLKEM10245

Signatures

Esta proposta define tipos de assinatura tanto híbridos quanto somente PQ. MLDSA44 híbrido é preferível ao MLDSA65 somente PQ. Os tamanhos de chaves e assinaturas para MLDSA65 e MLDSA87 são provavelmente muito grandes para nós, pelo menos inicialmente.

Categorias de segurança NIST FIPS 204:

AlgorithmSecurity Category
MLDSA442
MLKEM673
MLKEM875

Type Preferences

Embora vamos definir e implementar 3 tipos de criptografia e 9 tipos de assinatura, planejamos medir o desempenho durante o desenvolvimento e analisar ainda mais os efeitos do aumento dos tamanhos das estruturas. Também continuaremos a pesquisar e monitorar desenvolvimentos em outros projetos e protocolos.

Após um ano ou mais de desenvolvimento, tentaremos definir um tipo preferido ou padrão para cada caso de uso. A seleção exigirá fazer compensações entre largura de banda, CPU e nível de segurança estimado. Nem todos os tipos podem ser adequados ou permitidos para todos os casos de uso.

As preferências preliminares são as seguintes, sujeitas a alterações:

Criptografia: MLKEM768_X25519

Assinaturas: MLDSA44_EdDSA_SHA512_Ed25519

As restrições preliminares são as seguintes, sujeitas a alterações:

Criptografia: MLKEM1024_X25519 não permitido para SSU2

Assinaturas: MLDSA87 e variante híbrida provavelmente muito grandes; MLDSA65 e variante híbrida podem ser muito grandes

Implementation Notes

Library Support

As bibliotecas Bouncycastle, BoringSSL e WolfSSL agora suportam MLKEM e MLDSA. O suporte do OpenSSL estará no lançamento 3.5 em 8 de abril de 2025 OpenSSL.

A biblioteca Noise do southernstorm.com adaptada pelo Java I2P continha suporte preliminar para handshakes híbridos, mas nós o removemos por não estar sendo usado; teremos que adicioná-lo de volta e atualizá-lo para corresponder a Noise HFS spec.

Signing Variants

Utilizaremos a variante de assinatura “hedged” ou randomizada, não a variante “determinística”, conforme definido em FIPS 204 seção 3.4. Isso garante que cada assinatura seja diferente, mesmo quando sobre os mesmos dados, e fornece proteção adicional contra ataques de canal lateral. Embora FIPS 204 especifique que a variante “hedged” é o padrão, isso pode ou não ser verdadeiro em várias bibliotecas. Os implementadores devem garantir que a variante “hedged” seja usada para assinatura.

Usamos o processo de assinatura normal (chamado Pure ML-DSA Signature Generation) que codifica a mensagem internamente como 0x00 || len(ctx) || ctx || message, onde ctx é algum valor opcional de tamanho 0x00..0xFF. Não estamos usando nenhum contexto opcional. len(ctx) == 0. Este processo é definido em FIPS 204 Algoritmo 2 passo 10 e Algoritmo 3 passo 5. Note que alguns vetores de teste publicados podem exigir a definição de um modo onde a mensagem não é codificada.

Reliability

O aumento do tamanho resultará em muito mais fragmentação de túnel para armazenamentos NetDB, handshakes de streaming e outras mensagens. Verifique mudanças de desempenho e confiabilidade.

Structure Sizes

Encontre e verifique qualquer código que limite o tamanho em bytes de router infos e leaseSets.

NetDB

Revisar e possivelmente reduzir o máximo de LS/RI armazenados na RAM ou no disco, para limitar o aumento de armazenamento. Aumentar os requisitos mínimos de largura de banda para floodfills?

Ratchet

Operações ML-KEM Definidas

A auto-classificação/detecção de múltiplos protocolos nos mesmos tunnels deve ser possível baseada numa verificação de comprimento da mensagem 1 (New Session Message). Usando MLKEM512_X25519 como exemplo, o comprimento da mensagem 1 é 816 bytes maior que o protocolo ratchet atual, e o tamanho mínimo da mensagem 1 (com apenas um payload DateTime incluído) é 919 bytes. A maioria dos tamanhos de mensagem 1 com o ratchet atual tem um payload inferior a 816 bytes, então podem ser classificados como ratchet não-híbrido. Mensagens grandes são provavelmente POSTs que são raros.

Portanto, a estratégia recomendada é:

  • Se a mensagem 1 tiver menos de 919 bytes, é o protocolo ratchet atual.
  • Se a mensagem 1 tiver 919 bytes ou mais, provavelmente é MLKEM512_X25519. Tente MLKEM512_X25519 primeiro e, se falhar, tente o protocolo ratchet atual.

Isso deve nos permitir suportar eficientemente ratchet padrão e ratchet híbrido no mesmo destino, assim como anteriormente suportávamos ElGamal e ratchet no mesmo destino. Portanto, podemos migrar para o protocolo híbrido MLKEM muito mais rapidamente do que se não pudéssemos suportar protocolos duplos para o mesmo destino, porque podemos adicionar suporte MLKEM a destinos existentes.

As combinações suportadas obrigatórias são:

  • X25519 + MLKEM512
  • X25519 + MLKEM768
  • X25519 + MLKEM1024

As seguintes combinações podem ser complexas, e NÃO são obrigatórias de serem suportadas, mas podem ser, dependendo da implementação:

  • Mais de um MLKEM
  • ElG + um ou mais MLKEM
  • X25519 + um ou mais MLKEM
  • ElG + X25519 + um ou mais MLKEM

Podemos não tentar suportar múltiplos algoritmos MLKEM (por exemplo, MLKEM512_X25519 e MLKEM_768_X25519) no mesmo destino. Escolha apenas um; no entanto, isso depende de selecionarmos uma variante MLKEM preferida, para que os túneis de cliente HTTP possam usar uma. Dependente da implementação.

Nós PODEMOS tentar suportar três algoritmos (por exemplo X25519, MLKEM512_X25519, e MLKEM769_X25519) no mesmo destino. A classificação e estratégia de repetição podem ser muito complexas. A configuração e interface de configuração podem ser muito complexas. Dependente da implementação.

Provavelmente NÃO tentaremos suportar algoritmos ElGamal e híbridos no mesmo destino. ElGamal é obsoleto, e ElGamal + híbrido apenas (sem X25519) não faz muito sentido. Além disso, as Mensagens de Nova Sessão ElGamal e Híbrida são ambas grandes, então as estratégias de classificação frequentemente teriam que tentar ambas as descriptografias, o que seria ineficiente. Dependente da implementação.

Os clientes podem usar as mesmas chaves estáticas X25519 ou chaves diferentes para os protocolos X25519 e híbrido nos mesmos túneis, dependendo da implementação.

Alice KDF para Mensagem 1

A especificação ECIES permite Garlic Messages no payload da New Session Message, o que possibilita a entrega 0-RTT do pacote de streaming inicial, geralmente um HTTP GET, juntamente com o leaseset do cliente. No entanto, o payload da New Session Message não possui forward secrecy. Como esta proposta está enfatizando forward secrecy aprimorada para ratchet, as implementações podem ou devem adiar a inclusão do payload de streaming, ou da mensagem de streaming completa, até a primeira Existing Session Message. Isso seria às custas da entrega 0-RTT. As estratégias também podem depender do tipo de tráfego ou tipo de túnel, ou de GET vs. POST, por exemplo. Dependente da implementação.

Bob KDF para Mensagem 1

MLKEM, MLDSA, ou ambos no mesmo destino, aumentarão drasticamente o tamanho da New Session Message, como descrito acima. Isso pode diminuir significativamente a confiabilidade da entrega da New Session Message através de tunnels, onde elas devem ser fragmentadas em múltiplas mensagens de tunnel de 1024 bytes. O sucesso da entrega é proporcional ao número exponencial de fragmentos. As implementações podem usar várias estratégias para limitar o tamanho da mensagem, às custas da entrega 0-RTT. Dependente da implementação.

Ratchet

Podemos definir o MSB da chave efêmera (key[31] & 0x80) na solicitação de sessão para indicar que esta é uma conexão híbrida. Isso nos permitiria executar tanto NTCP padrão quanto NTCP híbrido na mesma porta. Apenas uma variante híbrida seria suportada e anunciada no endereço do router. Por exemplo, v=2,3 ou v=2,4 ou v=2,5.

Se não fizermos isso, precisamos de um endereço/porta de transporte diferente e um novo nome de protocolo como “NTCP1PQ1”.

Nota: Os códigos de tipo são apenas para uso interno. Os routers permanecerão tipo 4, e o suporte será indicado nos endereços do router.

TODO

SSU2

PODE precisar de endereço/porta de transporte diferentes, mas esperamos que não, temos um cabeçalho com flags para a mensagem 1. Poderíamos usar internamente o campo de versão e usar 3 para MLKEM512 e 4 para MLKEM768. Talvez apenas v=2,3,4 no endereço seria suficiente. Mas precisamos de identificadores para ambos os novos algoritmos: 3a, 3b?

Verifique e confirme que o SSU2 pode lidar com o RI fragmentado em múltiplos pacotes (6-8?). O i2pd atualmente suporta apenas 2 fragmentos no máximo?

Nota: Os códigos de tipo são apenas para uso interno. Os routers permanecerão como tipo 4, e o suporte será indicado nos endereços do router.

TODO

Router Compatibility

Transport Names

Provavelmente não precisaremos de novos nomes de transporte, se conseguirmos executar tanto o padrão quanto o híbrido na mesma porta, com flags de versão.

Se precisarmos de novos nomes de transporte, eles seriam:

TransportType
NTCP2PQ1MLKEM512_X25519
NTCP2PQ2MLKEM768_X25519
NTCP2PQ3MLKEM1024_X25519
SSU2PQ1MLKEM512_X25519
SSU2PQ2MLKEM768_X25519
Note que o SSU2 não consegue suportar MLKEM1024, é muito grande.

Router Enc. Types

Temos várias alternativas a considerar:

Bob KDF para Mensagem 2

Não recomendado. Use apenas os novos transportes listados acima que correspondem ao tipo de router. Routers mais antigos não conseguem conectar, construir tunnels através de, ou enviar mensagens netDb para. Levaria vários ciclos de lançamento para debugar e garantir suporte antes de habilitar por padrão. Pode estender o rollout por um ano ou mais em relação às alternativas abaixo.

KDF da Alice para Mensagem 2

Recomendado. Como o PQ não afeta a chave estática X25519 ou os protocolos de handshake N, poderíamos deixar os routers como tipo 4, e apenas anunciar novos transportes. Routers mais antigos ainda poderiam se conectar, construir túneis através deles, ou enviar mensagens netDb para eles.

KDF para Mensagem 3 (apenas XK)

Roteadores Tipo 4 podem anunciar endereços tanto NTCP2 quanto NTCP2PQ*. Estes podem usar a mesma chave estática e outros parâmetros, ou não. Provavelmente precisarão estar em portas diferentes; seria muito difícil suportar ambos os protocolos NTCP2 e NTCP2PQ* na mesma porta, já que não há cabeçalho ou enquadramento que permitiria ao Bob classificar e enquadrar a mensagem Session Request recebida.

Portas e endereços separados serão difíceis para o Java, mas simples para o i2pd.

KDF para split()

Routers tipo 4 poderiam anunciar endereços tanto SSU2 quanto SSU2PQ*. Com flags de cabeçalho adicionais, Bob poderia identificar o tipo de transporte de entrada na primeira mensagem. Portanto, poderíamos suportar tanto SSU2 quanto SSUPQ* na mesma porta.

Estes poderiam ser publicados como endereços separados (como o i2pd fez em transições anteriores) ou no mesmo endereço com um parâmetro indicando suporte PQ (como o Java i2p fez em transições anteriores).

Se no mesmo endereço, ou na mesma porta em endereços diferentes, estes usariam a mesma chave estática e outros parâmetros. Se em endereços diferentes com portas diferentes, estes poderiam usar a mesma chave estática e outros parâmetros, ou não.

Portas e endereços separados serão difíceis para o Java, mas diretos para o i2pd.

Recommendations

TODO

NTCP2

Identificadores Noise

Routers mais antigos verificam RIs e, portanto, não conseguem se conectar, construir túneis através de, ou enviar mensagens netDb para. Levaria vários ciclos de lançamento para depurar e garantir suporte antes de habilitar por padrão. Seriam os mesmos problemas do rollout de enc. type 5/6/7; poderia estender o rollout por um ano ou mais sobre a alternativa de rollout de enc. type 4 listada acima.

Sem alternativas.

LS Enc. Types

1b) Novo formato de sessão (com binding)

Estes podem estar presentes no LS com chaves X25519 do tipo 4 mais antigas. Routers mais antigos irão ignorar chaves desconhecidas.

Os destinos podem suportar múltiplos tipos de chave, mas apenas fazendo descriptografias de teste da mensagem 1 com cada chave. A sobrecarga pode ser mitigada mantendo contadores de descriptografias bem-sucedidas para cada chave, e tentando a chave mais usada primeiro. O Java I2P usa esta estratégia para ElGamal+X25519 no mesmo destino.

Dest. Sig. Types

1g) Formato de Resposta de Nova Sessão

Routers verificam assinaturas de leaseSet e, portanto, não conseguem conectar ou receber leaseSets para destinos tipo 12-17. Levaria vários ciclos de lançamento para depurar e garantir o suporte antes de habilitar por padrão.

Nenhuma alternativa.

Especificação

Os dados mais valiosos são o tráfego de ponta a ponta, criptografado com ratchet. Como um observador externo entre saltos de tunnel, isso está criptografado duas vezes mais, com criptografia de tunnel e criptografia de transporte. Como um observador externo entre OBEP e IBGW, está criptografado apenas uma vez mais, com criptografia de transporte. Como um participante OBEP ou IBGW, o ratchet é a única criptografia. No entanto, como os tunnels são unidirecionais, capturar ambas as mensagens no handshake ratchet exigiria roteadores em conluio, a menos que os tunnels fossem construídos com o OBEP e IBGW no mesmo roteador.

O modelo de ameaça PQ mais preocupante atualmente é armazenar tráfego hoje, para descriptografia daqui a muitos e muitos anos (sigilo progressivo). Uma abordagem híbrida protegeria contra isso.

O modelo de ameaça PQ de quebrar as chaves de autenticação em um período de tempo razoável (digamos alguns meses) e então personificar a autenticação ou descriptografar em quase tempo real, está muito mais distante? E é quando gostaríamos de migrar para chaves estáticas PQC.

Então, o modelo de ameaça PQ mais antigo é o OBEP/IBGW armazenando tráfego para descriptografia posterior. Devemos implementar ratchet híbrido primeiro.

Ratchet é a prioridade mais alta. Transportes são os próximos. Assinaturas são a prioridade mais baixa.

O lançamento de assinaturas também será um ano ou mais tarde do que o lançamento de criptografia, porque não é possível compatibilidade com versões anteriores. Além disso, a adoção do MLDSA na indústria será padronizada pelo CA/Browser Forum e pelas Autoridades Certificadoras. As CAs precisam primeiro do suporte de módulo de segurança de hardware (HSM), que não está disponível atualmente CA/Browser Forum. Esperamos que o CA/Browser Forum conduza as decisões sobre escolhas específicas de parâmetros, incluindo se deve apoiar ou exigir assinaturas compostas IETF draft.

MilestoneTarget
Ratchet betaLate 2025
Select best enc typeEarly 2026
NTCP2 betaEarly 2026
SSU2 betaMid 2026
Ratchet productionMid 2026
Ratchet defaultLate 2026
Signature betaLate 2026
NTCP2 productionLate 2026
SSU2 productionEarly 2027
Select best sig typeEarly 2027
NTCP2 defaultEarly 2027
SSU2 defaultMid 2027
Signature productionMid 2027

Migration

Se não conseguirmos suportar tanto os protocolos ratchet antigos quanto os novos nos mesmos tunnels, a migração será muito mais difícil.

Devemos ser capazes de simplesmente tentar um-depois-do-outro, como fizemos com X25519, para ser comprovado.

Issues

  • Seleção de Hash Noise - manter SHA256 ou atualizar? SHA256 deve ser bom por mais 20-30 anos, não ameaçado por PQ, Ver NIST presentation e NIST presentation. Se SHA256 for quebrado, temos problemas piores (netDb).
  • NTCP2 porta separada, endereço de router separado
  • SSU2 relay / teste de peer
  • Campo de versão SSU2
  • Versão de endereço de router SSU2