#ifndef CIRCE_CORE_PEER_TABLE_H #define CIRCE_CORE_PEER_TABLE_H #include "kangarootwelve128.h" #include "mldsa_native.h" #include "mlkem_native.h" #include #include struct circe_location { enum { CIRCE_ADDRESS_IPV4, CIRCE_ADDRESS_IPV6, } ip_type; uint16_t port; union { uint8_t ipv4[4]; uint8_t ipv6[16]; } ip_addr; }; #define CIRCE_PEER_TABLE_LEN 64 #define CIRCE_IDENTITY_LEN 64 // SHA-512 hash of hostname || island name enum circe_handshake_stage { CIRCE_HANDSHAKE_STAGE_OPEN, CIRCE_HANDSHAKE_STAGE_ACK, CIRCE_HANDSHAKE_STAGE_ID, CIRCE_HANDSHAKE_STAGE_DONE, }; struct circe_peer { bool double_lan; // lan1 is not valid if false struct circe_location lan0_loc; struct circe_location lan1_loc; struct circe_location wan_loc; uint8_t relay_server_identity[CIRCE_IDENTITY_LEN]; // SERVERS DON'T USE THIS, // ONLY CLIENTS DO uint8_t lan0_hash[32]; // SHA-256 uint8_t lan1_hash[32]; enum { CIRCE_ROUTE_LAN0, CIRCE_ROUTE_LAN1, CIRCE_ROUTE_WAN, CIRCE_ROUTE_RELAY, } current_route; uint8_t identity[CIRCE_IDENTITY_LEN]; uint8_t mldsa_pubkey[1312]; // ML-DSA-44 uint8_t rx_key[32]; uint8_t tx_key[32]; uint64_t next_heartbeat_ms; uint64_t next_kex_ms; uint64_t last_seqn_tx; uint64_t last_seqn_rx; enum circe_handshake_stage next_handshake_stage; uint64_t packets_received_mask; // ZERO ALL OF THESE AFTER KEY EXCHANGE IS COMPLETE uint8_t my_th2[64]; // SHA-512 uint8_t my_th3[64]; // SHA-512 uint8_t my_ecdh_privkey[32]; uint8_t my_mlkem_privkey[MLKEM_SECRETKEYBYTES (768)]; uint8_t prk[TCT_TURBOSHAKE128_STATE_LEN]; uint8_t id_payload_halves[2] [(CIRCE_IDENTITY_LEN + MLDSA_BYTES (44)) / 2 + 16]; uint8_t id_payload_aads[2][16]; // Yeah that should be enough }; #endif