include/qrnsp_crypto.h
/*
* QR-NSP Volcanic Edition — Public Crypto API
* SPDX-License-Identifier: AGPL-3.0-or-later
* Module 2: Hybrid PQC Key Encapsulation
*
* Usage:
* 1. hybrid_keypair_generate() → (pk, sk)
* 2. Sender: hybrid_encapsulate(ct, ss, pk) → ciphertext + shared secret
* 3. Receiver: hybrid_decapsulate(ss, ct, sk, pk) → same shared secret
* 4. Use ss as key for AES-256-GCM (Module 3)
*
* Wire sizes:
* Public key: 1600 bytes (ML-KEM-1024: 1568, X25519: 32)
* Secret key: 3200 bytes (ML-KEM-1024: 3168, X25519: 32)
* Ciphertext: 1600 bytes (ML-KEM-1024: 1568, X25519: 32)
* Shared secret: 32 bytes
*/
#ifndef QRNSP_CRYPTO_H
#define QRNSP_CRYPTO_H
#include <stdint.h>
#include <stddef.h>
/* ─────────────────────────────────────────────
* Size constants
* ───────────────────────────────────────────── */
#define QRNSP_CRYPTO_PUBLICKEYBYTES 1600
#define QRNSP_CRYPTO_SECRETKEYBYTES 3200
#define QRNSP_CRYPTO_CIPHERTEXTBYTES 1600
#define QRNSP_CRYPTO_SSBYTES 32
/* ─────────────────────────────────────────────
* Key generation
*
* Generates ML-KEM-1024 + X25519 hybrid keypair.
* pk: public key (send to peer)
* sk: secret key (keep private)
*
* Returns 0 on success, -1 on RNG failure.
* ───────────────────────────────────────────── */
int hybrid_keypair_generate(uint8_t pk[QRNSP_CRYPTO_PUBLICKEYBYTES],
uint8_t sk[QRNSP_CRYPTO_SECRETKEYBYTES]);
/* ─────────────────────────────────────────────
* Encapsulation (sender side)
*
* Given peer's public key, produces:
* ct: ciphertext (send to peer)
* ss: shared secret (use as AES-256-GCM key)
*
* Returns 0 on success.
* ───────────────────────────────────────────── */
int hybrid_encapsulate(uint8_t ct[QRNSP_CRYPTO_CIPHERTEXTBYTES],
uint8_t ss[QRNSP_CRYPTO_SSBYTES],
const uint8_t pk[QRNSP_CRYPTO_PUBLICKEYBYTES]);
/* ─────────────────────────────────────────────
* Decapsulation (receiver side)
*
* Given ciphertext and own keys, recovers shared secret.
* With implicit rejection: always produces output (timing-safe).
*
* Returns 0 always (implicit rejection is silent).
* ───────────────────────────────────────────── */
int hybrid_decapsulate(uint8_t ss[QRNSP_CRYPTO_SSBYTES],
const uint8_t ct[QRNSP_CRYPTO_CIPHERTEXTBYTES],
const uint8_t sk[QRNSP_CRYPTO_SECRETKEYBYTES],
const uint8_t pk[QRNSP_CRYPTO_PUBLICKEYBYTES]);
#endif /* QRNSP_CRYPTO_H */