Skip to content

Latest commit

 

History

History
88 lines (63 loc) · 3.13 KB

File metadata and controls

88 lines (63 loc) · 3.13 KB

PQC Session Protocol

This project implements a research protocol for measuring post-quantum session setup across different networking stacks. It is not a TLS implementation. The point is to keep the cryptographic protocol stable while changing the transport path underneath it.

Cryptographic Suite

The default suite is:

KYBER768+DILITHIUM3+SHAKE256+AESGCM

The C++ handshake benchmark can also sweep security levels:

Level KEM Signature
Level1 Kyber512 Dilithium2
Level3 Kyber768 Dilithium3
Level5 Kyber1024 Dilithium5

Handshake Flow

The session setup is a four-message mutually authenticated exchange:

Client                                      Server
  |                                          |
  | CLIENT_HELLO: nonce, KEM pk, cert, sig  |
  |----------------------------------------->|
  |                                          | verify client signature
  | SERVER_HELLO: nonce, KEM pk, cert, sig  |
  |<-----------------------------------------|
  | verify server signature                  |
  | CLIENT_KEM: ct to server KEM pk, sig    |
  |----------------------------------------->|
  |                                          | verify, decapsulate
  | SERVER_KEM: ct to client KEM pk, sig    |
  |<-----------------------------------------|
  | verify, decapsulate                      |

Both sides contribute ephemeral KEM material. Each signature covers the current message plus transcript context, so later messages are bound to the earlier exchange.

Transcript Binding

Messages are serialized canonically before signing and before key derivation. The protocol uses SHAKE256 domain separators for each signed context:

Context Purpose
C-hello Client initial authentication
S-hello Server authentication bound to client hello
C-kem Client KEM ciphertext bound to accumulated transcript
S-kem Server KEM ciphertext bound to accumulated transcript
handshake Full transcript hash for key derivation

Key Derivation

The two KEM shared secrets and the full transcript feed a SHAKE256 extract-and-expand derivation:

transcript_hash = SHAKE256("handshake||" || full_transcript, 64)
prk = SHAKE256("EXTRACT||" || ss_client || ss_server || transcript_hash, 64)

client_write_key = SHAKE256("HKDF-v1||client write key||" || prk, 32)
server_write_key = SHAKE256("HKDF-v1||server write key||" || prk, 32)
client_base_iv   = SHAKE256("HKDF-v1||client base iv||" || prk, 12)
server_base_iv   = SHAKE256("HKDF-v1||server base iv||" || prk, 12)

Data Plane

After the handshake, the data path uses AES-256-GCM. The nonce follows the TLS-style construction:

nonce = base_iv XOR (0x00000000 || uint64_sequence_number)

AAD binds direction and sequence number:

v1||KYBER+DILITHIUM||direction||uint64_sequence_number

The receiver tracks the highest accepted sequence number and rejects stale encrypted messages.

Framing

TCP-style transports use a 4-byte big-endian length prefix followed by canonical JSON payloads. DPDK UDP uses application-level fragmentation/reassembly for PQC messages that exceed MTU.