package shared import "encoding/binary" const PROTO_VERSION uint16 = 1 // pubKey - public key generated by the client // privKey - private key generated by the client // serverPubKey - pre-shared public key used for authenticating the server // serverPrivKey - long-term private key used for authenticating the server // sessionKey - per-peer symmetrical key derived via HPKE for encrypting unicast packets // multicastKey - key shared between everyone for encrypting multicast packets // authSecret - secret assigned to a client for authenticating subsequent requests // SYM = XChaCha20‑Poly1305 with nonce prepended // HMAC = HMAC-SHA-256 // hpke = HPKE(MLKEM768X25519, ChaCha20Poly1305, HKDF-SHA-256) // ds = ML-DSA // packet format // [ version - 2 bytes ] [ type - 2 bytes ] [ payload - see below ] const ( _ uint16 = iota // (client -> server) requests a challenge to prove the ownership of the privKey // [ pubKey - 1216 bytes ] REQ_GET_CHALLENGE // (server -> client) provides an encrypted authSecret // [ ds.Sign(serverPrivKey, rest) - 2420 bytes ] [ HPKE(pubKey, authSecret) - 1168 bytes ] RESP_GET_CHALLENGE // (client -> server) requests an IP // [ HMAC(authSecret, pubKey) - 32 bytes ] [ pubKey - 1216 bytes ] REQ_REGISTER // (server -> client) returns the assigned IP and encrypted multicastKey // [ ds.Sign(serverPrivKey, rest) - 2420 bytes ] [ ip - 16 bytes ] [ hpke.Seal(pubKey, multicastKey) - 1168 bytes ] RESP_REGISTER // (client -> server) requests peer's pubKey from the server for encapsulation // [ HMAC(authSecret, rest) - 32 bytes ] [ ip - 16 bytes ] REQ_GET_PUBKEY // (server -> client) provides requested pubKey // [ ds.Sign(serverPrivKey, rest) - 2420 bytes ] [ ip - 16 bytes ] [ pubKey - 1216 bytes ] RESP_GET_PUBKEY // (client -> server -> client2) establishes a sessionKey with another peer // [ HMAC(authSecret, rest) - 32 bytes ] [ destIP - 16 bytes ] [ srcIP - 16 bytes ] [ hpke.Encap(pubKey) - 1120 bytes ] REQ_ESTABLISH // (client2 -> server -> client) acknowledges the sessionKey was established // [ HMAC(authSecret, rest) - 32 bytes ] [ destIP - 16 bytes ] [ srcIP - 16 bytes ] RESP_ESTABLISH // (client -> server -> client2) relays an encrypted packet to a specified peer // [ HMAC(authSecret, rest) - 32 bytes ] [ destIP - 16 bytes ] [ srcIP - 16 bytes ] [ SYM(sessionKey, pkt) ] UNICAST_PKT // (client -> server -> *) broadcasts an encrypted packet // [ HMAC(authSecret, rest) - 32 bytes ] [ SYM(multicastKey, pkt) ] BROADCAST_PKT ) func BuildPkt(pktType uint16, parts ...[]byte) []byte { var total int for _, p := range parts { total += len(p) } out := make([]byte, 4, 4+total) binary.LittleEndian.PutUint16(out[0:], PROTO_VERSION) binary.LittleEndian.PutUint16(out[2:], pktType) for _, p := range parts { out = append(out, p...) } return out }