#ifndef CIRCE_CORE_PEER_TABLE_H #define CIRCE_CORE_PEER_TABLE_H #include "mldsa/mldsa_native.h" #include "mlkem/mlkem_native.h" #include "proto_circe.h" #include "tinycrypt/kangarootwelve128.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 #define CIRCE_TUNNEL_ID_LEN 64 // Random bytes 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[MLDSA_PUBLICKEYBYTES (44)]; uint8_t rx_key[32]; uint8_t tx_key[32]; uint8_t tunnel_id[64]; uint64_t next_heartbeat_ms; uint64_t next_kex_ms; uint64_t last_seqn_tx; uint64_t last_seqn_rx; enum circe_handshake_stage last_handshake_stage; uint8_t dgram_rx_buffer[PROTO_CIRCE_V1_MAX_MSG_LEN]; uint8_t dgram_tx_buffer[PROTO_CIRCE_V1_MAX_MSG_LEN]; proto_circe_v1_rx_t dgram_rx_state; proto_circe_v1_tx_t dgram_tx_state; // 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]; }; #endif