Internet-Draft S. Karthik Individual Submission Independent Intended status: Experimental 15 August 2026 Expires: 14 February 2027 State Graph Cryptographic Protocol (SGCP) draft-sgcp-state-graph-cryptographic-protocol-00 Abstract This document specifies the State Graph Cryptographic Protocol (SGCP), a communication-security framework in which a client and server establish a cryptographically protected session and maintain a synchronized state graph throughout the lifetime of the communication session. SGCP combines device identity, port context, socket context, session identity, ECDH-based shared-secret establishment, cryptographic key derivation, epochs, packet sequence numbers, authenticated state transitions, state-dependent packet transformation, replay protection, continuous context verification, controlled reauthentication, and session recovery. The central principle is that both endpoints independently derive the same cryptographic state from a common authenticated session secret and deterministic state information. The state graph defines which communication states are valid and which transitions are permitted. This document also illustrates the protocol with a worked example of a full-duplex binary media file transfer (an MP3 audio file) showing the complete packet-level exchange. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 14 February 2027. Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction ................................................ 5 2. Conventions and Definitions ................................. 6 2.1. Requirements Language ................................... 6 2.2. Terminology ............................................. 6 3. High-Level Architecture ..................................... 8 4. X.509 Certificate Integration and Protocol Stack ........... 9 4.1. Role of X.509 in SGCP .................................. 9 4.2. Complete Protocol Stack ................................ 10 4.3. Certificate Requirements ............................... 11 4.4. OpenSSL Integration .................................... 11 4.5. SGCP Handshake with X.509 Certificate Flow ............. 12 4.6. What X.509 Establishes vs. What SGCP Establishes ....... 13 5. Protocol Phases ............................................ 14 5.1. Phase 1 - Client Initialization ........................ 14 5.2. Phase 2 - Initial Connection ........................... 14 5.3. Phase 3 - Authentication .............................. 15 5.4. Phase 4 - Shared Secret Establishment .................. 16 5.5. Phase 5 - Session Creation ............................. 17 5.6. Phase 6 - Device-Port-Socket Context ................... 17 5.7. Phase 7 - Creation of the State Graph .................. 18 5.8. Phase 8 - Packet Creation .............................. 19 5.9. Phase 9 - Receiver Processing .......................... 20 5.10. Phase 10 - State Advancement ........................... 21 5.11. Phase 11 - Replay Protection ........................... 21 5.12. Phase 12 - Continuous Context Monitoring ............... 22 6. Packet Format .............................................. 23 6.1. Common Packet Header ................................... 23 6.2. Handshake Packets ...................................... 24 6.3. Data Packets ........................................... 25 7. State Graph Model .......................................... 26 7.1. Graph Nodes ............................................ 26 7.2. Graph Edges ............................................ 26 7.3. Deterministic State Derivation ......................... 27 7.4. Node and Edge Relationship ............................. 27 8. Key Hierarchy .............................................. 28 8.1. Root Secret ............................................ 28 8.2. Epoch Key .............................................. 28 8.3. Packet Key ............................................. 29 8.4. Transformation State Key .............................. 29 8.5. Domain Separation Labels .............................. 29 9. State-Dependent Packet Transformation ...................... 30 10. Epoch Architecture ......................................... 31 10.1. Context Change ......................................... 32 10.2. Key Rotation ........................................... 32 11. State Transition Engine .................................... 33 11.1. Transition Events ...................................... 33 11.2. Transition Examples .................................... 33 12. Session Recovery ........................................... 34 13. Sender-Receiver Synchronization ............................ 35 14. Full-Duplex MP3 Media Transfer Example ..................... 36 14.1. Scenario Description ................................... 36 14.2. MP3 File Parameters .................................... 36 14.3. Handshake Phase ........................................ 37 14.4. MP3 Segment Transfer - Client to Server ................ 40 14.5. Full-Duplex Operation - Simultaneous Exchange .......... 43 14.6. Epoch Transition During Transfer ....................... 46 14.7. Completion and Session Summary ......................... 48 15. Complete State Model ....................................... 49 16. Security Considerations .................................... 50 16.1. Attack Surface Analysis ................................ 50 16.2. Replay Attacks ......................................... 51 16.3. State Divergence ....................................... 51 16.4. Deterministic State Security Rule ...................... 52 17. IANA Considerations ........................................ 52 18. References ................................................. 53 18.1. Normative References ................................... 53 18.2. Informative References ................................. 54 Appendix A. Graph Interaction Diagrams ......................... 55 Appendix B. Test Vectors (Illustrative) ........................ 56 Authors' Addresses ............................................. 57 1. Introduction Modern communication security protocols, such as TLS [RFC8446] and DTLS [RFC9147], establish shared secrets and derive traffic keys but treat each packet largely independently from the perspective of the state machine governing what constitutes a valid packet at a given point in the session. Session context (the device, the port, the socket) is typically authenticated only at the handshake and not continuously bound to individual packet keys. The State Graph Cryptographic Protocol (SGCP) addresses this limitation by introducing the concept of a cryptographic state graph: a deterministically derived directed graph in which each node represents a valid cryptographic communication state (keyed to the current epoch, sequence number, and context binding) and each edge represents a cryptographically authenticated transition between two such states. SGCP provides the following security properties: o Mutual device authentication via certificate-based challenge-response. o Forward-secure key establishment via ECDH (with optional ML-KEM [FIPS203] hybridization for post-quantum protection). o Per-packet key uniqueness: each packet uses a fresh key derived from the epoch key, direction, and sequence number. o Context binding: the session cryptographic state is bound to the Device-Port-Socket tuple at key-derivation time. o Authenticated state transitions: every transition in the state graph is cryptographically verified. o Replay protection: a sequence-number window rejects replayed packets even if their cryptographic authentication were to pass. o Epoch-based key rotation: significant context changes or policy events advance the epoch and derive fresh key material without disclosing the root secret again. o Session recovery: a reconnecting peer must re-authenticate and establish a new epoch, preventing session-token reuse attacks. This document specifies the protocol in full and illustrates its operation with a worked example involving the full-duplex transfer of a sample MP3 audio file between two SGCP endpoints. The remainder of this document is organized as follows. Section 2 defines terminology. Section 3 describes the high-level architecture. Section 4 specifies X.509 certificate integration and the complete protocol stack. Section 5 walks through the twelve protocol phases. Section 6 specifies packet formats. Sections 7 through 13 specify the state graph model, key hierarchy, transformation mechanism, epoch architecture, transition engine, and synchronization model. Section 14 provides the MP3 media transfer worked example. Sections 15 and 16 define the complete state model and security considerations. 2. Conventions and Definitions 2.1. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 2.2. Terminology The following terms are used throughout this document. State Graph: A deterministically derived directed graph in which each node represents a valid cryptographic communication state and each directed edge represents a permitted and cryptographically authenticated state transition. Node: A vertex in the state graph, representing one valid cryptographic communication state. A node is identified by the tuple (Session_ID, Epoch, Sequence, Direction). Edge: A directed arc between two nodes representing a permitted transition. An edge carries an Authentication_Proof. Epoch: A cryptographic generation. Each epoch possesses a distinct set of derived keys. A new epoch is created upon a key- rotation event, a context change requiring reauthentication, or a session-recovery event. Root Secret: The session-level secret derived from the authenticated DH/ECDH exchange. The root secret is the ultimate key-derivation ancestor and is never transmitted. Epoch Key: A key derived from the Root Secret scoped to a particular epoch. Packet keys for all packets within the epoch are derived from the Epoch Key. Packet Key: A per-packet symmetric key derived from the Epoch Key, packet direction, and sequence number using a KDF. Context Binding: The cryptographic hash of the normalized Device-Port-Socket context tuple that binds the session to its communication environment. Transformation State: A deterministic, state-dependent bit-level transformation applied to the ciphertext prior to placing the packet on the wire. This is derived from the Epoch Key, sequence, and direction and provides an additional layer of packet differentiation; it is not a substitute for AEAD. Key_ID: A non-secret identifier for the expected cryptographic state of a packet, computed as H(Session_ID || Epoch || Direction || Sequence). Session Recovery: The process by which a reconnecting endpoint proves its identity, triggers a new epoch, and resumes communication without reusing old key material. Hash Chain: A monotonically advancing chain of cryptographic hash values linking successive state-graph nodes, providing tamper-evident ordering across the communication session. 3. High-Level Architecture The overall SGCP architecture is shown below. +----------------------+ | CLIENT | | | | Device Identity | | Private Key | | Certificate | | Context Monitor | +----------+-----------+ | | Handshake v +----------+-----------+ | AUTHENTICATION | | | | Identity Validation | | Certificate Check | | Challenge/Response | +----------+-----------+ | v +----------+-----------+ | KEY ESTABLISHMENT | | | | ECDH / DH | | Optional ML-KEM | +----------+-----------+ | v +----------+-----------+ | ROOT SECRET | | (Session Secret) | +----------+-----------+ | +------------------+------------------+ | | | v v v Device Context Port Context Socket Context | | | +------------------+------------------+ v Context Binding | v +----------+-----------+ | STATE ENGINE | | | | Epoch | | Sequence | | Direction | | Key Identity | | Context State | | Trust State | +----------+-----------+ | v +----------+-----------+ | STATE GRAPH | | | | Nodes + Authenticated| | Edges + Hash Chain | +----------+-----------+ | v +----------+-----------+ | PACKET ENGINE | | | | Key Derivation | | AEAD Encryption | | Transformation | | Authentication | +----------+-----------+ | v PACKET | v +----------+-----------+ | SERVER | | | | State Reconstruction | | Verification | | Decryption | | Trust Evaluation | +----------------------+ 4. X.509 Certificate Integration and Protocol Stack 4.1. Role of X.509 in SGCP SGCP uses X.509 [RFC5280] certificates exclusively to establish the authenticated identities of both endpoints during the handshake. X.509 defines the certificate format and the identity-binding mechanism; SGCP defines how those certificates are used and how the authentication outcome feeds into the cryptographic state graph. The separation of concerns is: o X.509: "This public key belongs to this authenticated identity." o SGCP: Uses that authenticated identity to establish a session Root Secret and derive a cryptographic state graph that governs every subsequent packet. X.509 certificates do NOT contain the SGCP state graph, epoch state, or packet keys. They exist only at the authentication boundary. 4.2. Complete Protocol Stack The full stack, from identity layer to packet protection, is: SGCP | +---------+---------+ | | X.509 Certificate ECDH (via OpenSSL) Exchange | | v v Authenticate Shared Secret | | +---------+---------+ | v KDF / Key Tree (HKDF, Section 8) | v SGCP Root Secret | v SGCP State Graph | +---------+---------+ v v State Node State Edge | | +---------+---------+ | v Packet Protection (Epoch Key -> Packet Key -> AEAD) Stated as a linear stack: OpenSSL | v X.509 Certificates (identity and public-key binding) | v SGCP Authentication (challenge-response, certificate validation) | v ECDH / ML-KEM (shared secret establishment) | v KDF (HKDF-Extract/Expand with domain labels) | v SGCP Root Secret (session-level cryptographic anchor) | v SGCP State Graph (epoch, sequence, context-bound nodes/edges) | v Per-Packet Key (AEAD + state-dependent transformation) | v Wire Packet 4.3. Certificate Requirements Each SGCP endpoint MUST possess: client.crt (X.509 end-entity certificate, DER or PEM) client.key (private key corresponding to the certificate) and correspondingly for the server: server.crt server.key Certificates MUST: o Be signed by a certificate authority (CA) trusted by the remote endpoint, or be mutually pre-configured as trusted. o Contain a Subject Alternative Name (SAN) or Common Name (CN) entry that matches the Device_ID used in the SGCP handshake. o Not be expired or revoked at the time of handshake. o Use a key algorithm consistent with the negotiated SGCP cipher suite (e.g., P-256 or Ed25519 for classical suites). The certificate hash used in Root Secret derivation is: Certificate_Hash = SHA-256(DER-encoded certificate) This binds the Root Secret to the specific certificates exchanged during this handshake, preventing certificate substitution attacks. 4.4. OpenSSL Integration Implementations MAY use OpenSSL (or a compatible TLS library) to perform the X.509 certificate operations during the SGCP handshake. The following OpenSSL operations are involved: o Certificate loading: SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM) SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) o Certificate verification: SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback) SSL_CTX_load_verify_locations(ctx, "ca-chain.crt", NULL) o Certificate inspection (to extract Device_ID from SAN/CN): X509 *cert = SSL_get_peer_certificate(ssl); X509_NAME *subj = X509_get_subject_name(cert); X509_NAME_get_text_by_NID(subj, NID_commonName, buf, sizeof(buf)); o ECDH key generation (for SGCP's own DH exchange, separate from any TLS key exchange): EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL); EVP_PKEY_keygen_init(ctx); EVP_PKEY_keygen(ctx, &pkey); IMPORTANT: When OpenSSL is used as an underlying library, the SGCP handshake runs ON TOP OF the X.509 certificate exchange; SGCP does not delegate its state graph, epoch management, or packet key derivation to OpenSSL. OpenSSL is used only for certificate parsing, signature verification, and ECDH primitives. 4.5. SGCP Handshake with X.509 Certificate Flow The complete handshake, showing certificate exchange and the transition from X.509-authenticated identity into SGCP state: CLIENT SERVER (client.crt + client.key) (server.crt + server.key) |- ClientHello ---------------------------->| | + Client X.509 Certificate | | + Client DH Public Key | | + Client KEM Public Key (if PQ) | | + Client_Nonce | | Verify client certificate chain Extract Device_ID from SAN/CN Lookup Device_ID in device registry Verify certificate not revoked Generate Server_Challenge | |<- ServerHello ----------------------------| | + Server X.509 Certificate | | + Server DH Public Key | | + Server KEM Ciphertext (if PQ) | | + Server_Challenge | | + ServerHello_Signature | | Verify server certificate chain Verify ServerHello_Signature Compute DH_Secret (X25519) Decapsulate KEM_Secret (if PQ) | v Root_Secret = HKDF-Extract( "SGCP_ROOT_PQ_v1", DH_Secret || KEM_Secret || Client_Nonce || Server_Nonce || SHA-256(client.crt) || SHA-256(server.crt)) | |- ClientFinish -------------------------->| | + Challenge_Response | | (signed with client.key) | | + ClientFinish_MAC | | Verify Challenge_Response Compute DH_Secret Compute Root_Secret | v SGCP takes over: | v Session_ID = H("SGCP_SID" || Root_Secret || Client_Nonce || Server_Nonce) | v Epoch_0_Key = HKDF-Expand( Root_Secret, "SGCP_EPOCH" || 0 || Context_Binding, 32) | v Initial State N0 | v N0 -> N1 -> N2 -> N3 -> ... After ClientFinish is verified, both sides independently derive the identical SGCP Root Secret and enter the state graph at N0. From this point, X.509 is no longer involved in per-packet operations. 4.6. What X.509 Establishes vs. What SGCP Establishes The following table clarifies the strict boundary between the responsibilities of X.509 and SGCP: +---------------------------+----------------------------------+ | X.509 Establishes | SGCP Establishes | +---------------------------+----------------------------------+ | Identity binding | Session Root Secret | | Public key authenticity | Epoch key hierarchy | | Certificate validity | Per-packet unique keys | | Chain of trust to CA | State graph (N0, N1, N2, ...) | | Revocation status | Context binding | | Signature algorithms | Replay protection windows | | | Epoch transitions | | | Authenticated state edges | | | Hash chain linking nodes | +---------------------------+----------------------------------+ In summary: X.509 answers "who are you?" SGCP answers "what cryptographic state governs each byte of our ongoing session?" 5. Protocol Phases 5.1. Phase 1 - Client Initialization The process begins before any network communication takes place. The client possesses: o A Device_ID (a stable unique device identifier) o A Device Public Key / Private Key pair o A certificate binding the public key to the Device_ID o An application-level identity (AppID) o A local security policy and Trust State The client's private key MUST never be transmitted to the server or any third party. The server maintains a device registry containing at minimum: Device_ID Public_Key Certificate_ID Status Policy_ID Key_Version Trust_State Only Device_IDs with Status = AUTHORIZED MAY initiate a new session. 5.2. Phase 2 - Initial Connection The client establishes a transport connection to the server. At the point of initial connection, the communication context is the tuple: Context = (Device_ID, Protocol, Local_Port, Remote_Port, Socket_ID, Session_Nonce) SGCP does not treat IP address, MAC address, port number, or socket identifiers as secret. These are context attributes whose purpose is to bind the cryptographic session to its communication environment. The client SHOULD compute and locally cache the preliminary context hash: Prelim_Context_Hash = H("SGCP_CTX_v1" || Device_ID || Protocol || Local_Port || Remote_Port || Socket_ID) This value is used later during context-binding (Section 4.6). 5.3. Phase 3 - Authentication SGCP performs mutual authentication via a three-message challenge-response exchange. Message 1 (Client Hello): ClientHello { ProtocolVersion, SupportedCipherSuites, Device_ID, Certificate, Client_Nonce, Client_DH_Public_Key, Client_KEM_Public_Key (if ML-KEM is negotiated) } Message 2 (Server Hello): ServerHello { SelectedCipherSuite, Server_Certificate, Server_Nonce, Server_DH_Public_Key, Server_KEM_Ciphertext, (if ML-KEM is negotiated) Server_Challenge, ServerHello_Signature } ServerHello_Signature = Sign(Server_Private_Key, H("SGCP_SHELLO" || ClientHello || ServerHello_data)) Message 3 (Client Finish): ClientFinish { Challenge_Response, ClientFinish_MAC } Challenge_Response = Sign(Client_Private_Key, H("SGCP_CHALLENGE" || Server_Challenge || Client_Nonce)) ClientFinish_MAC = HMAC(Handshake_Key, H("SGCP_CFIN" || ClientHello || ServerHello)) The server validates: o The client certificate chain up to a trusted root. o The Device_ID against the device registry. o The certificate revocation status. o The challenge response signature. o The ClientFinish_MAC. If any validation step fails, the server MUST terminate the connection with an authentication-failure alert. 5.4. Phase 4 - Shared Secret Establishment Following successful authentication, both sides perform an authenticated Diffie-Hellman key exchange. The recommended primitive is X25519 [RFC7748] or P-256. The raw shared secret is computed as: DH_Secret = DH(Client_Private, Server_Public) = DH(Server_Private, Client_Public) The raw DH output MUST NOT be used directly as a traffic key. Instead, a KDF is applied to derive the Root Session Secret: Root_Secret = HKDF-Extract("SGCP_ROOT_v1", DH_Secret || Client_Nonce || Server_Nonce || Client_Certificate_Hash || Server_Certificate_Hash) If post-quantum protection is required, a hybrid construction is used. The KEM encapsulation is performed during the handshake (see Section 4.3). The hybrid shared secret is: KEM_Secret = KEM.Decapsulate( Client_Private_KEM_Key, Server_KEM_Ciphertext) Root_Secret = HKDF-Extract("SGCP_ROOT_PQ_v1", DH_Secret || KEM_Secret || Client_Nonce || Server_Nonce || Client_Certificate_Hash || Server_Certificate_Hash) The post-quantum KEM MUST be a standardized algorithm such as ML-KEM-768 [FIPS203]. Custom or proprietary KEMs MUST NOT be used. 5.5. Phase 5 - Session Creation After successful key establishment, both endpoints independently create the initial session state: Session_ID = H("SGCP_SID" || Root_Secret || Client_Nonce || Server_Nonce) Epoch = 0 Sequence = 0 Direction = Client->Server (for the client-to-server channel) Server->Client (for the server-to-client channel) Node_ID = N0 State_ID = H("SGCP_NODE" || Session_ID || Epoch || 0) SGCP is a full-duplex protocol. Each direction maintains independent sequence numbering and per-direction key derivation. The server maintains an authoritative session record; the client maintains the corresponding local state. Both are synchronized by construction through the key derivation tree. 5.6. Phase 6 - Device-Port-Socket Context The communication context is constructed from the following canonical fields: Version (SGCP version integer) Device_ID (stable device identifier) Protocol (transport protocol, e.g., 6 = TCP, 17 = UDP) Local_Port (16-bit port number) Remote_Port (16-bit port number) Socket_ID (implementation-specific socket cookie) Session_ID (from Phase 5) The Context Binding is: Context_Binding = H("SGCP_CTX_BIND_v1" || Version || Device_ID || Protocol || Local_Port || Remote_Port || Socket_ID || Session_ID) The Context Binding becomes an input to all epoch-key derivations, thereby cryptographically binding every packet key to the communication environment in which the session was established. Raw sensitive context values (e.g., internal socket file descriptors) SHOULD NOT appear in cleartext on the wire. 5.7. Phase 7 - Creation of the State Graph The first node of the state graph is: N0 = { Node_ID : H("SGCP_NODE" || Session_ID || 0 || 0), Session_ID : , Epoch : 0, Sequence : 0, Context_Binding: , Key_ID : H(Session_ID || 0 || "C->S" || 0), Direction : Client->Server, State_Status : ACTIVE, Chain_Hash : H("SGCP_CHAIN_GENESIS" || Session_ID) } A mirror N0 exists for the Server->Client direction. Subsequent nodes are created deterministically as each packet is sent or received: N(k+1).Chain_Hash = H("SGCP_CHAIN" || N(k).Chain_Hash || N(k).Node_ID || Sequence(k+1) || Epoch) This chain links each node to its predecessor, forming a hash chain that detects any tampering with the node sequence. The graph grows as follows for normal operation: N0 --E0--> N1 --E1--> N2 --E2--> N3 --E3--> N4 ... Each edge E(k) carries: E(k) = { Previous_Node : N(k), Next_Node : N(k+1), Sequence : k, Event : PACKET_ACCEPTED, Context_Version : , Transition_Type : NORMAL, Authentication_Proof: AEAD_Tag(Packet(k)) } 5.8. Phase 8 - Packet Creation For every outgoing packet, the sender performs the following sequence: (1) Read the current session state: (Session_ID, Epoch, Sequence, Direction, Context_Binding) (2) Derive the Packet Key: Epoch_Key = HKDF-Expand(Root_Secret, "SGCP_EPOCH" || Epoch || Context_Binding, key_length) Packet_Key = HKDF-Expand(Epoch_Key, "SGCP_PACKET" || Direction || Sequence, key_length) (3) Construct the AEAD Additional Data: AAD = Session_ID || Epoch || Sequence || Direction || Context_Binding || Key_ID (4) AEAD-Encrypt the application data: (Ciphertext, Tag) = AEAD-Encrypt(Packet_Key, Nonce, Plaintext, AAD) Nonce = Epoch || Sequence || Direction (5) Derive the Transformation State: Transform_State = HKDF-Expand(Epoch_Key, "SGCP_TRANSFORM" || Sequence || Direction, transform_length) (6) Apply the state-dependent transformation: Wire_Payload = Transform(Ciphertext || Tag, Transform_State) (7) Construct the wire packet (see Section 5.3) and transmit. (8) Advance the local sequence number: Sequence += 1. NOTE: The state-dependent transformation provides additional differentiation of wire-level byte patterns but is NOT the primary confidentiality or integrity mechanism. The AEAD construction MUST provide those guarantees. 5.9. Phase 9 - Receiver Processing Upon receipt of a packet the receiver performs: (1) Parse the packet header (Section 5.1). (2) Look up the session by Session_ID. (3) Read the Epoch from the packet header. (4) Validate the Sequence number against the replay window (Section 4.11). (5) Verify the Key_ID matches the expected value: Expected_Key_ID = H(Session_ID || Epoch || Direction || Sequence) If it does not match, the packet MUST be discarded. (6) Derive the Epoch_Key and Packet_Key as in Section 4.8 step 2. (7) Derive the Transform_State as in Section 4.8 step 5. (8) Reverse the wire transformation: (Ciphertext || Tag) = Untransform(Wire_Payload, Transform_State) (9) Reconstruct the AAD as in Section 4.8 step 3. (10) AEAD-Decrypt and verify the authentication tag: Plaintext = AEAD-Decrypt(Packet_Key, Nonce, Ciphertext, Tag, AAD) If verification fails, the packet MUST be silently discarded. (11) Accept the state transition: advance the sequence window. (12) Evaluate Context and Trust State (Section 4.12). The receiver MUST NOT attempt multiple candidate transformations or keys until decryption succeeds. Only one deterministically derived state is tested per packet; ambiguity-based oracle attacks are thereby prevented. 5.10. Phase 10 - State Advancement After successful packet verification, both the sender and receiver independently advance their local state: Sequence += 1 Node_ID = H("SGCP_NODE" || Session_ID || Epoch || Sequence) The state graph correspondingly grows by one node and one edge. Because both endpoints derive the new state identically, they remain synchronized without any additional protocol messages. 5.11. Phase 11 - Replay Protection Each endpoint maintains a replay window per (Session_ID, Epoch, Direction) tuple. Window_High = highest accepted Sequence number Window_Bits = a bitmap covering [Window_High - W + 1, Window_High] where W is the configured window size (RECOMMENDED: W >= 64). Upon receipt of a packet with Sequence S: o If S <= Window_High - W: DISCARD (too old). o If S is within the window and the bit is set: DISCARD (duplicate). o If S > Window_High: advance Window_High to S and set the corresponding bit (after successful AEAD verification). o If S is within the window and the bit is not set: accept (after successful AEAD verification) and set the bit. A new epoch resets the replay window for that direction. 5.12. Phase 12 - Continuous Context Monitoring SGCP does not permanently trust a session once established. Both endpoints SHOULD continuously monitor: o Device context (hardware posture, OS integrity) o Network context (interface, IP address if policy-relevant) o Port context (port rebinding events) o Socket context (socket close/reopen) o Session context (session age, packet count) o Behavioral context (traffic anomalies) The monitoring engine evaluates whether the current context is consistent with the policy applicable to the session. A detected change does not automatically imply compromise; the trust engine determines the appropriate response: Context Change | v Trust Engine | +-----------+-----------+ v v v ACCEPT REAUTH REVOKE | | | v v v Continue Verify Terminate 6. Packet Format 6.1. Common Packet Header All SGCP packets begin with the following fixed header. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version (8) | Packet_Type(8)| Flags (8) | Reserved (8) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Session_ID (128 bits) | | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Epoch (32 bits) | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | Sequence Number (64 bits) | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | Direction | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key_ID (64 bits) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Payload Length (32) | Header Checksum (16) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Version (8 bits): SGCP version. This document defines version 1 (0x01). Packet_Type (8 bits): Type of packet: 0x01 = CLIENT_HELLO 0x02 = SERVER_HELLO 0x03 = CLIENT_FINISH 0x04 = DATA 0x05 = CONTEXT_CHANGE 0x06 = KEY_ROTATION 0x07 = REAUTH_REQUEST 0x08 = REAUTH_RESPONSE 0x09 = RECOVERY_INIT 0x0A = RECOVERY_ACK 0x0B = ALERT 0x0C = SESSION_CLOSE 0x10 = MEDIA_SEGMENT 0x11 = MEDIA_ACK Flags (8 bits): Bitmask: Bit 0 = FULL_DUPLEX Bit 1 = EPOCH_BOUNDARY Bit 2 = CONTEXT_CHANGED Bit 3 = KEY_ROTATION_PENDING Bits 4-7 = Reserved Direction (8 bits): 0x01 = Client->Server 0x02 = Server->Client Session_ID (128 bits): Unique session identifier derived in Phase 5. Epoch (32 bits): Current epoch number. Sequence (64 bits): Per-direction monotonically increasing packet sequence number. Wraps to a new epoch before reaching 2^64 - 1. Key_ID (64 bits): Non-secret key identifier (truncated to 64 bits): Key_ID = H(Session_ID || Epoch || Direction || Sequence)[0:8] Payload_Length(32 bits): Length of the payload (transformed ciphertext + AEAD tag) in bytes. Header_Checksum(16 bits):CRC-16 over all header fields except this field itself. 6.2. Handshake Packets Handshake packets (Packet_Type 0x01-0x03) carry their data in cleartext TLV (Type-Length-Value) structures within the payload region. The AEAD protection of handshake messages uses a handshake-specific key: Handshake_Key = HKDF-Expand(Root_Secret, "SGCP_HANDSHAKE", key_length) The Session_ID, Epoch, and Sequence fields in the header of handshake packets are set to zero for MESSAGE_1 (CLIENT_HELLO) and populated from Phase 5 for MESSAGE_3 (CLIENT_FINISH). 6.3. Data Packets Data packets (Packet_Type 0x04 and 0x10-0x11) carry the wire payload produced by Phase 8: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Common Header (Section 5.1) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Wire_Payload (variable) | | (= Transform(Ciphertext || AEAD_Tag, Transform_State)) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ For MEDIA_SEGMENT (0x10) packets an additional media header immediately precedes the Wire_Payload within the encrypted plaintext: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Media_Type (8)| Codec (8) | Segment_Index (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Total_Segments (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Byte_Offset_in_File (64) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Segment_Byte_Length (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | File_Hash (SHA-256, 256 bits = 32 bytes) | | | | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Segment_Data (variable) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Media_Type: 0x01 = AUDIO Codec: 0x01 = MP3, 0x02 = AAC, 0x03 = OPUS, 0xFF = RAW File_Hash: SHA-256 over the complete, unencrypted file, enabling end-to-end integrity verification at the receiver after all segments are reassembled. 7. State Graph Model 7.1. Graph Nodes A node represents a valid cryptographic communication state. Each node contains: Node = { Node_ID : H("SGCP_NODE" || Session_ID || Epoch || Sequence), Session_ID : , Epoch : , Sequence : , Context_Binding : , Key_ID : , Direction : Server | Server->Client>, State_Status : ACTIVE | SUSPENDED | TERMINATED, Chain_Hash : H("SGCP_CHAIN" || Prev_Chain_Hash || Node_ID || Sequence || Epoch) } The secret keys associated with a node MUST NOT be stored inside the node record. They are derived on demand from the key hierarchy (Section 7). 7.2. Graph Edges An edge represents a permitted, cryptographically authenticated transition between two nodes: Edge = { Previous_Node : Node_ID(k), Next_Node : Node_ID(k+1), Sequence : k, Event : , Context_Version : , Transition_Type : NORMAL | EPOCH_BOUNDARY | REAUTH | RECOVERY | REVOCATION, Authentication_Proof: AEAD_Tag(Packet(k)) } The Authentication_Proof is the AEAD tag of the packet that caused the state transition. It cannot be forged without knowledge of the Packet_Key. 7.3. Deterministic State Derivation The graph is reproducible from the authenticated state; it does not need to be transmitted as a secret object. Any endpoint that possesses the Root Secret, Session_ID, Epoch, and Context_Binding can independently reconstruct all node and edge identifiers. Node_Key = HKDF-Expand(Root_Secret, "SGCP_NODEKEY" || Session_ID || Epoch || Node_ID, key_length) Packet_Key = HKDF-Expand(Epoch_Key, "SGCP_PACKET" || Direction || Sequence, key_length) The KDF domain-separation labels ensure that keys derived for different purposes cannot be confused. 7.4. Node and Edge Relationship Consider: N10 ----E10----> N11 The sender knows (Current_Node = N10, Sequence = 10). It derives: Edge_State = F(Root_Secret, Epoch, 10, Context_Binding) The receiver independently derives the same expected edge state. If AEAD verification succeeds, the transition N10 -> N11 is accepted. If verification fails, the transition is rejected and the sequence window is not advanced. 8. Key Hierarchy 8.1. Root Secret The Root Secret is derived in Phase 4 (Section 4.4) and is the sole ancestor of all cryptographic keys in the session. It MUST be protected in memory (e.g., using OS-level secure memory APIs) and erased when the session terminates. 8.2. Epoch Key An Epoch Key is derived for each epoch: Epoch_Key = HKDF-Expand(Root_Secret, "SGCP_EPOCH" || uint32(Epoch) || Context_Binding, key_length) A new Epoch Key is derived whenever: o A key-rotation event occurs. o A context change triggers reauthentication. o A session-recovery event completes. Old Epoch Keys SHOULD be erased after epoch transition to maintain forward secrecy within the session. 8.3. Packet Key Each packet uses a unique Packet Key: Packet_Key = HKDF-Expand(Epoch_Key, "SGCP_PACKET" || Direction || uint64(Sequence), key_length) This ensures that no two packets in the session ever share a key. 8.4. Transformation State Key Transform_State = HKDF-Expand(Epoch_Key, "SGCP_TRANSFORM" || uint64(Sequence) || Direction, transform_length) 8.5. Domain Separation Labels The following labels MUST be used as-is (ASCII, no null terminator) in all HKDF-Expand info parameters: "SGCP_ROOT_v1" "SGCP_ROOT_PQ_v1" "SGCP_SID" "SGCP_HANDSHAKE" "SGCP_EPOCH" "SGCP_PACKET" "SGCP_TRANSFORM" "SGCP_NODEKEY" "SGCP_CHAIN" "SGCP_CHAIN_GENESIS" "SGCP_CTX_BIND_v1" "SGCP_RECOVERY" Implementations MUST NOT use unlabeled or unscoped derivations. 9. State-Dependent Packet Transformation The state-dependent transformation is a deterministic, invertible byte-level operation applied to the AEAD ciphertext+tag before the packet is placed on the wire. Its purpose is to differentiate the wire representation of successive packets even when the plaintext is identical, providing an additional layer of traffic analysis resistance. The transformation MUST satisfy: o Determinism: given the same (Ciphertext, Transform_State), the output is always identical. o Invertibility: the receiver can recover Ciphertext from the wire payload and Transform_State. o Non-ambiguity: there is exactly one inverse. o Independence from the AEAD primitive: it MUST NOT affect the integrity guarantee of the AEAD tag. A compliant implementation MAY use: o XOR with the Transform_State stream (simplest, low overhead). o A stream cipher initialized with Transform_State as key/nonce. o A byte-transposition permutation keyed by Transform_State. Sender: Wire_Payload = Transform(Ciphertext || Tag, Transform_State) Receiver: (Ciphertext || Tag) = Untransform(Wire_Payload, Transform_State) Plaintext = AEAD-Decrypt(Packet_Key, Nonce, Ciphertext, Tag, AAD) The transformation MUST NOT be used as a substitute for encryption. Confidentiality and integrity are guaranteed by the AEAD construction. 10. Epoch Architecture A session is divided into one or more epochs. Each epoch possesses: o A unique epoch number (monotonically increasing). o A distinct Epoch Key derived from the Root Secret and the epoch number. o An independent sequence-number space starting from 0. o An independent replay window. Normal operation within a single epoch: Epoch 0: N0 -> N1 -> N2 -> N3 -> ... -> N(max) The complete session timeline: SESSION S1 Epoch 0 N0 -> N1 -> N2 -> N3 | | Context Change / Key Rotation v Epoch 1 N0' -> N1' -> N2' -> N3' | | Key Rotation v Epoch 2 N0'' -> N1'' -> N2'' 10.1. Context Change When a context-change event is detected, the trust engine determines one of three responses: ACCEPT: Context changed but within policy bounds. Continue the current epoch. Update Context_Binding. REAUTH: Context changed beyond policy bounds. Initiate reauthentication. Upon success, derive a new Epoch Key and reset the sequence space. REVOKE: Context indicates potential compromise. Immediately terminate the session and revoke the session credentials. The graph during a REAUTH transition: Context Change | v N4 -------------> T0 (Transition Node) | | Reauthentication v N0' (Epoch 1, Sequence 0) | v N1' -> N2' 10.2. Key Rotation Proactive key rotation SHOULD occur: o After a configurable number of packets (e.g., every 2^32 packets) within one epoch. o After a configurable time interval. o Upon receipt of a KEY_ROTATION packet from the peer. The key-rotation procedure: (1) The initiating endpoint sends a KEY_ROTATION packet with Flags bit 3 (KEY_ROTATION_PENDING) set. (2) The responding endpoint acknowledges. (3) Both endpoints derive: New_Epoch = Epoch + 1 New_Epoch_Key = HKDF-Expand(Root_Secret, "SGCP_EPOCH" || New_Epoch || Context_Binding, key_length) (4) Both endpoints reset their sequence numbers to 0 and replay windows for the new epoch. 11. State Transition Engine 11.1. Transition Events The transition engine accepts the following events: PACKET_ACCEPTED - A data packet passed full verification. KEY_ROTATION - A proactive key-rotation request. CONTEXT_CHANGED - A context-monitoring event. REAUTHENTICATED - Reauthentication completed. SESSION_RECOVERY - A recovery flow completed. TIMEOUT - A configurable inactivity timeout. POLICY_CHANGE - An external policy update. REVOCATION - A certificate or session revocation. The transition function: Next_State = Transition(Current_State, Event, Context, Policy) produces a new state only if the transition is policy-permitted. 11.2. Transition Examples Normal operation: N100 -- PACKET_ACCEPTED --> N101 Key rotation: N101 -- KEY_ROTATION --> N0(Epoch+1) Context change with reauthentication: N200 -- CONTEXT_CHANGED --> T0 T0 -- REAUTHENTICATED --> N0(Epoch+1) Revocation: N300 -- REVOCATION --> TERMINATED 12. Session Recovery Network interruptions may cause a session to become disconnected. The reconnecting endpoint MUST prove its identity and establish fresh cryptographic material before resuming. Recovery flow: CLIENT SERVER | | |--- RECOVERY_INIT ----------------->| | (Session_ID_Hint, Device_ID, | | Client_Nonce_R) | | | |<-- Recovery_Challenge -------------| | | |--- RECOVERY_ACK ------------------>| | (Challenge_Response_R, | | Client_DH_Public_Key_R) | | | |<-- Server_DH_Public_Key_R ---------| | | | [ Both sides derive ] | | Recovery_Secret = | | HKDF-Extract("SGCP_RECOVERY", | | DH_R || Old_Root_Secret_Hash | | || Client_Nonce_R | | || Server_Nonce_R) | | | | New Epoch(N), Sequence = 0 | The server MUST NOT accept a claimed Session_ID without completing the challenge-response. Old traffic keys MUST NOT be reused after a recovery event. The recovery flow MUST produce a new epoch. The recovery graph: Epoch 4 N500 -> N501 -> N502 | | CONNECTION LOST v R0 (Recovery Start) | | Recovery Authentication v R1 | | New Key Establishment v Epoch 5 N0' -> N1' -> N2' 13. Sender-Receiver Synchronization The fundamental synchronization guarantee of SGCP: COMMON ROOT SECRET | +-----------+-----------+ v v CLIENT SERVER | | Context Context | | Epoch Epoch | | Sequence Sequence | | v v State F() State F() | | +----------+------------+ v SAME EXPECTED STATE Both endpoints derive the same state without transmitting any secret. State divergence can arise from: o Packet loss or reordering o Connection interruption o Implementation errors o An attack Because state is derived from the sequence number (not from the previous packet's decryption result), the receiver CAN reconstruct the expected state for any received sequence number within the current epoch, supporting out-of-order delivery: State(N) = F(Epoch_Key, N, Direction) A sliding-window replay filter (Section 4.11) prevents replays while accommodating reordering. When the receiver detects irrecoverable state divergence, it MUST initiate session recovery (Section 11) or terminate the session. 14. Full-Duplex MP3 Media Transfer Example This section provides a detailed, packet-level worked example of a full-duplex SGCP session transferring an MP3 audio file from the client to the server, while the server simultaneously sends acknowledgement data and status packets back to the client. 14.1. Scenario Description Endpoints: Client: Device_ID = "DEV-AUDIO-CLIENT-42" IP = 203.0.113.10, Port = 51234 Server: Device_ID = "SRV-MEDIA-PROCESSOR-07" IP = 198.51.100.20, Port = 8443 Transport: TCP (Protocol = 6) Direction Client->Server: transfers the MP3 file in segments. Direction Server->Client: sends per-segment acknowledgements and real-time processing status. This is full-duplex operation: both channels are active simultaneously. 14.2. MP3 File Parameters File: podcast_episode_42.mp3 Size: 7,340,032 bytes (7 MB exactly) SHA-256 Hash: A3F1...9C7D (256-bit value, abbreviated here) Bit Rate: 128 kbps Duration: ~7 min 41 sec Sample Rate: 44100 Hz Channels: Stereo (2 channels) MPEG Version: MPEG-1 Layer III ID3 Tag Length: 10,240 bytes (prepended to file) Segmentation: Segment Size: 8192 bytes (8 KiB per segment) Total Segs: 896 segments (= ceil(7340032 / 8192)) Last Seg Size: 7340032 mod 8192 = 0 bytes (file divides evenly into 896 x 8192 byte segments) The File_Hash covers the complete 7,340,032-byte file (including ID3 tag), computed as: File_Hash = SHA-256(podcast_episode_42.mp3) Illustrative value (for this example): File_Hash = A3F1 82B0 C441 79D3 5E6F 2A91 04BC 8D7E F203 4A56 87CD 19E0 23B4 56A7 89F0 1C2D 4E78 90AB CD12 34EF 5678 90BC 12DE 9C7D 14.3. Handshake Phase The following message sequence uses illustrative (non-real) cryptographic values. All multi-octet fields are in network byte order (big-endian). --- Message 1: CLIENT_HELLO --- Time: T+0.000s Direction: Client -> Server Header: Version = 0x01 Packet_Type = 0x01 (CLIENT_HELLO) Flags = 0x01 (FULL_DUPLEX) Session_ID = 0x00000000...00 (zero, pre-session) Epoch = 0x00000000 Sequence = 0x0000000000000000 Key_ID = 0x0000000000000000 Payload (cleartext TLV): ProtocolVersion = 0x0001 SupportedSuites = [ SGCP_X25519_AESGCM256_SHA256, SGCP_X25519_MLKEM768_AESGCM256_SHA256 ] Device_ID = "DEV-AUDIO-CLIENT-42" Certificate = Client_Nonce = 0x8A3F...1B2C (32 random bytes) Client_DH_Pub = 0x5C2D...7F4A (32 bytes, X25519 point) Client_KEM_Pub = 0x3A1B...E9D2 (1184 bytes, ML-KEM-768) --- Message 2: SERVER_HELLO --- Time: T+0.018s (18 ms round-trip) Direction: Server -> Client Header: Version = 0x01 Packet_Type = 0x02 (SERVER_HELLO) Flags = 0x01 (FULL_DUPLEX) Session_ID = 0x00000000...00 Epoch = 0x00000000 Sequence = 0x0000000000000000 Payload (cleartext TLV): SelectedSuite = SGCP_X25519_MLKEM768_AESGCM256_SHA256 Server_Certificate = Server_Nonce = 0x2F7C...4E8D (32 random bytes) Server_DH_Pub = 0xA1B2...CD3E (32 bytes, X25519 point) Server_KEM_CT = 0xB2C3...EF40 (1088 bytes, ML-KEM-768 ciphertext) Server_Challenge = 0xD4E5...1F60 (32 random bytes) Signature = 0x3045...8A21 (ECDSA-P256 signature over transcript hash) Client verifies: - Server certificate chain - Signature over (ClientHello || ServerHello_data) - Server's certificate is not revoked Client computes shared secrets: DH_Secret = X25519(Client_DH_Priv, Server_DH_Pub) = 0x9F2A...7C3B (32 bytes) KEM_Secret = ML-KEM-768.Decapsulate(Client_KEM_Priv, Server_KEM_CT) = 0xE1D2...4C5B (32 bytes) Root_Secret = HKDF-Extract("SGCP_ROOT_PQ_v1", DH_Secret || KEM_Secret || Client_Nonce || Server_Nonce || H(Client_Cert) || H(Server_Cert)) = 0x7B4A...F9CE (32 bytes) --- Message 3: CLIENT_FINISH --- Time: T+0.020s Direction: Client -> Server Session_ID derived: Session_ID = H("SGCP_SID" || Root_Secret || Client_Nonce || Server_Nonce) = 0xC3D4...A5B6 (16 bytes) Header: Version = 0x01 Packet_Type = 0x03 (CLIENT_FINISH) Flags = 0x01 (FULL_DUPLEX) Session_ID = 0xC3D4...A5B6 Epoch = 0x00000000 Sequence = 0x0000000000000000 Payload (Handshake_Key-AEAD encrypted): Challenge_Response = ECDSA-P256-Sign(Client_Private_Key, H("SGCP_CHALLENGE" || Server_Challenge || Client_Nonce)) = 0x3046...9B72 ClientFinish_MAC = HMAC-SHA256(Handshake_Key, H("SGCP_CFIN" || ClientHello || ServerHello)) = 0xA2B3...7C8D (32 bytes) Server verifies ClientFinish successfully. Context Binding: Context_Binding = H("SGCP_CTX_BIND_v1" || 0x0001 (Version) || "DEV-AUDIO-CLIENT-42" || 0x06 (TCP) || 0xC822 (51234) || 0x20FB (8443) || Socket_ID || Session_ID) = 0xF1A2...B3C4 (32 bytes) Epoch 0 Key: Epoch_0_Key = HKDF-Expand(Root_Secret, "SGCP_EPOCH" || 0x00000000 || Context_Binding, 32) = 0x4D5E...6F70 (32 bytes) Initial State Graph Nodes: N0_C2S = { (Client->Server direction) Node_ID = H("SGCP_NODE" || Session_ID || 0 || 0), Epoch = 0, Sequence = 0, Chain_Hash = H("SGCP_CHAIN_GENESIS" || Session_ID) } N0_S2C = { (Server->Client direction) Node_ID = H("SGCP_NODE" || Session_ID || 0 || 0 || "S2C"), Epoch = 0, Sequence = 0, Chain_Hash = H("SGCP_CHAIN_GENESIS" || Session_ID || "S2C") } Handshake complete at T+0.022s. Both sides are now in ACTIVE state with Epoch = 0, Sequence = 0. 14.4. MP3 Segment Transfer - Client to Server The client transmits the MP3 file in 896 segments of 8192 bytes each. The following shows the first 4 segments in detail. ====== DATA PACKET: Segment 0 (Sequence 0, Client->Server) ====== Time: T+0.025s Plaintext media header + segment data (before encryption): Media_Type = 0x01 (AUDIO) Codec = 0x01 (MP3) Segment_Index = 0x00000000 Total_Segments = 0x00000380 (896) Byte_Offset = 0x0000000000000000 Segment_Byte_Len = 0x00002000 (8192) File_Hash = A3F182B0...9C7D (32 bytes) Segment_Data = [bytes 0..8191 of podcast_episode_42.mp3, which include the ID3v2 header: "ID3" 0x03 0x00 0x00 0x00 0x00 0x0A 0x00 followed by ID3 frames...] Packet Key derivation (Epoch 0, Seq 0, C->S): Packet_Key_0 = HKDF-Expand(Epoch_0_Key, "SGCP_PACKET" || 0x01 || 0x0000000000000000, 32) = 0x1A2B...3C4D Nonce_0 = 0x00000000 || 0x0000000000000000 || 0x01 (Epoch=0, Seq=0, Dir=C->S) AAD_0 = Session_ID || 0x00000000 || 0x0000000000000000 || 0x01 || Context_Binding || Key_ID_0 (Ciphertext_0, Tag_0) = AES-256-GCM-Encrypt(Packet_Key_0, Nonce_0, Plaintext_0, AAD_0) Transform_State_0 = HKDF-Expand(Epoch_0_Key, "SGCP_TRANSFORM" || 0x0000000000000000 || 0x01, 8208) // len(Ciphertext_0 || Tag_0) = 8192+16 = 8208 Wire_Payload_0 = XOR(Ciphertext_0 || Tag_0, Transform_State_0) Wire Packet (hex header fields, illustrative): 01 10 01 00 ; Version=1, Type=MEDIA_SEGMENT, ; Flags=FULL_DUPLEX, Reserved=0 C3D4A5B6C7D8E9F0 ; Session_ID (first 8 of 16 bytes) A1B2C3D4E5F6A7B8 ; Session_ID (last 8 bytes) 00000000 ; Epoch = 0 0000000000000000 ; Sequence = 0 01 ; Direction = C->S 00 ; Reserved [Key_ID_0 8 bytes] 00002010 ; Payload Length = 8208 [CRC-16] [Wire_Payload_0: 8208 bytes] Node advanced: Sequence_C2S = 1 N1_C2S.Chain_Hash = H("SGCP_CHAIN" || N0_C2S.Chain_Hash || N1_C2S.Node_ID || 1 || 0) ====== DATA PACKET: Segment 1 (Sequence 1, Client->Server) ====== Time: T+0.030s (5 ms after previous) Segment_Index = 0x00000001 Byte_Offset = 0x0000000000002000 (8192) Segment_Data = [bytes 8192..16383 of mp3 file] Packet_Key_1 = HKDF-Expand(Epoch_0_Key, "SGCP_PACKET" || 0x01 || 0x0000000000000001, 32) = 0x4D5E...6F80 (different from Key_0) Key_ID_1 = H(Session_ID || 0 || 0x01 || 1)[0:8] [Processing identical to Segment 0 with updated indices] ====== DATA PACKET: Segment 2 (Sequence 2, Client->Server) ====== Time: T+0.035s Segment_Index = 0x00000002 Byte_Offset = 0x0000000000004000 (16384) Segment_Data = [bytes 16384..24575 of mp3 file] ====== DATA PACKET: Segment 3 (Sequence 3, Client->Server) ====== Time: T+0.040s Segment_Index = 0x00000003 Byte_Offset = 0x0000000000006000 (24576) Segment_Data = [bytes 24576..32767 of mp3 file] State Graph after 4 segments (C->S direction): N0 --[Pkt0]--> N1 --[Pkt1]--> N2 --[Pkt2]--> N3 --[Pkt3]--> N4 Each node is cryptographically distinct; each packet used a unique key. 14.5. Full-Duplex Operation - Simultaneous Exchange While the client is sending MP3 segments, the server sends acknowledgement and status packets back on the Server->Client channel. Both channels operate independently and concurrently. Timeline (T+0.025s to T+0.100s): Time Client->Server Server->Client ------- -------------------------- ------------------------------------ T+0.025 MEDIA_SEGMENT Seq=0 (8KB) T+0.030 MEDIA_SEGMENT Seq=1 (8KB) T+0.033 MEDIA_ACK Seq=0 (ack Seg 0) T+0.035 MEDIA_SEGMENT Seq=2 (8KB) T+0.038 MEDIA_ACK Seq=1 (ack Seg 1) T+0.040 MEDIA_SEGMENT Seq=3 (8KB) T+0.043 MEDIA_ACK Seq=2 (ack Seg 2) T+0.045 MEDIA_SEGMENT Seq=4 (8KB) T+0.048 MEDIA_ACK Seq=3 (ack Seg 3) T+0.050 MEDIA_SEGMENT Seq=5 (8KB) T+0.055 STATUS Seq=4 (decode OK) ... T+0.880 MEDIA_SEGMENT Seq=895(8KB) (final segment) T+0.883 MEDIA_ACK Seq=895 (all OK) T+0.885 STATUS Seq=... (complete) ====== ACK PACKET: Segment 0 ACK (Sequence 0, Server->Client) === Time: T+0.033s Server derives S->C Packet Key: Packet_Key_S2C_0 = HKDF-Expand(Epoch_0_Key, "SGCP_PACKET" || 0x02 || 0x0000000000000000, 32) = 0x7E8F...9A0B (entirely different from any C->S key) Plaintext (before encryption): Type: MEDIA_ACK Acknowledged_Seq = 0x0000000000000000 (ack for C->S Seq 0) Segment_Index = 0x00000000 Received_Bytes = 0x00002000 (8192) Integrity_OK = 0x01 Server_Timestamp = T+0.033s Cumulative_Received = 8192 Wire Packet Header: 01 11 01 00 ; Version=1, Type=MEDIA_ACK, ; Flags=FULL_DUPLEX [Session_ID 16 bytes] 00000000 ; Epoch = 0 0000000000000000 ; Sequence = 0 (S->C channel) 02 ; Direction = S->C 00 [Key_ID_S2C_0] [Payload Length] [CRC-16] [Wire_Payload] ====== STATUS PACKET (Sequence 4, Server->Client) ============== Time: T+0.055s (after 5 segments received) Server sends a processing status update: Plaintext (before encryption): Type: PROCESSING_STATUS Status_Code = 0x00 (OK) Segments_Decoded = 5 Decode_Quality = 100% Audio_Duration_S = 0.298 (298 ms of audio decoded so far from 5 x 8192 bytes at 128kbps) Buffer_Level = 42% Peak_Amplitude = -12 dBFS Checksum_Partial = SHA-256(bytes 0..40959 of original mp3) Key derivation (S->C, Seq = 4): Packet_Key_S2C_4 = HKDF-Expand(Epoch_0_Key, "SGCP_PACKET" || 0x02 || 0x0000000000000004, 32) = 0xB0C1...D2E3 State Graph (S->C direction) after 5 ACKs + STATUS: N0 -> N1 -> N2 -> N3 -> N4 -> N5 Both state graphs (C->S and S->C) advance in parallel and independently, as SGCP is inherently full-duplex. 14.6. Epoch Transition During Transfer After 512 segments are sent (Sequence = 512 on C->S channel), the client initiates a proactive key rotation to demonstrate epoch advancement during the transfer. Time: T+0.453s ====== KEY_ROTATION PACKET (Sequence 512, Client->Server) ====== Header: Packet_Type = 0x06 (KEY_ROTATION) Flags = 0x09 (FULL_DUPLEX | KEY_ROTATION_PENDING) Sequence = 512 Epoch = 0 Payload (encrypted with Epoch_0 key): New_Epoch = 1 Reason = PROACTIVE_ROTATION MAC = HMAC-SHA256(Epoch_0_Key, "SGCP_KEYROT" || Session_ID || 1) Server receives KEY_ROTATION, verifies MAC. ====== KEY_ROTATION ACK (Sequence 256, Server->Client) ========= Time: T+0.455s Server sends KEY_ROTATION_ACK back on S->C channel: Packet_Type = 0x06 (KEY_ROTATION) Flags = 0x08 (KEY_ROTATION_PENDING) Sequence = 256 (S->C sequence at this point) Epoch = 0 Payload: New_Epoch = 1 ACK_MAC = HMAC-SHA256(Epoch_0_Key, "SGCP_KEYROT_ACK" || Session_ID || 1) Both sides derive Epoch 1: Epoch_1_Key = HKDF-Expand(Root_Secret, "SGCP_EPOCH" || 0x00000001 || Context_Binding, 32) = 0x5F6A...7B8C (entirely new key material) Both sides reset: C->S: Sequence = 0, Epoch = 1, replay window cleared S->C: Sequence = 0, Epoch = 1, replay window cleared Epoch_0_Key is erased from memory. State Graph at Epoch Transition: Epoch 0 (C->S): N0 -> N1 -> ... -> N512 (KEY_ROTATION boundary) | | KEY_ROTATION event (E512) v Epoch 1 (C->S): N0' -> N1' -> ... (continuing from Segment 512) Epoch 0 (S->C): N0 -> N1 -> ... -> N256 (KEY_ROTATION ACK boundary) | | KEY_ROTATION_ACK event v Epoch 1 (S->C): N0' -> N1' -> ... ====== POST-ROTATION SEGMENT (Epoch 1, Sequence 0) ============= Time: T+0.457s (first packet in Epoch 1) Client sends Segment 512 using Epoch 1 keys: Packet_Key_E1_C2S_0 = HKDF-Expand(Epoch_1_Key, "SGCP_PACKET" || 0x01 || 0x0000000000000000, 32) = 0x2C3D...4E5F Header: Epoch = 0x00000001 Sequence = 0x0000000000000000 Flags = 0x03 (FULL_DUPLEX | EPOCH_BOUNDARY) Payload: Segment_Index = 0x00000200 (512) Byte_Offset = 0x0000000000400000 (512 * 8192 = 4194304) Segment_Data = [bytes 4194304..4202495 of mp3 file] Server verifies using Epoch_1_Key; state graph continues in the new epoch. 14.7. Completion and Session Summary Time: T+0.880s (final segment) Client sends Segment 895 (the last segment): Segment_Index = 0x0000037F (895) Byte_Offset = 0x00000000006FE000 Segment_Byte_Len = 0x00002000 (8192) Flags = 0x01 (FULL_DUPLEX) Server receives all 896 segments, reassembles the file, and verifies the end-to-end integrity: Received_File_Hash = SHA-256(reassembled data) Verify: Received_File_Hash == File_Hash from Segment 0 == A3F1...9C7D Result: PASS Server sends final STATUS packet (S->C): Status_Code = 0x00 (OK) All_Segments_Received = TRUE File_Integrity = PASS Total_Bytes_Received = 7340032 Total_Segments = 896 Session Close: Client sends SESSION_CLOSE (0x0C) packet. Server acknowledges. Both endpoints: - Erase all epoch keys. - Erase the Root Secret. - Record session termination in the device registry. Transfer summary: C->S Packets: 896 MEDIA_SEGMENT + 1 KEY_ROTATION + 1 SESSION_CLOSE = 898 packets S->C Packets: 896 MEDIA_ACK + ~179 STATUS + 1 KEY_ROTATION_ACK = ~1077 packets Epochs used: 2 (Epoch 0: segs 0-511; Epoch 1: segs 512-895) Total data: 7,340,032 bytes transferred End-to-end integrity verified by File_Hash comparison. Every packet used a unique, independently derived key. 15. Complete State Model The complete per-direction session state maintained by each endpoint is: STATE = { Session_ID, // 128-bit session identifier Epoch, // 32-bit epoch counter Sequence, // 64-bit per-direction sequence counter Direction, // C->S or S->C Node_ID, // current graph node identifier Key_ID, // current non-secret key identifier Context_Binding, // 256-bit context hash Device_State, // device trust/posture information Port_State, // port binding information Socket_State, // socket binding information Trust_State, // session trust level Replay_State, // (Window_High, Window_Bits[W]) Policy_Version, // applicable policy revision State_Version, // monotonic state-version counter Chain_Hash // hash-chain pointer to current node } Secret keys (Root_Secret, Epoch_Key, etc.) are NOT stored in the state record; they are derived from the Root Secret on demand. The Root Secret is stored in a separate, protected memory region. Not every field of the state needs to be transmitted in every packet; many fields are maintained locally and derived cryptographically. 16. Security Considerations 16.1. Attack Surface Analysis SGCP's security properties and the corresponding threats they mitigate are summarized below. +-----------------------------+-----------------------------------+ | Property | Threat Mitigated | +-----------------------------+-----------------------------------+ | Mutual authentication | Impersonation, MITM | | ECDH key establishment | Passive eavesdropping | | Per-packet unique keys | Key compromise propagation | | Context binding | Session transplantation | | Authenticated state edges | Fake state injection | | Replay window | Replay attacks | | Epoch rotation | Long-term key exposure | | Session recovery auth | Session token replay | | Hash chain | State history tampering | | Deterministic state rule | Oracle attacks on transformation | | ML-KEM hybridization | Quantum-computer attacks | +-----------------------------+-----------------------------------+ 16.2. Replay Attacks The replay window (Section 4.11) rejects packets with a sequence number that has already been accepted within the current epoch. The AEAD construction ensures that a replayed packet cannot be modified to appear as a new packet (the AAD includes the sequence number and epoch). An epoch boundary resets the sequence space; old-epoch packets MUST NOT be accepted in a new epoch. 16.3. State Divergence When the receiver detects a sequence number that does not correspond to an expected state, it evaluates recoverability: o If the discrepancy is within the replay window size and the packet successfully passes AEAD verification: accept and update the window (handles reordering). o If the discrepancy exceeds the window or AEAD fails consistently: the receiver SHOULD initiate session recovery (Section 11). Termination is preferred over any attempt to resynchronize by guessing states. Implementations MUST NOT attempt to brute-force candidate transform states or packet keys. 16.4. Deterministic State Security Rule The most critical security rule in SGCP: The receiver MUST derive exactly ONE expected state for a received packet and test it. If the single test fails, the packet is discarded. The receiver MUST NOT iterate over multiple candidate states or transformations. Violating this rule creates an oracle that could allow an adversary to learn information about the key hierarchy by submitting crafted packets and observing whether they are accepted. 17. IANA Considerations This document requests the following IANA registrations. Registry: SGCP Cipher Suites Value Name ----- ---- 0x0001 SGCP_X25519_AESGCM256_SHA256 0x0002 SGCP_P256_AESGCM256_SHA256 0x0003 SGCP_X25519_MLKEM768_AESGCM256_SHA256 0x0004 SGCP_P256_MLKEM1024_AESGCM256_SHA384 Registry: SGCP Packet Types Value Name ----- ---- 0x01 CLIENT_HELLO 0x02 SERVER_HELLO 0x03 CLIENT_FINISH 0x04 DATA 0x05 CONTEXT_CHANGE 0x06 KEY_ROTATION 0x07 REAUTH_REQUEST 0x08 REAUTH_RESPONSE 0x09 RECOVERY_INIT 0x0A RECOVERY_ACK 0x0B ALERT 0x0C SESSION_CLOSE 0x10 MEDIA_SEGMENT 0x11 MEDIA_ACK Registry: SGCP Alert Codes Value Name ----- ---- 0x01 AUTH_FAILURE 0x02 DECRYPTION_FAILURE 0x03 REPLAY_DETECTED 0x04 STATE_MISMATCH 0x05 CONTEXT_VIOLATION 0x06 POLICY_VIOLATION 0x07 SESSION_EXPIRED 0x08 REVOCATION 0x09 INTERNAL_ERROR 0xFF CLOSE_NOTIFY Registry: SGCP KDF Domain Separation Labels Label (ASCII) Usage ------------------ ---------------------------------------- SGCP_ROOT_v1 Root secret derivation (classical) SGCP_ROOT_PQ_v1 Root secret derivation (hybrid PQ) SGCP_SID Session ID derivation SGCP_HANDSHAKE Handshake traffic key SGCP_EPOCH Epoch key derivation SGCP_PACKET Per-packet key derivation SGCP_TRANSFORM Transformation state derivation SGCP_NODEKEY Node key derivation SGCP_CHAIN Hash chain node derivation SGCP_CHAIN_GENESIS Initial hash chain seed SGCP_CTX_BIND_v1 Context binding hash SGCP_RECOVERY Session recovery secret derivation 18. References 18.1. Normative References [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC5869] Krawczyk, H. and P. Eronen, "HMAC-based Extract-and- Expand Key Derivation Function (HKDF)", RFC 5869, DOI 10.17487/RFC5869, May 2010, . [RFC7748] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves for Security", RFC 7748, DOI 10.17487/RFC7748, January 2016, . [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, January 2017, . [RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, . [FIPS203] National Institute of Standards and Technology, "Module-Lattice-Based Key-Encapsulation Mechanism Standard", NIST FIPS 203, August 2024, . [FIPS197] National Institute of Standards and Technology, "Advanced Encryption Standard (AES)", NIST FIPS 197, November 2001, . 18.2. Informative References [RFC9147] Rescorla, E., Tschofenig, H., and N. Modadugu, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", RFC 9147, DOI 10.17487/RFC9147, April 2022, . [RFC5905] Mills, D., Martin, J., Burbank, J., and W. Kasch, "Network Time Protocol Version 4: Protocol and Algorithms Specification", RFC 5905, DOI 10.17487/RFC5905, June 2010, . [LAMPORT1979] Lamport, L., "Constructing Digital Signatures from a One-Way Function", SRI International Technical Report CSL-98, 1979. Appendix A. Graph Interaction Diagrams A.1. Normal Full-Duplex Operation CLIENT (C->S direction) SERVER ================================ ================================= Epoch=0, Seq=0, Node=N0_C2S Epoch=0, Seq=0, Node=N0_C2S | | |--- MEDIA_SEGMENT(Seq=0) -----> | | | verifies, advances to N1_C2S | |--- MEDIA_ACK(S2C,Seq=0) ----->| |--- MEDIA_SEGMENT(Seq=1) -----> | | advances to N2_C2S | verifies, advances to N2_C2S ... A.2. Epoch Boundary Epoch=0, Seq=511, Node=N511_C2S | |--- KEY_ROTATION(Seq=512) ----->| | |--- KEY_ROTATION_ACK --------->| | Epoch=1, Seq=0, Node=N0'_C2S (Epoch_0_Key erased) |--- MEDIA_SEGMENT(Epoch=1,Seq=0)-->| A.3. Session Recovery CONNECTION LOST | |--- RECOVERY_INIT ------------>| |<-- Recovery_Challenge --------| |--- RECOVERY_ACK ------------->| |<-- Server_DH_Public_Key_R ----| | Epoch=N+1, Seq=0 (fresh keys) |--- MEDIA_SEGMENT(Epoch=N+1) ->| Appendix B. Test Vectors (Illustrative) The following values are illustrative only and do not constitute real cryptographic test vectors. Implementors MUST generate test vectors using real implementations of the specified primitives. Session parameters: Device_ID = "DEV-TEST-01" Client_Nonce = 32 bytes of 0xAA Server_Nonce = 32 bytes of 0xBB DH_Secret = 32 bytes of 0xCC (hypothetical) KEM_Secret = 32 bytes of 0xDD (hypothetical) Root Secret (illustrative): HKDF-Extract("SGCP_ROOT_PQ_v1", 0xCC...CC || 0xDD...DD || 0xAA...AA || 0xBB...BB || H("DEV-TEST-01-CERT") || H("SRV-TEST-01-CERT")) = <32 bytes> Session_ID (illustrative): HKDF-Expand(Root_Secret, "SGCP_SID" || ..., 16) = <16 bytes> Real test vectors will be provided in a future revision of this document following independent implementation and verification. 17. Reference Implementation A reference implementation of SGCP is available as an open-source Python package on the Python Package Index (PyPI) under the package name "sgcp". PyPI: https://pypi.org/project/sgcp/ Installation: pip install sgcp The reference implementation covers all normative sections of this document: o Section 4 (X.509 Certificate Integration) o Section 5 (All 12 Phases — from initialization to context monitoring) o Section 6 (Wire Format — header, handshake, data, and media packets) o Section 7 (State Graph — nodes, edges, hash chain) o Section 8 (Key Derivation — Root Secret, Epoch Key, Packet Key, Transform State) o Section 9 (State-Dependent Transformation) o Section 10 (Epoch Management — rotation and key erasure) o Section 11 (State Transition Engine — FSM with trust policy) o Section 12 (Session Recovery — RECOVERY_INIT / RECOVERY_ACK) o Section 13 (Sender-Receiver Synchronization) o Section 14 (Full-Duplex MP3 Media Transfer — segmentation, transfer, and SHA-256 File_Hash integrity) o Section 15 (State Persistence format) o Section 16 (Security Requirements) The implementation provides two high-level endpoint classes: SGCPClient -- client endpoint (send/receive, full-duplex) SGCPServer -- server endpoint (send/receive, full-duplex) Both classes expose a unified receive() method that automatically dispatches on packet type (DATA 0x04 vs MEDIA_SEGMENT 0x10), returning an SGCPMessage envelope with the decrypted payload. Source repository: https://github.com/sgcp-wg/sgcp-protocol IETF Datatracker: https://datatracker.ietf.org/doc/draft-sgcp-state-graph-cryptographic-protocol/ Authors' Addresses Sripad Karthik Independent EMail: sripadkarthik@gmail.com URI: https://datatracker.ietf.org/doc/draft-sgcp-state-graph-cryptographic-protocol/ PyPI: https://pypi.org/project/sgcp/