Skip to main content

State Graph Cryptographic Protocol (SGCP)
draft-sgcp-state-graph-cryptographic-protocol-01

Document Type Active Internet-Draft (individual)
Author sripad karthik
Last updated 2026-08-17
RFC stream (None)
Intended RFC status (None)
Formats
Stream Stream state (No stream defined)
Consensus boilerplate Unknown
RFC Editor Note (None)
IESG IESG state I-D Exists
Telechat date (None)
Responsible AD (None)
Send notices to (None)
draft-sgcp-state-graph-cryptographic-protocol-01
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-01

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     : <from Phase 5>,
          Epoch          : 0,
          Sequence       : 0,
          Context_Binding: <from Phase 6>,
          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    : <current Context_Binding>,
          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      : <session identifier>,
          Epoch           : <epoch number>,
          Sequence        : <sequence number>,
          Context_Binding : <from Section 4.6>,
          Key_ID          : <non-secret key identifier>,
          Direction       : <Client->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               : <event type>,
          Context_Version     : <Context_Binding at time of edge>,
          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        = <DER-encoded X.509 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 = <DER-encoded X.509 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,
              <https://www.rfc-editor.org/rfc/rfc2119>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in
              RFC 2119 Key Words", BCP 14, RFC 8174,
              DOI 10.17487/RFC8174, May 2017,
              <https://www.rfc-editor.org/rfc/rfc8174>.

   [RFC5869]  Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-
              Expand Key Derivation Function (HKDF)", RFC 5869,
              DOI 10.17487/RFC5869, May 2010,
              <https://www.rfc-editor.org/rfc/rfc5869>.

   [RFC7748]  Langley, A., Hamburg, M., and S. Turner, "Elliptic
              Curves for Security", RFC 7748, DOI 10.17487/RFC7748,
              January 2016,
              <https://www.rfc-editor.org/rfc/rfc7748>.

   [RFC8032]  Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital
              Signature Algorithm (EdDSA)", RFC 8032,
              DOI 10.17487/RFC8032, January 2017,
              <https://www.rfc-editor.org/rfc/rfc8032>.

   [RFC8446]  Rescorla, E., "The Transport Layer Security (TLS)
              Protocol Version 1.3", RFC 8446,
              DOI 10.17487/RFC8446, August 2018,
              <https://www.rfc-editor.org/rfc/rfc8446>.

   [FIPS203]  National Institute of Standards and Technology,
              "Module-Lattice-Based Key-Encapsulation Mechanism
              Standard", NIST FIPS 203, August 2024,
              <https://doi.org/10.6028/NIST.FIPS.203>.

   [FIPS197]  National Institute of Standards and Technology,
              "Advanced Encryption Standard (AES)", NIST FIPS 197,
              November 2001,
              <https://doi.org/10.6028/NIST.FIPS.197>.

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,
              <https://www.rfc-editor.org/rfc/rfc9147>.

   [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,
              <https://www.rfc-editor.org/rfc/rfc5905>.

   [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/