Phases 3-6 (SPEC T19-T23): type-1 identity carries ML-KEM-768 + ML-DSA-65 pubs, COM type-2 double-sign, HELLO capability bit, local.conf settings.pqcMode (off/hybrid/pqconly) with classic fallback. selftest KAT + interop matrix + fragment-loss benchmark green.
44 lines
2.2 KiB
C++
44 lines
2.2 KiB
C++
#include "PQHybrid.hpp"
|
|
|
|
#include "Constants.hpp"
|
|
#include "SHA512.hpp"
|
|
|
|
#include <oqs/kem_ml_kem.h>
|
|
#include <oqs/sig_ml_dsa.h>
|
|
namespace ZeroTier {
|
|
|
|
static_assert(PQHybrid::MLKEM768_PK_LEN == OQS_KEM_ml_kem_768_length_public_key, "ML-KEM-768 public key size mismatch");
|
|
static_assert(PQHybrid::MLKEM768_SK_LEN == OQS_KEM_ml_kem_768_length_secret_key, "ML-KEM-768 secret key size mismatch");
|
|
static_assert(PQHybrid::MLKEM768_CT_LEN == OQS_KEM_ml_kem_768_length_ciphertext, "ML-KEM-768 ciphertext size mismatch");
|
|
static_assert(PQHybrid::MLKEM768_SS_LEN == OQS_KEM_ml_kem_768_length_shared_secret, "ML-KEM-768 shared secret size mismatch");
|
|
static_assert(PQHybrid::MLKEM768_SS_LEN == 32, "hybrid KDF expects 32-byte pq secret");
|
|
static_assert(PQHybrid::MLDSA65_PK_LEN == OQS_SIG_ml_dsa_65_length_public_key, "ML-DSA-65 public key size mismatch");
|
|
static_assert(PQHybrid::MLDSA65_SK_LEN == OQS_SIG_ml_dsa_65_length_secret_key, "ML-DSA-65 secret key size mismatch");
|
|
static_assert(PQHybrid::MLDSA65_SIG_LEN == OQS_SIG_ml_dsa_65_length_signature, "ML-DSA-65 signature size mismatch");
|
|
|
|
bool PQHybrid::generateKeypair(uint8_t* pk, uint8_t* sk)
|
|
{ return (OQS_KEM_ml_kem_768_keypair(pk, sk) == OQS_SUCCESS); }
|
|
|
|
bool PQHybrid::encaps(const uint8_t* peerPk, uint8_t* ct, uint8_t* ss)
|
|
{ return (OQS_KEM_ml_kem_768_encaps(ct, ss, peerPk) == OQS_SUCCESS); }
|
|
|
|
bool PQHybrid::decaps(const uint8_t* sk, const uint8_t* ct, uint8_t* ss)
|
|
{ return (OQS_KEM_ml_kem_768_decaps(ss, ct, sk) == OQS_SUCCESS); }
|
|
|
|
void PQHybrid::hybridKey(const uint8_t classical[ZT_SYMMETRIC_KEY_SIZE], const uint8_t pq[MLKEM768_SS_LEN], uint8_t out[ZT_SYMMETRIC_KEY_SIZE])
|
|
{ HMACSHA384(classical, pq, MLKEM768_SS_LEN, out); }
|
|
|
|
bool PQHybrid::generateSigKeypair(uint8_t* pk, uint8_t* sk)
|
|
{ return (OQS_SIG_ml_dsa_65_keypair(pk, sk) == OQS_SUCCESS); }
|
|
|
|
bool PQHybrid::sign(const uint8_t* sk, const void* msg, unsigned int len, uint8_t* sig)
|
|
{
|
|
size_t siglen = 0;
|
|
return (OQS_SIG_ml_dsa_65_sign(sig, &siglen, (const uint8_t*)msg, len, sk) == OQS_SUCCESS) && (siglen == MLDSA65_SIG_LEN);
|
|
}
|
|
|
|
bool PQHybrid::verify(const uint8_t* pk, const void* msg, unsigned int len, const uint8_t* sig)
|
|
{ return (OQS_SIG_ml_dsa_65_verify((const uint8_t*)msg, len, sig, MLDSA65_SIG_LEN, pk) == OQS_SUCCESS); }
|
|
|
|
} // namespace ZeroTier
|