QRCLibGitHub

Agree on a secret that is never sent.

Alice publishes a public key. Bob uses it to create a ciphertext and a 32-byte secret. Alice uses her private key on that ciphertext and gets the same secret. This is X-Wing: ML-KEM-768 and X25519, combined so that both have to be broken.

What Establish does

  1. 01

    Alice generates a 32-byte seed.

    SHAKE256 stretches it into an ML-KEM-768 key and an X25519 key. The public key you will see is 1,216 bytes: 1,184 of lattice, then 32 of X25519.

  2. 02

    Bob encapsulates to that public key.

    He gets an ML-KEM ciphertext (1,088 bytes) and an X25519 ephemeral public key (32 bytes). Those 1,120 bytes are what he sends. The secret stays local.

  3. 03

    Both sides run the same combiner.

    SHA3-256 over the two shared secrets, Bob’s ephemeral key, Alice’s X25519 key, and a fixed label. If the digests match, the exchange worked.

Nothing has been exchanged yet.

Same call in Python
from qrclib.hybrid import generate_kem_keys, encapsulate, decapsulate

alice = generate_kem_keys()
ciphertext, bob = encapsulate(alice.public_key)
alice_copy = decapsulate(alice.secret_key, ciphertext)
assert alice_copy == bob