I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
169-pq-crypto.rst 60.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • zzz's avatar
    zzz committed
    ===================================
    Post-Quantum Crypto Protocols
    ===================================
    .. meta::
        :author: zzz
        :created: 2025-01-21
        :thread: http://zzz.i2p/topics/3294
    
    zzz's avatar
    zzz committed
        :lastupdated: 2025-02-18
    
    zzz's avatar
    zzz committed
        :status: Open
        :target: 0.9.80
    
    .. contents::
    
    
    
    
    
    
    Overview
    ========
    
    While research and competition for suitable post-quantum (PQ)
    
    zzz's avatar
    zzz committed
    cryptography have been proceeding for a decade, the choices
    
    zzz's avatar
    zzz committed
    have not become clear until recently.
    
    We started looking at the implications of PQ crypto
    in 2022 [FORUM]_.
    
    
    zzz's avatar
    zzz committed
    TLS standards added hybrid encryption support in the last two years and it now
    is used for a significant portion of encrypted traffic on the internet
    due to support in Chrome and Firefox [CLOUDFLARE]_.
    
    zzz's avatar
    zzz committed
    
    NIST recently finalized and published the recommended algorithms
    for post-quantum cryptography [NIST-PQ]_.
    
    zzz's avatar
    zzz committed
    Several common cryptography libraries now support the NIST standards
    or will be releasing support in the near future.
    
    zzz's avatar
    zzz committed
    
    Both [CLOUDFLARE]_ and [NIST-PQ]_ recommend that migration start immediately.
    See also the 2022 NSA PQ FAQ [NSA-PQ]_.
    I2P should be a leader in security and cryptography.
    Now is the time to implement the recommended algorithms.
    Using our flexible crypto type and signature type system,
    we will add types for hybrid crypto, and for PQ and hybrid signatures.
    
    
    Goals
    =====
    
    - Select PQ-resistant algorithms
    - Add PQ-only and hybrid algorithms to I2P protocols where appropriate
    - Select best variants after implementation, testing, analysis, and research
    - Add support incrementally and with backward compatibility
    
    
    Non-Goals
    =========
    
    
    zzz's avatar
    zzz committed
    - Don't change one-way (Noise N) encryption protocols
    
    
    Threat Model
    ============
    
    - Routers at the OBEP or IBGW, possibly colluding,
      storing garlic messages for later decryption (forward secrecy)
    - Network observers
      storing transport messages for later decryption (forward secrecy)
    - Network participants forging signatures for RI, LS, streaming, datagrams,
      or other structures
    
    zzz's avatar
    zzz committed
    
    
    
    Design
    ======
    
    We will support the NIST FIPS 203 and 204 standards [FIPS203]_ [FIPS204]_
    which are based on, but NOT compatible with,
    CRYSTALS-Kyber and CRYSTALS-Dilithium (versions 3.1, 3, and older).
    
    
    
    Key Exchange
    -------------
    
    We will support key exchange in the following protocols:
    
    =======  ==========  ==============  ===============
    Proto    Noise Type  Support PQ?     Support Hybrid?
    =======  ==========  ==============  ===============
    NTCP2       XK       no              yes
    SSU2        XK       no              yes
    Ratchet     IK       no              yes
    TBM          N       no              no
    NetDB        N       no              no
    =======  ==========  ==============  ===============
    
    PQ KEM provides ephemeral keys only, and does not directly support
    static-key handshakes such as Noise XK and IK.
    While there is some recent research [PQ-WIREGUARD]_ on adapting Wireguard (IK)
    for pure PQ crypto, there are several open questions, and
    this approach is unproven.
    
    Noise N does not use a two-way key exchange and so it is not suitable
    for hybrid encryption.
    
    So we will support hybrid encryption only, for NTCP2, SSU2, and Ratchet.
    We will define the three ML-KEM variants as in [FIPS203]_,
    for 3 new encryption types total.
    Hybrid types will only be defined in combination with X25519.
    
    
    zzz's avatar
    zzz committed
    The new encryption types are:
    
    
    zzz's avatar
    zzz committed
    ================  ====
      Type            Code
    ================  ====
    MLKEM512_X25519     5
    MLKEM768_X25519     6
    MLKEM1024_X25519    7
    ================  ====
    
    zzz's avatar
    zzz committed
    
    
    zzz's avatar
    zzz committed
    Overhead will be substantial. Typical message 1 and 2 sizes (for XK and IK)
    are currently around 100 bytes (before any additional payload).
    This will increase by 8x to 15x depending on algorithm.
    
    
    Signatures
    -----------
    
    We will support PQ and hybrid signatures in the following structures:
    
    ==========================  ==============  ===============
    Type                        Support PQ?     Support Hybrid?
    ==========================  ==============  ===============
    RouterInfo                  yes             yes
    LeaseSet                    yes             yes
    Streaming SYN/SYNACK/Close  yes             yes
    Repliable Datagrams         yes             yes
    I2CP create session msg     yes             yes
    SU3 files                   yes             yes
    X.509 certificates          yes             yes
    Java keystores              yes             yes
    ==========================  ==============  ===============
    
    
    So we will support both PQ-only and hybrid signatures.
    We will define the three ML-DSA variants as in [FIPS204]_,
    for 6 new signature types total.
    Hybrid types will only be defined in combination with Ed25519.
    We will use the standard ML-DSA, NOT the pre-hash variants (HashML-DSA).
    
    
    zzz's avatar
    zzz committed
    The new signature types are:
    
    
    zzz's avatar
    zzz committed
    ============================  ====
            Type                  Code
    ============================  ====
    MLDSA44_EdDSA_SHA512_Ed25519   12
    MLDSA65_EdDSA_SHA512_Ed25519   13
    MLDSA87_EdDSA_SHA512_Ed25519   14
    MLDSA44                        15
    MLDSA65                        16
    MLDSA87                        17
    ============================  ====
    
    zzz's avatar
    zzz committed
    
    
    zzz's avatar
    zzz committed
    X.509 certificates and other DER encodings will use the
    composite structures and OIDs defined in [COMPOSITE-SIGS]_.
    
    Overhead will be substantial. Typical Ed25519 destination and router identity
    sizes are 391 bytes.
    These will increase by 3.5x to 6.8x depending on algorithm.
    Ed25519 signatures are 64 bytes.
    These will increase by 38x to 76x depending on algorithm.
    Typical signed RouterInfo, LeaseSet, repliable datagrams, and signed streaming messages are about 1KB.
    These will increase by 3x to 8x depending on algorithm.
    
    As the new destination and router identity types will not contain padding,
    they will not be compressible. Sizes of destinations and router identities
    that are gzipped in-transit will increase by 12x - 38x depending on algorithm.
    
    TODO: Add RSA4096 hybrid types for su3?
    
    
    
    zzz's avatar
    zzz committed
    Legal Combinations
    ------------------
    
    zzz's avatar
    zzz committed
    
    For Destinations, the new signature types are supported with all encryption
    
    zzz's avatar
    zzz committed
    types in the leaseset. Set the encryption type in the key certificate to NULL (255).
    
    zzz's avatar
    zzz committed
    
    For RouterIdentities, ElGamal encryption type is deprecated.
    The new signature types are supported with X25519 (type 4) encryption only.
    The new encryption types will be indicated in the RouterAddresses.
    The encryption type in the key certificate will continue to be type 4.
    
    
    
    
    zzz's avatar
    zzz committed
    New Crypto Required
    -------------------
    
    - ML-KEM (formerly CRYSTALS-Kyber) [FIPS203]_
    - ML-DSA (formerly CRYSTALS-Dilithium) [FIPS204]_
    
    zzz's avatar
    zzz committed
    - SHA3-128 (formerly Keccak-256) [FIPS202]_ Used only for SHAKE128
    
    zzz's avatar
    zzz committed
    - SHA3-256 (formerly Keccak-512) [FIPS202]_
    - SHAKE128 and SHAKE256 (XOF extensions to SHA3-128 and SHA3-256) [FIPS202]_
    
    
    zzz's avatar
    zzz committed
    Test vectors for SHA3-256, SHAKE128, and SHAKE256 are at [NIST-VECTORS]_.
    
    
    zzz's avatar
    zzz committed
    Note that the Java bouncycastle library supports all the above.
    
    zzz's avatar
    zzz committed
    C++ library support will be in OpenSSL 3.5 [OPENSSL]_.
    
    zzz's avatar
    zzz committed
    
    
    Alternatives
    -------------
    
    We will not support [FIPS205]_ (Sphincs+), it is much much slower and bigger than ML-DSA.
    We will not support the upcoming FIPS206 (Falcon), it is not yet standardized.
    
    zzz's avatar
    zzz committed
    We will not support NTRU or other PQ candidates that were not standardized by NIST.
    
    zzz's avatar
    zzz committed
    
    
    Specification
    =============
    
    Common Structures
    -----------------
    
    PublicKey
    
    zzz's avatar
    zzz committed
    ````````````````
    
    zzz's avatar
    zzz committed
    
    ================    ================= ======  =====
      Type              Public Key Length Since   Usage
    ================    ================= ======  =====
    MLKEM512_X25519               32      0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM768_X25519               32      0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM1024_X25519              32      0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM512                     800      0.9.xx  See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
    MLKEM768                    1184      0.9.xx  See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
    MLKEM1024                   1568      0.9.xx  See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
    
    zzz's avatar
    zzz committed
    NULL                           0      0.9.xx  See proposal 169, for destinations with PQ sig types only, not for RIs or Leasesets
    
    zzz's avatar
    zzz committed
    ================    ================= ======  =====
    
    Hybrid public keys are the X25519 key.
    KEM public keys are the ephemeral PQ key sent from Alice to Bob.
    
    Byte order defined in [FIPS203]_.
    
    zzz's avatar
    zzz committed
    
    
    PrivateKey
    
    zzz's avatar
    zzz committed
    ````````````````
    
    zzz's avatar
    zzz committed
    
    ================    ================== ======  =====
      Type              Private Key Length Since   Usage
    ================    ================== ======  =====
    MLKEM512_X25519               32       0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM768_X25519               32       0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM1024_X25519              32       0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM512                    1632       0.9.xx  See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
    MLKEM768                    2400       0.9.xx  See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
    MLKEM1024                   3168       0.9.xx  See proposal 169, for handshakes only, not for Leasesets, RIs or Destinations
    ================    ================== ======  =====
    
    Hybrid private keys are the X25519 key followed by the PQ key.
    KEM private keys are the ciphertext sent from Bob to Alice.
    
    Byte order defined in [FIPS203]_.
    
    zzz's avatar
    zzz committed
    
    
    
    
    SigningPublicKey
    
    zzz's avatar
    zzz committed
    ````````````````
    
    zzz's avatar
    zzz committed
    
    
    ============================   ==============  ======  =====
             Type                  Length (bytes)  Since   Usage
    ============================   ==============  ======  =====
    MLDSA44_EdDSA_SHA512_Ed25519         1344      0.9.xx  See proposal 169
    MLDSA65_EdDSA_SHA512_Ed25519         1984      0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA87_EdDSA_SHA512_Ed25519         2624      0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA44                              1312      0.9.xx  See proposal 169
    MLDSA65                              1952      0.9.xx  See proposal 169
    MLDSA87                              2592      0.9.xx  See proposal 169
    ============================   ==============  ======  =====
    
    Hybrid signing public keys are the Ed25519 key followed by the PQ key.
    
    Byte order defined in [FIPS204]_.
    
    zzz's avatar
    zzz committed
    
    
    SigningPrivateKey
    `````````````````
    
    ============================   ==============  ======  =====
             Type                  Length (bytes)  Since   Usage
    ============================   ==============  ======  =====
    MLDSA44_EdDSA_SHA512_Ed25519         2592      0.9.xx  See proposal 169
    MLDSA65_EdDSA_SHA512_Ed25519         4064      0.9.xx  See proposal 169
    MLDSA87_EdDSA_SHA512_Ed25519         4928      0.9.xx  See proposal 169
    MLDSA44                              2560      0.9.xx  See proposal 169
    MLDSA65                              4032      0.9.xx  See proposal 169
    MLDSA87                              4896      0.9.xx  See proposal 169
    ============================   ==============  ======  =====
    
    Hybrid signing private keys are the Ed25519 key followed by the PQ key.
    
    Byte order defined in [FIPS204]_.
    
    zzz's avatar
    zzz committed
    
    
    Signature
    ``````````
    ============================   ==============  ======  =====
             Type                  Length (bytes)  Since   Usage
    ============================   ==============  ======  =====
    MLDSA44_EdDSA_SHA512_Ed25519         2484      0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA65_EdDSA_SHA512_Ed25519         3373      0.9.xx  See proposal 169
    MLDSA87_EdDSA_SHA512_Ed25519         4691      0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA44                              2420      0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA65                              3309      0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA87                              4627      0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    ============================   ==============  ======  =====
    
    Hybrid signatures are the Ed25519 signature followed by the PQ signature.
    Hybrid signatures are verified by verifying both signatures, and failing
    if either one fails.
    
    Byte order defined in [FIPS204]_.
    
    zzz's avatar
    zzz committed
    
    
    
    Key Certificates
    ````````````````
    
    The defined Signing Public Key types are:
    
    ============================  ===========  =======================  ======  =====
            Type                  Type Code    Total Public Key Length  Since   Usage
    ============================  ===========  =======================  ======  =====
    
    zzz's avatar
    zzz committed
    MLDSA44_EdDSA_SHA512_Ed25519      12                 1344           0.9.xx  See proposal 169
    MLDSA65_EdDSA_SHA512_Ed25519      13                 1984           0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA87_EdDSA_SHA512_Ed25519      14                 2624           0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    MLDSA44                           15                 1312           0.9.xx  See proposal 169
    MLDSA65                           16                 1952           0.9.xx  See proposal 169
    MLDSA87                           17                 2592           0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    NULL                             255                    0           0.9.xx  See proposal 169
    
    zzz's avatar
    zzz committed
    ============================  ===========  =======================  ======  =====
    
    
    
    The defined Crypto Public Key types are:
    
    ================    ===========  ======================= ======  =====
      Type              Type Code    Total Public Key Length Since   Usage
    ================    ===========  ======================= ======  =====
    MLKEM512_X25519          5                 32            0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM768_X25519          6                 32            0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    MLKEM1024_X25519         7                 32            0.9.xx  See proposal 169, for Leasesets only, not for RIs or Destinations
    ================    ===========  ======================= ======  =====
    
    
    Hybrid key types are NEVER included in key certificates; only in leasesets.
    
    
    zzz's avatar
    zzz committed
    For destinations with Hybrid or PQ signature types,
    
    zzz's avatar
    zzz committed
    use NULL (type 255) for the encryption type,
    
    zzz's avatar
    zzz committed
    but there is no crypto key, and the
    
    zzz's avatar
    zzz committed
    entire 384-byte main section is for the signing key.
    
    
    Destination sizes
    ``````````````````
    
    Here are lengths for the new Destination types.
    
    zzz's avatar
    zzz committed
    Enc type for all is NULL (type 255) and the encryption key length is treated as 0.
    
    zzz's avatar
    zzz committed
    The entire 384-byte section is used for the first part of the signing public key.
    
    zzz's avatar
    zzz committed
    NOTE: This is different than the spec for the ECDSA_SHA512_P521
    and the RSA signature types, where we maintained the 256-byte ElGamal
    key in the destination even though it was unused.
    
    
    zzz's avatar
    zzz committed
    No padding.
    Total length is 7 + total key length.
    Key certificate length is 4 + excess key length.
    
    Example 1319-byte destination byte stream for MLDSA44:
    
    skey[0:383] 5 (932 >> 8) (932 & 0xff) 00 12 00 255 skey[384:1311]
    
    
    
    ============================  ===========  =======================  ======  ======  =====
            Type                  Type Code    Total Public Key Length  Main    Excess  Total Dest Length
    ============================  ===========  =======================  ======  ======  =====
    MLDSA44_EdDSA_SHA512_Ed25519      12                 1344           384      960    1351
    MLDSA65_EdDSA_SHA512_Ed25519      13                 1984           384     1600    1991
    
    zzz's avatar
    zzz committed
    MLDSA87_EdDSA_SHA512_Ed25519      14                 2624           384     2240    2631
    
    zzz's avatar
    zzz committed
    MLDSA44                           15                 1312           384      928    1319
    MLDSA65                           16                 1952           384     1568    1959
    MLDSA87                           17                 2592           384     2208    2599
    ============================  ===========  =======================  ======  ======  =====
    
    
    
    RouterIdent sizes
    ``````````````````
    
    Here are lengths for the new Destination types.
    
    zzz's avatar
    zzz committed
    Enc type for all is X25519 (type 4).
    
    zzz's avatar
    zzz committed
    The entire 352-byte section after the X28819 public key is used for the first part of the signing public key.
    No padding.
    Total length is 39 + total key length.
    Key certificate length is 4 + excess key length.
    
    Example 1351-byte router identity byte stream for MLDSA44:
    
    enckey[0:31] skey[0:351] 5 (960 >> 8) (960 & 0xff) 00 12 00 4 skey[352:1311]
    
    
    
    ============================  ===========  =======================  ======  ======  =====
            Type                  Type Code    Total Public Key Length  Main    Excess  Total RouterIdent Length
    ============================  ===========  =======================  ======  ======  =====
    MLDSA44_EdDSA_SHA512_Ed25519      12                 1344           352      992    1383
    MLDSA65_EdDSA_SHA512_Ed25519      13                 1984           352     1632    2023
    
    zzz's avatar
    zzz committed
    MLDSA87_EdDSA_SHA512_Ed25519      14                 2624           352     2272    2663
    
    zzz's avatar
    zzz committed
    MLDSA44                           15                 1312           352      960    1351
    MLDSA65                           16                 1952           352     1600    1991
    MLDSA87                           17                 2592           352     2240    2631
    ============================  ===========  =======================  ======  ======  =====
    
    
    
    Handshake Patterns
    ------------------
    
    Handshakes use [Noise]_ handshake patterns.
    
    The following letter mapping is used:
    
    - e = one-time ephemeral key
    - s = static key
    - p = message payload
    - e1 = one-time ephemeral PQ key, sent from Alice to Bob
    - ekem1 = the KEM ciphertext, sent from Bob to Alice
    
    The following modifications to XK and IK for hybrid forward secrecy (hfs) are:
    
    .. raw:: html
    
      {% highlight lang='dataspec' %}
    
    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 ->
    
      e1 is encrypted together with the message 1 payload p
      ekem1 is encrypted together with the message 2 payload 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 is encrypted together with the message 1 alice static key s
      ekem1 is encrypted with the message 2 ee DH result state FIXME
    
    {% endhighlight %}
    
    
    
    
    Noise Handshake KDF
    ---------------------
    
    
    zzz's avatar
    zzz committed
    This section applies to both IK and XK protocols.
    
    
    zzz's avatar
    zzz committed
    The KEM 32-byte shared secret is combined or mixHash()ed or HKDF()ed into the
    final Noise shared secret, before split(), for a final 32-byte shared secret.
    Not concatenated with the DH shared secret for a 64-byte final shared secret,
    which is what TLS does [TLS-HYBRID]_.
    
    
    zzz's avatar
    zzz committed
    Defined ML-KEM Operations
    `````````````````````````
    
    We define the following functions corresponding to the cryptographic building blocks used
    as defined in [FIPS203]_.
    
    (encap_key, decap_key) = 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.
    
    (cihpertext, 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.
    
    Note that both the encap_key and the ciphertext are encrypted inside ChaCha/Poly
    blocks in the Noise handshake messages 1 and 2.
    They will be decrypted as part of the handshake process.
    
    The kem_shared_key is combined with the X25519 DH shared key to
    create a shared session key.
    See below for details.
    
    
    Alice KDF for Message 1
    `````````````````````````
    
    (encap_key, decap_key) = KEYGEN()
    
    
    Bob KDF for Message 2
    `````````````````````````
    
    (cihpertext, kem_shared_key) = ENCAPS(encap_key)
    
    
    Alice KDF for Message 2
    `````````````````````````
    
    kem_shared_key = DECAPS(ciphertext, decap_key)
    
    
    Alice/Bob KDF for split()
    `````````````````````````
    
    see below
    
    
    
    
    
    zzz's avatar
    zzz committed
    
    Ratchet
    ---------
    
    Noise identifiers:
    
    - "Noise_IKhfselg2_25519+MLKEM512_ChaChaPoly_SHA256"
    - "Noise_IKhfselg2_25519+MLKEM768_ChaChaPoly_SHA256"
    - "Noise_IKhfselg2_25519+MLKEM1024_ChaChaPoly_SHA256"
    
    
    zzz's avatar
    zzz committed
    
    
    1b) New session format (with binding)
    `````````````````````````````````````
    
    
    zzz's avatar
    zzz committed
    Changes: Current ratchet contained only the static key in the first ChaCha section.
    With ML-KEM, the first ChaCha section will also contain the encrypted PQ public key.
    
    
    
    zzz's avatar
    zzz committed
    Encrypted format:
    
    .. raw:: html
    
      {% highlight lang='dataspec' %}
    +----+----+----+----+----+----+----+----+
      |                                       |
      +                                       +
      |   New Session Ephemeral Public Key    |
      +             32 bytes                  +
      |     Encoded with Elligator2           |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
      |                                       |
    
    zzz's avatar
    zzz committed
      + ML-KEM encap_key and X25519 Static Key+
    
    zzz's avatar
    zzz committed
      |       ChaCha20 encrypted data         |
    
    zzz's avatar
    zzz committed
      +      (see table below for length)     +
    
    zzz's avatar
    zzz committed
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
      |  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                  |
      +----+----+----+----+----+----+----+----+
    
    
    
    zzz's avatar
    zzz committed
    {% endhighlight %}
    
    Decrypted format:
    
    .. raw:: html
    
    zzz's avatar
    zzz committed
    
      {% highlight lang='dataspec' %}
    
    zzz's avatar
    zzz committed
    Payload Part 1:
    
    
    zzz's avatar
    zzz committed
    
    
    zzz's avatar
    zzz committed
      +----+----+----+----+----+----+----+----+
      |                                       |
    
    zzz's avatar
    zzz committed
      +       ML-KEM encap_key                +
    
    zzz's avatar
    zzz committed
      |                                       |
      +      (see table below for length)     +
      |                                       |
      ~                                       ~
      |                                       |
      +----+----+----+----+----+----+----+----+
      |                                       |
      +       X25519 Static Key               +
      |                                       |
      +      (32 bytes)                       +
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
    
    
    zzz's avatar
    zzz committed
      Payload Part 2:
    
      +----+----+----+----+----+----+----+----+
      |                                       |
      +            Payload Section            +
      |                                       |
      ~                                       ~
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
    
    {% endhighlight %}
    
    
    zzz's avatar
    zzz committed
    Sizes:
    
    ================    =========  =====  =========  =============  =============  ==========  =======
      Type              Type Code  X len  Msg 1 len  Msg 1 Enc len  Msg 1 Dec len  PQ key len  pl len
    ================    =========  =====  =========  =============  =============  ==========  =======
    X25519                   4       32     96+pl        64+pl             pl           --       pl
    MLKEM512_X25519          5       32    896+pl       864+pl         800+pl          800       pl
    MLKEM768_X25519          6       32   1280+pl      1344+pl        1184+pl         1184       pl
    MLKEM1024_X25519         7       32   1664+pl      1632+pl        1568+pl         1568       pl
    ================    =========  =====  =========  =============  =============  ==========  =======
    
    
    zzz's avatar
    zzz committed
    
    1g) New Session Reply format
    ````````````````````````````
    
    
    zzz's avatar
    zzz committed
    Changes: Current ratchet has an empty payload for the first ChaCha section.
    With ML-KEM, the first ChaCha section will contain the encrypted PQ ciphertext.
    
    
    Encrypted format:
    
    
    zzz's avatar
    zzz committed
    .. raw:: html
    
      {% highlight lang='dataspec' %}
    +----+----+----+----+----+----+----+----+
      |       Session Tag   8 bytes           |
      +----+----+----+----+----+----+----+----+
      |                                       |
      +        Ephemeral Public Key           +
      |                                       |
      +            32 bytes                   +
      |     Encoded with Elligator2           |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
      |                                       |
      +                                       +
    
    zzz's avatar
    zzz committed
      | ChaCha20 encrypted ML-KEM ciphertext  |
    
    zzz's avatar
    zzz committed
      +      (see table below for length)     +
      ~                                       ~
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
      |  Poly1305 Message Authentication Code |
    
    zzz's avatar
    zzz committed
      +  (MAC) for Key Section                +
    
    zzz's avatar
    zzz committed
      |             16 bytes                  |
      +----+----+----+----+----+----+----+----+
      |                                       |
      +            Payload Section            +
      |       ChaCha20 encrypted data         |
      ~                                       ~
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
      |  Poly1305 Message Authentication Code |
      +         (MAC) for Payload Section     +
      |             16 bytes                  |
      +----+----+----+----+----+----+----+----+
    
    
    {% endhighlight %}
    
    
    zzz's avatar
    zzz committed
    Decrypted format:
    
    .. raw:: html
    
    zzz's avatar
    zzz committed
    
      {% highlight lang='dataspec' %}
    
    zzz's avatar
    zzz committed
    Payload Part 1:
    
    
      +----+----+----+----+----+----+----+----+
      |                                       |
      +       ML-KEM ciphertext               +
      |                                       |
      +      (see table below for length)     +
      |                                       |
      ~                                       ~
      |                                       |
      +----+----+----+----+----+----+----+----+
    
      Payload Part 2:
    
      +----+----+----+----+----+----+----+----+
      |                                       |
      +            Payload Section            +
      |                                       |
      ~                                       ~
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    {% endhighlight %}
    
    Sizes:
    
    ================    =========  =====  =========  =============  =============  ==========  =======
      Type              Type Code  Y len  Msg 2 len  Msg 2 Enc len  Msg 2 Dec len  PQ CT len   opt len
    ================    =========  =====  =========  =============  =============  ==========  =======
    X25519                   4       32     72+pl        32+pl             pl           --       pl
    
    zzz's avatar
    zzz committed
    MLKEM512_X25519          5       32    840+pl       800+pl         768+pl          768       pl
    MLKEM768_X25519          6       32   1160+pl      1120+pl        1088+pl         1088       pl
    MLKEM1024_X25519         7       32   1640+pl      1600+pl        1568+pl         1568       pl
    
    zzz's avatar
    zzz committed
    ================    =========  =====  =========  =============  =============  ==========  =======
    
    
    zzz's avatar
    zzz committed
    
    KDF for Payload Section Encrypted Contents
    ``````````````````````````````````````````
    
    
    .. raw:: html
    
      {% highlight lang='text' %}
    // split()
      keydata = HKDF(chainKey, ZEROLEN, "", 64)
    
      TODO
    
      k_ab = keydata[0:31]
      k_ba = keydata[32:63]
    
      rest unchanged
    {% endhighlight %}
    
    
    zzz's avatar
    zzz committed
    
    
    
    NTCP2
    ------
    
    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"
    
    
    zzz's avatar
    zzz committed
    
    1) SessionRequest
    ``````````````````
    
    
    zzz's avatar
    zzz committed
    Changes: Current NTCP2 contains only the options in the ChaCha section.
    With ML-KEM, the ChaCha section will also contain the encrypted PQ public key.
    
    
    zzz's avatar
    zzz committed
    
    Raw contents:
    
    .. raw:: html
    
      {% highlight lang='dataspec' %}
    +----+----+----+----+----+----+----+----+
      |                                       |
      +        obfuscated with RH_B           +
      |       AES-CBC-256 encrypted X         |
      +             (32 bytes)                +
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
      |                                       |
      +                                       +
      |   ChaChaPoly frame                    |
    
    zzz's avatar
    zzz committed
      +      (see table below for length)     +
    
    zzz's avatar
    zzz committed
      |   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 ChaChaPoly frame is bigger
    
    
    {% endhighlight %}
    
    Unencrypted data (Poly1305 authentication tag not shown):
    
    .. raw:: html
    
      {% highlight lang='dataspec' %}
    +----+----+----+----+----+----+----+----+
      |                                       |
      +                                       +
      |                   X                   |
      +              (32 bytes)               +
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
      |           ML-KEM encap_key            |
    
    zzz's avatar
    zzz committed
      +      (see table below for length)     +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
      |               options                 |
      +              (16 bytes)               +
      |                                       |
      +----+----+----+----+----+----+----+----+
      |     unencrypted authenticated         |
      +         padding (optional)            +
      |     length defined in options block   |
      ~               .   .   .               ~
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    
    
    {% endhighlight %}
    
    
    zzz's avatar
    zzz committed
    Sizes:
    
    ================    =========  =====  =========  =============  =============  ==========  =======
      Type              Type Code  X len  Msg 1 len  Msg 1 Enc len  Msg 1 Dec len  PQ key len  opt len
    ================    =========  =====  =========  =============  =============  ==========  =======
    X25519                   4       32     64+pad       32              16           --         16
    MLKEM512_X25519          5       32    864+pad      832             816          800         16
    MLKEM768_X25519          6       32   1248+pad     1216            1200         1184         16
    MLKEM1024_X25519         7       32   1632+pad     1600            1584         1568         16
    ================    =========  =====  =========  =============  =============  ==========  =======
    
    
    zzz's avatar
    zzz committed
    Note: Type codes are for internal use only. Routers will remain type 4,
    and support will be indicated in the router addresses.
    
    
    zzz's avatar
    zzz committed
    
    2) SessionCreated
    ``````````````````
    
    
    zzz's avatar
    zzz committed
    Changes: Current NTCP2 contains only the options in the ChaCha section.
    With ML-KEM, the ChaCha section will also contain the encrypted PQ public key.
    
    
    zzz's avatar
    zzz committed
    
    Raw contents:
    
    .. raw:: html
    
      {% highlight lang='dataspec' %}
    +----+----+----+----+----+----+----+----+
      |                                       |
      +        obfuscated with RH_B           +
      |       AES-CBC-256 encrypted Y         |
      +              (32 bytes)               +
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
      |   ChaChaPoly frame                    |
      +   Encrypted and authenticated data    +
    
    zzz's avatar
    zzz committed
      -      (see table below for length)     -
    
    zzz's avatar
    zzz committed
      +   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 ChaChaPoly frame is bigger
    
    {% endhighlight %}
    
    Unencrypted data (Poly1305 auth tag not shown):
    
    .. raw:: html
    
      {% highlight lang='dataspec' %}
    +----+----+----+----+----+----+----+----+
      |                                       |
      +                                       +
      |                  Y                    |
      +              (32 bytes)               +
      |                                       |
      +                                       +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
      |           ML-KEM Ciphertext           |
      +      (see table below for length)     +
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    zzz's avatar
    zzz committed
      |               options                 |
      +              (16 bytes)               +
      |                                       |
      +----+----+----+----+----+----+----+----+
      |     unencrypted authenticated         |
      +         padding (optional)            +
      |     length defined in options block   |
      ~               .   .   .               ~
      |                                       |
      +----+----+----+----+----+----+----+----+
    
    {% endhighlight %}
    
    
    zzz's avatar
    zzz committed
    Sizes:
    
    ================    =========  =====  =========  =============  =============  ==========  =======
      Type              Type Code  Y len  Msg 2 len  Msg 2 Enc len  Msg 2 Dec len  PQ CT len   opt len
    ================    =========  =====  =========  =============  =============  ==========  =======
    X25519                   4       32     64+pad       32              16           --         16
    MLKEM512_X25519          5       32    832+pad      800             784          768         16
    MLKEM768_X25519          6       32   1120+pad     1088            1104         1088         16
    MLKEM1024_X25519         7       32   1600+pad     1568            1584         1568         16
    ================    =========  =====  =========  =============  =============  ==========  =======
    
    
    zzz's avatar
    zzz committed
    Note: Type codes are for internal use only. Routers will remain type 4,
    and support will be indicated in the router addresses.
    
    
    zzz's avatar
    zzz committed
    
    
    zzz's avatar
    zzz committed
    
    3) SessionConfirmed
    ```````````````````
    
    Unchanged
    
    
    Key Derivation Function (KDF) (for data phase)
    ``````````````````````````````````````````````
    
    The data phase uses a zero-length associated data input.
    
    
    The KDF generates two cipher keys k_ab and k_ba from the chaining key ck,
    using HMAC-SHA256(key, data) as defined in [RFC-2104]_.
    This is the Split() function, exactly as defined in the Noise spec.
    
    .. raw:: html
    
      {% highlight lang='text' %}
    
    ck = from handshake phase
    
      // k_ab, k_ba = HKDF(ck, zerolen)
      // ask_master = HKDF(ck, zerolen, info="ask")
    
      // zerolen is a zero-length byte array
      temp_key = HMAC-SHA256(ck, zerolen)
    
      TODO
    
    
      remainder unchanged
    
    {% endhighlight %}
    
    
    
    
    zzz's avatar
    zzz committed
    
    SSU2
    ----
    
    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"
    
    
    zzz's avatar
    zzz committed
    Long Header
    `````````````
    The long header is 32 bytes. It is used before a session is created, for Token Request, SessionRequest, SessionCreated, and Retry.