/* * Ed25519Utils.hpp — Ed25519 cryptographic primitives for Antheos auth. * * Thin wrapper around OpenSSL 3.0 EVP API. Keygen, sign, verify, * key serialization (hex), trusted key store, random nonce generation. * * All keys and signatures are hex-encoded strings. Private keys are * 64 hex chars (32-byte Ed25519 seed), public keys are 64 hex chars * (32 bytes), signatures are 128 hex chars (64 bytes). * * Copyright (c) 2026 Are Bjørby * SPDX-License-Identifier: MIT */ #pragma once #include #include #include #include #include namespace antpeer { namespace crypto { /* ── Key types ────────────────────────────────────────────────────── */ struct KeyPair { std::string private_key; /* 64 hex chars (32-byte Ed25519 seed) */ std::string public_key; /* 64 hex chars (32 bytes) */ std::string key_id; /* 32 hex chars (16-byte random identifier) */ }; struct TrustedKey { std::string oid; std::string key_id; /* 32 hex chars */ std::string public_key; /* 64 hex chars */ }; /* ── Key generation ───────────────────────────────────────────────── */ /** Generate a fresh Ed25519 keypair with random key_id. */ KeyPair keygen(); /* ── Sign / Verify ────────────────────────────────────────────────── */ /** Sign data with Ed25519 private key. Returns signature as 128 hex chars. */ std::string sign(const void* data, size_t len, const std::string& private_key_hex); std::string sign(std::string_view data, const std::string& private_key_hex); /** Verify Ed25519 signature against public key. */ bool verify(const void* data, size_t len, const std::string& signature_hex, const std::string& public_key_hex); bool verify(std::string_view data, const std::string& signature_hex, const std::string& public_key_hex); /* ── Nonce ────────────────────────────────────────────────────────── */ /** Generate cryptographically random nonce as hex string. */ std::string nonce(size_t bytes = 32); /* ── Key I/O ──────────────────────────────────────────────────────── */ /** * Save keypair to file. Format: * private_key = * public_key = * key_id = */ void save_key(const KeyPair& kp, const char* path); /** Load keypair from file (same format as save_key). */ KeyPair load_key(const char* path); /* ── Trusted key store ────────────────────────────────────────────── */ /** * Load trusted keys from config file. Format (one per line): * OID key_id public_key_hex * Lines starting with # are comments. Empty lines are skipped. */ std::vector load_trusted_keys(const char* path); /** * Look up public key for an OID in a trusted key set. * If key_id is non-empty, matches both OID and key_id. * Returns nullptr if not found. */ const TrustedKey* find_trusted_key(const std::vector& keys, std::string_view oid, std::string_view key_id = {}); /* ── Hex utilities ────────────────────────────────────────────────── */ std::string to_hex(const uint8_t* data, size_t len); bool from_hex(const std::string& hex, uint8_t* out, size_t max_len); } // namespace crypto } // namespace antpeer