Internet-Draft SGCP August 2026
Karthik Expires 16 February 2027 [Page]
Workgroup:
Individual Submission
Internet-Draft:
draft-sgcp-state-graph-cryptographic-protocol-00
Published:
Intended Status:
Experimental
Expires:
Author:
S. Karthik
Independent

State Graph Cryptographic Protocol (SGCP)

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 16 February 2027.

Table of Contents

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:

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.

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

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. Derived from the Epoch Key, sequence, and direction; 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 in Figure 1.

                     +----------------------+
                     |       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 ID  |
                     |  Context / Trust     |
                     +----------+-----------+
                                |
                                v
                     +----------+-----------+
                     |    STATE GRAPH       |
                     |  Nodes + Auth Edges  |
                     |  + Hash Chain        |
                     +----------+-----------+
                                |
                                v
                     +----------+-----------+
                     |   PACKET ENGINE      |
                     |  Key Derivation      |
                     |  AEAD Encryption     |
                     |  Transformation      |
                     +----------+-----------+
                                |
                                v
                              PACKET
                                |
                                v
                     +----------+-----------+
                     |       SERVER         |
                     |  State Reconstruction|
                     |  Verification        |
                     |  Decryption          |
                     |  Trust Evaluation    |
                     +----------------------+
Figure 1: SGCP High-Level Architecture

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:

  • X.509: "This public key belongs to this authenticated identity."
  • 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)
Figure 2: SGCP Complete Protocol Stack

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)

   server.crt
   server.key

Certificates MUST:

  • Be signed by a CA trusted by the remote endpoint, or be mutually pre-configured as trusted.
  • Contain a Subject Alternative Name (SAN) or Common Name (CN) entry matching the Device_ID used in the SGCP handshake.
  • Not be expired or revoked at the time of handshake.
  • Use a key algorithm consistent with the negotiated SGCP cipher suite (e.g., P-256 or Ed25519).

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:

  • Certificate loading:

       SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM);
       SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM);
    
  • Certificate verification:

       SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
       SSL_CTX_load_verify_locations(ctx, "ca-chain.crt", NULL);
    
  • Certificate inspection (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));
    
  • ECDH key generation (for SGCP's own DH 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, Root_Secret
                              |
                              v
                         SGCP takes over:
                              |
                              v
                     Session_ID = H("SGCP_SID" || ...)
                              |
                              v
                       Epoch_0_Key = HKDF-Expand(...)
                              |
                              v
                      Initial State N0
                              |
                              v
                    N0 -> N1 -> N2 -> N3 -> ...

   After ClientFinish: X.509 is no longer involved.
   Both sides enter the state graph at N0.
Figure 3: SGCP Handshake Certificate Flow

4.6. What X.509 Establishes vs. What SGCP Establishes

Table 1: X.509 vs. SGCP Responsibility Boundary
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. The client possesses:

  • A Device_ID (a stable unique device identifier)
  • A Device Public Key / Private Key pair
  • A certificate binding the public key to the Device_ID
  • An application-level identity (AppID)
  • 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. 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:

   Prelim_Context_Hash =
       H("SGCP_CTX_v1" || Device_ID || Protocol
         || Local_Port || Remote_Port || Socket_ID)

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))

If any validation step fails, the server MUST terminate the connection with an authentication-failure alert.

5.4. Phase 4 - Shared Secret Establishment

The recommended primitive is X25519 [RFC7748] or P-256. The raw shared secret MUST NOT be used directly as a traffic key. Instead:

   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:

   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

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 (C->S channel)
                Server->Client (S->C channel)
   Node_ID    = N0

SGCP is a full-duplex protocol. Each direction maintains independent sequence numbering and per-direction key derivation.

5.6. Phase 6 - Device-Port-Socket Context

The Context Binding is computed as:

   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.

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)
   }

Subsequent nodes form the hash chain:

   N(k+1).Chain_Hash =
       H("SGCP_CHAIN" || N(k).Chain_Hash || N(k).Node_ID
         || Sequence(k+1) || Epoch)

Normal graph growth:

   N0 --E0--> N1 --E1--> N2 --E2--> N3 --E3--> N4 ...

5.8. Phase 8 - Packet Creation

For every outgoing packet, the sender performs the following sequence:

(1)
Read (Session_ID, Epoch, Sequence, Direction, Context_Binding).
(2)

Derive Epoch_Key and 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 AAD = Session_ID || Epoch || Sequence || Direction || Context_Binding || Key_ID.
(4)

AEAD-Encrypt:

   (Ciphertext, Tag) =
       AEAD-Encrypt(Packet_Key, Nonce, Plaintext, AAD)

   Nonce = Epoch || Sequence || Direction
(5)

Derive Transform_State and apply wire transformation:

   Transform_State =
       HKDF-Expand(Epoch_Key,
                   "SGCP_TRANSFORM" || Sequence || Direction,
                   transform_length)

   Wire_Payload = Transform(Ciphertext || Tag, Transform_State)
(6)
Transmit the wire packet and advance Sequence += 1.

5.9. Phase 9 - Receiver Processing

Upon receipt of a packet the receiver performs:

(1)
Parse the packet header.
(2)
Look up the session by Session_ID.
(3)
Read Epoch from the packet header.
(4)
Validate the Sequence number against the replay window.
(5)
Verify Key_ID matches H(Session_ID||Epoch||Direction||Sequence). If not, discard.
(6)
Derive Epoch_Key, Packet_Key, and Transform_State.
(7)
Reverse the wire transformation.
(8)
AEAD-Decrypt and verify the authentication tag. If verification fails, silently discard.
(9)
Accept the state transition and advance the sequence window.
(10)
Evaluate Context and Trust State.

The receiver MUST NOT attempt multiple candidate transformations or keys. Only one deterministically derived state is tested per packet.

5.10. Phase 10 - State Advancement

After successful packet verification, both sender and receiver independently advance their local state:

   Sequence += 1
   Node_ID  = H("SGCP_NODE" || Session_ID || Epoch || Sequence)

5.11. Phase 11 - Replay Protection

Each endpoint maintains a replay window per (Session_ID, Epoch, Direction) tuple with Window_High and a Window_Bits 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:

  • If S <= Window_High - W: DISCARD (too old).
  • If S is within the window and the bit is set: DISCARD (duplicate).
  • If S > Window_High: advance window after AEAD verification.
  • If S is within the window and the bit is clear: accept after AEAD verification.

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 device, network, port, socket, session, and behavioral context.

          Context Change
                |
                v
          Trust Engine
                |
    +-----------+-----------+
    v           v           v
 ACCEPT       REAUTH     REVOKE
    |           |           |
    v           v           v
 Continue    Verify     Terminate
Figure 4: Trust Engine Decision

6. Packet Format

6.1. Common Packet 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)    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 5: SGCP Common Packet Header
Version (8 bits):
SGCP version. This document defines version 1 (0x01).
Packet_Type (8 bits):
   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):
   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-to-Server; 0x02 = Server-to-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):
H(Session_ID || Epoch || Direction || Sequence)[0:8].
Payload_Length (32 bits):
Length of wire payload (transformed ciphertext + AEAD tag) in bytes.
Header_Checksum (16 bits):
CRC-16 over all header fields except this field itself.

6.2. Media Segment Packet Extension

For MEDIA_SEGMENT (0x10) packets, an additional media header precedes the segment data 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, 32 bytes)                         |
|                                                             |
|                                                             |
|                                                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               Segment_Data (variable)                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 6: SGCP Media Segment Inner Header

Media_Type: 0x01 = AUDIO. Codec: 0x01 = MP3, 0x02 = AAC, 0x03 = OPUS, 0xFF = RAW. File_Hash is SHA-256 over the complete unencrypted file, enabling end-to-end integrity verification after reassembly.

7. State Graph Model

7.1. Graph Nodes

   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       : <C->S | S->C>,
       State_Status    : ACTIVE | SUSPENDED | TERMINATED,
       Chain_Hash      : H("SGCP_CHAIN" || Prev_Chain_Hash
                           || Node_ID || Sequence || Epoch)
   }

Secret keys MUST NOT be stored inside the node record; they are derived on demand from the key hierarchy.

7.2. Graph Edges

   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))
   }

7.3. Deterministic State Derivation

The graph is reproducible from authenticated state; it does not need to be transmitted as a secret object.

   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)

8. Key Hierarchy

8.1. Root Secret

The Root Secret is the sole ancestor of all cryptographic keys. It MUST be protected in memory and erased when the session terminates.

8.2. Epoch Key

   Epoch_Key =
       HKDF-Expand(Root_Secret,
                   "SGCP_EPOCH" || uint32(Epoch)
                   || Context_Binding,
                   key_length)

Old Epoch Keys SHOULD be erased after epoch transition to maintain forward secrecy within the session.

8.3. Packet Key

   Packet_Key =
       HKDF-Expand(Epoch_Key,
                   "SGCP_PACKET" || Direction || uint64(Sequence),
                   key_length)

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"

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.

The transformation MUST satisfy:

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 a unique epoch number, a distinct Epoch Key, an independent sequence-number space starting from 0, and an independent replay window.

   SESSION S1

   Epoch 0:  N0 -> N1 -> N2 -> N3
                              |
                              | Context Change
                              v
   Epoch 1:  N0' -> N1' -> N2' -> N3'
                              |
                              | Key Rotation
                              v
   Epoch 2:  N0'' -> N1'' -> N2''
Figure 7: Multi-Epoch Session Structure

10.1. Context Change

When a context-change event is detected:

  • ACCEPT: Context changed within policy bounds. Continue current epoch and update Context_Binding.
  • REAUTH: Context changed beyond policy bounds. Initiate reauthentication, derive new Epoch Key, reset sequence space.
  • REVOKE: Context indicates potential compromise. Immediately terminate the session.

10.2. Key Rotation

Proactive key rotation SHOULD occur after a configurable number of packets (e.g., every 2^32 packets) within one epoch, after a configurable time interval, or upon receipt of a KEY_ROTATION packet from the peer.

11. State Transition Engine

11.1. Transition Events

   PACKET_ACCEPTED    KEY_ROTATION    CONTEXT_CHANGED
   REAUTHENTICATED    SESSION_RECOVERY  TIMEOUT
   POLICY_CHANGE      REVOCATION

11.2. Transition Examples

   Normal:
     N100 -- PACKET_ACCEPTED --> N101

   Key Rotation:
     N101 -- KEY_ROTATION --> N0(Epoch+1)

   Context Change + Reauth:
     N200 -- CONTEXT_CHANGED --> T0
     T0   -- REAUTHENTICATED --> N0(Epoch+1)

   Revocation:
     N300 -- REVOCATION --> TERMINATED

12. Session Recovery

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.

   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 ---------|
     |                                    |
     |  Recovery_Secret derived           |
     |  New Epoch(N), Sequence = 0        |
Figure 8: Session Recovery Message Flow

13. Sender-Receiver Synchronization

Both endpoints derive the same state without transmitting any secret. 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)

When the receiver detects irrecoverable state divergence, it MUST initiate session recovery or terminate the session.

14. Full-Duplex MP3 Media Transfer Example

14.1. Scenario Description

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)

The Client-to-Server direction transfers the MP3 file in segments. The Server-to-Client direction sends per-segment acknowledgements and real-time processing status. Both channels are active simultaneously (full-duplex operation).

14.2. MP3 File Parameters

   File:            podcast_episode_42.mp3
   Size:            7,340,032 bytes  (7 MB exactly)
   SHA-256 Hash:    A3F182B0C44179D35E6F2A9104BC8D7E
                    F2034A5687CD19E023B456A789F01C2D
                    4E7890ABCD1234EF567890BC12DE9C7D
   Bit Rate:        128 kbps
   Duration:        ~7 min 41 sec
   Sample Rate:     44100 Hz
   Channels:        Stereo (2)
   MPEG Version:    MPEG-1 Layer III
   ID3 Tag Length:  10,240 bytes (prepended)

   Segment Size:    8,192 bytes
   Total Segments:  896   (= 7,340,032 / 8,192)

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).

14.3.1. Message 1: CLIENT_HELLO (T+0.000s)

   Header:
     Version       = 0x01
     Packet_Type   = 0x01  (CLIENT_HELLO)
     Flags         = 0x01  (FULL_DUPLEX)
     Session_ID    = 0x00..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>
     Client_Nonce       = 0x8A3F...1B2C  (32 bytes)
     Client_DH_Pub      = 0x5C2D...7F4A  (32 bytes, X25519)
     Client_KEM_Pub     = 0x3A1B...E9D2  (1184 bytes, ML-KEM-768)

14.3.2. Message 2: SERVER_HELLO (T+0.018s)

   Payload (cleartext TLV):
     SelectedSuite      = SGCP_X25519_MLKEM768_AESGCM256_SHA256
     Server_Certificate = <DER-encoded X.509>
     Server_Nonce       = 0x2F7C...4E8D  (32 bytes)
     Server_DH_Pub      = 0xA1B2...CD3E  (32 bytes, X25519)
     Server_KEM_CT      = 0xB2C3...EF40  (1088 bytes, ML-KEM-768 CT)
     Server_Challenge   = 0xD4E5...1F60  (32 bytes)
     Signature          = 0x3045...8A21  (ECDSA-P256)

   Client computes:
     DH_Secret  = X25519(Client_DH_Priv, Server_DH_Pub)
                = 0x9F2A...7C3B

     KEM_Secret = ML-KEM-768.Decapsulate(Client_KEM_Priv,
                                          Server_KEM_CT)
                = 0xE1D2...4C5B

     Root_Secret = HKDF-Extract("SGCP_ROOT_PQ_v1",
                     DH_Secret || KEM_Secret
                     || Client_Nonce || Server_Nonce
                     || H(Client_Cert) || H(Server_Cert))
                 = 0x7B4A...F9CE

14.3.3. Message 3: CLIENT_FINISH (T+0.020s)

   Session_ID =
       H("SGCP_SID" || Root_Secret || Client_Nonce || Server_Nonce)
       = 0xC3D4...A5B6  (16 bytes)

   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

   Context_Binding =
       H("SGCP_CTX_BIND_v1"
         || 0x0001                   (Version)
         || "DEV-AUDIO-CLIENT-42"
         || 0x06                     (TCP)
         || 0xC822                   (Port 51234)
         || 0x20FB                   (Port 8443)
         || Socket_ID
         || Session_ID)
       = 0xF1A2...B3C4

   Epoch_0_Key =
       HKDF-Expand(Root_Secret,
           "SGCP_EPOCH" || 0x00000000 || Context_Binding,
           32)
       = 0x4D5E...6F70

   Handshake complete at T+0.022s.
   Both sides: Epoch = 0, Sequence = 0, State = ACTIVE.

14.4. MP3 Segment Transfer - Client to Server

14.4.1. Segment 0 (Sequence 0, C->S, T+0.025s)

   Plaintext media header + data:
     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]

   Packet_Key_0 =
       HKDF-Expand(Epoch_0_Key,
           "SGCP_PACKET" || 0x01 || 0x0000000000000000,
           32)
       = 0x1A2B...3C4D

   Nonce_0 = Epoch(0) || Seq(0) || Dir(0x01)

   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)  // 8192 + 16 (AEAD tag)

   Wire_Payload_0 =
       XOR(Ciphertext_0 || Tag_0, Transform_State_0)

   Wire Header (illustrative hex):
     01 10 01 00           ; Ver=1 Type=MEDIA_SEGMENT Flags=FD
     C3D4A5B6C7D8E9F0      ; Session_ID [0..7]
     A1B2C3D4E5F6A7B8      ; Session_ID [8..15]
     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]

   State after Seg 0:  Sequence_C2S = 1

14.4.2. Segments 1-3 (Sequences 1-3)

   Seg 1 (T+0.030s):  Byte_Offset = 8192   Packet_Key differs
   Seg 2 (T+0.035s):  Byte_Offset = 16384  Packet_Key differs
   Seg 3 (T+0.040s):  Byte_Offset = 24576  Packet_Key differs

   State Graph (C->S) after 4 segments:
   N0 --[Pkt0]--> N1 --[Pkt1]--> N2 --[Pkt2]--> N3 --[Pkt3]--> N4

14.5. Full-Duplex Operation - Simultaneous Exchange

   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
   T+0.035  MEDIA_SEGMENT Seq=2 (8KB)
   T+0.038                              MEDIA_ACK Seq=1
   T+0.040  MEDIA_SEGMENT Seq=3 (8KB)
   T+0.043                              MEDIA_ACK Seq=2
   T+0.045  MEDIA_SEGMENT Seq=4 (8KB)
   T+0.048                              MEDIA_ACK Seq=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
   T+0.885                              STATUS (complete, PASS)
Figure 9: Full-Duplex Timeline (T+0.025s to T+0.060s)

The S->C Packet Key is derived independently from the C->S key:

   Packet_Key_S2C_0 =
       HKDF-Expand(Epoch_0_Key,
           "SGCP_PACKET" || 0x02 || 0x0000000000000000,
           32)
       = 0x7E8F...9A0B  (entirely different from any C->S key)

14.6. Epoch Transition During Transfer

After 512 segments (Sequence = 512 on C->S), the client initiates proactive key rotation at T+0.453s.

   KEY_ROTATION packet (C->S, Seq=512, Epoch=0):
     Packet_Type = 0x06  (KEY_ROTATION)
     Flags       = 0x09  (FULL_DUPLEX | KEY_ROTATION_PENDING)
     Payload (encrypted):
       New_Epoch = 1
       Reason    = PROACTIVE_ROTATION
       MAC       = HMAC-SHA256(Epoch_0_Key,
                               "SGCP_KEYROT" || Session_ID || 1)

   Server verifies, sends KEY_ROTATION_ACK (S->C, Seq=256, Epoch=0).

   Both sides derive Epoch 1:
     Epoch_1_Key =
         HKDF-Expand(Root_Secret,
             "SGCP_EPOCH" || 0x00000001 || Context_Binding,
             32)
         = 0x5F6A...7B8C

   Epoch_0_Key erased from memory.
   C->S: Sequence reset to 0, Epoch = 1
   S->C: Sequence reset to 0, Epoch = 1

   State Graph at boundary:

   Epoch 0 (C->S): N0 -> N1 -> ... -> N512
                                         |
                                         | KEY_ROTATION (E512)
                                         v
   Epoch 1 (C->S): N0' -> N1' -> ...  (Seg 512 onwards)

   First packet in Epoch 1 (T+0.457s):
     Epoch  = 0x00000001
     Seq    = 0x0000000000000000
     Flags  = 0x03  (FULL_DUPLEX | EPOCH_BOUNDARY)
     Packet_Key_E1_C2S_0 =
         HKDF-Expand(Epoch_1_Key,
             "SGCP_PACKET" || 0x01 || 0x0000000000000000,
             32)
         = 0x2C3D...4E5F

14.7. Transfer Completion and Session Summary

Server reassembles all 896 segments and verifies integrity:

   Received_File_Hash = SHA-256(reassembled 7,340,032 bytes)
   Verify: Received_File_Hash == A3F1...9C7D   -> PASS

   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
     Integrity:     PASS (end-to-end SHA-256 match)
     Key uniqueness: Every packet used a unique derived key.

15. Complete State Model

   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
       Port_State,         // port binding
       Socket_State,       // socket binding
       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 are NOT stored in the state record; they are derived from the Root Secret on demand from a separate protected memory region.

16. Security Considerations

16.1. Attack Surface Analysis

Table 2: SGCP Security Properties vs. Threats
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 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

Implementations MUST NOT attempt to brute-force candidate transform states or packet keys. When the receiver detects irrecoverable state divergence, it MUST initiate session recovery or terminate the session.

16.4. Deterministic State Security Rule

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.

17. IANA Considerations

This document requests the following IANA registrations. Values not listed in a registry are unassigned; new values MUST be registered via the Specification Required policy [RFC8126].

17.1. SGCP Cipher Suites Registry

Table 3: 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

17.2. SGCP Packet Types Registry

Table 4: 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

17.3. SGCP Alert Codes Registry

Table 5: 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

18. References

18.1. Normative References

[FIPS197]
National Institute of Standards and Technology, "Advanced Encryption Standard (AES)", NIST FIPS 197, DOI 10.6028/NIST.FIPS.197, , <https://doi.org/10.6028/NIST.FIPS.197>.
[FIPS203]
National Institute of Standards and Technology, "Module-Lattice-Based Key-Encapsulation Mechanism Standard", NIST FIPS 203, DOI 10.6028/NIST.FIPS.203, , <https://doi.org/10.6028/NIST.FIPS.203>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC5280]
Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, DOI 10.17487/RFC5280, , <https://www.rfc-editor.org/rfc/rfc5280>.
[RFC5869]
Krawczyk, H. and P. Eronen, "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)", RFC 5869, DOI 10.17487/RFC5869, , <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, , <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, , <https://www.rfc-editor.org/rfc/rfc8032>.
[RFC8126]
Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, , <https://www.rfc-editor.org/rfc/rfc8126>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.
[RFC8446]
Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, , <https://www.rfc-editor.org/rfc/rfc8446>.

18.2. Informative References

[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, , <https://www.rfc-editor.org/rfc/rfc5905>.
[RFC9147]
Rescorla, E., Tschofenig, H., and N. Modadugu, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", RFC 9147, DOI 10.17487/RFC9147, , <https://www.rfc-editor.org/rfc/rfc9147>.

Appendix A. Graph Interaction Diagrams

A.1. Normal Full-Duplex Operation

   CLIENT (C->S)                        SERVER
   ====================================  ============================
   Epoch=0, Seq=0, Node=N0_C2S           Epoch=0, Seq=0, Node=N0_C2S
   |                                     |
   |--- MEDIA_SEGMENT(Seq=0) ----------->|
   |                                     | verify -> N1_C2S
   |                                     |--- MEDIA_ACK(S2C,Seq=0) ->|
   |--- MEDIA_SEGMENT(Seq=1) ----------->|
   |  -> N2_C2S                          | verify -> N2_C2S
   ...

A.2. Epoch Boundary

   Epoch=0, Seq=512, Node=N512_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.

Appendix C. 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, including:

The implementation provides two high-level endpoint classes: SGCPClient and SGCPServer, both exposing a unified receive() method that automatically dispatches on packet type (DATA 0x04 vs MEDIA_SEGMENT 0x10), returning an SGCPMessage envelope containing 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/

Author's Address

Sripad Karthik
Independent Submission