State Graph Cryptographic Protocol (SGCP)
draft-sgcp-state-graph-cryptographic-protocol-01
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| 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/