How Encryption Is Handled in OpenFlux Transports: AES-256-GCM Implementation Guide

OpenFlux implements end-to-end encryption via an EncryptedTransport wrapper that uses scrypt-based key derivation, HMAC-SHA-256 directional sub-keys, and AES-256-GCM authenticated encryption with per-packet nonces and LRU-based replay protection.

OpenFlux provides a modular tunneling system where any transport implementation can be transparently wrapped for cryptographic protection. According to the OpenFlux source code, the encryption logic resides in transport/encrypted.go and implements a complete AEAD (Authenticated Encryption with Associated Data) scheme that ensures confidentiality and integrity for all packets crossing the tunnel.

Scrypt-Based Key Derivation

The encryption foundation begins with a user-supplied shared secret of at least 16 bytes combined with a public context string. In transport/encrypted.go at lines 58-60, the implementation generates a SHA-256 hash of a fixed label plus the context to serve as the scrypt salt. The secret then undergoes key stretching via scrypt with parameters N=32768, r=8, p=1 to produce a 256-bit master key. This computationally expensive derivation protects against brute-force attacks on the shared secret while ensuring identical secrets with different contexts generate unique key material.

Directional Key Separation for Bidirectional Security

From the master key, OpenFlux derives two distinct directional sub-keys to isolate traffic flows. At lines 63-65 of transport/encrypted.go, the code uses HMAC-SHA-256 with the labels "client-to-exit" and "exit-to-client" respectively. This ensures that compromise of the client-to-exit key cannot decrypt exit-to-client traffic, enforcing strict cryptographic separation between transmission directions.

AES-256-GCM Implementation

Each derived directional key initializes an AES-256-GCM cipher instance. The newGCM function (lines 96-104) calls aes.NewCipher followed by cipher.NewGCM to obtain a cipher.AEAD interface. This provides both confidentiality and authenticity for all payload data, ensuring integrity verification fails if any ciphertext bit is modified in transit.

Packet Structure and Header Authentication

Every encrypted packet begins with a 5-byte header constructed in the Send method at line 9:

  • 3-byte magic: {'O','F','X'} identifies the packet as OpenFlux encrypted traffic
  • 1-byte version: 0x01 for the current protocol version
  • 1-byte direction: 0 for client→exit, 1 for exit→client

The header is included as additional authenticated data (AAD) in the AEAD.Seal operation (line 17), binding the direction and version metadata to the ciphertext. Tampering with any header byte causes authentication failure during decryption.

Nonce Management and Replay Protection

OpenFlux generates a fresh 12-byte nonce for every packet using crypto/rand (lines 10-12), placed immediately after the header. The AEAD.Seal operation encrypts the payload using this nonce with the header as AAD.

To prevent replay attacks, the implementation maintains a bounded LRU cache called seen in the rememberNonce function (lines 42-55). This map stores up to 4096 recent nonces; duplicate nonces trigger immediate packet rejection, while the LRU eviction policy prevents unbounded memory growth during long-running sessions.

Transparent Transport Integration

The EncryptedTransport struct implements the standard Transport interface defined in transport/transport.go, exposing identical Send and Receive methods to the underlying transport. The NewEncryptedTransport constructor (lines 46-88) requires four parameters: the base transport, shared secret, context string, and an exitNode boolean. When exitNode is true, the directional keys are swapped automatically, ensuring cryptographic alignment between tunnel endpoints without exposing key management complexity to calling code.

Practical Implementation Example

// --- Example: Setting up an encrypted tunnel between a client and an exit node ---
import (
    "github.com/p1neappleXpress/OpenFlux/main/transport"
    "github.com/p1neappleXpress/OpenFlux/main/tunnel"
)

// 1️⃣ Create the raw transport (e.g., TCP, UDP, raw socket, etc.)
raw, _ := tunnel.NewRawSocketTransport() // placeholder – any Transport implementation works

// 2️⃣ Wrap it with EncryptedTransport
secret  := "super‑secret‑shared‑passphrase"
context := "session‑2024‑09‑14"
exitNode := false // client side – set true on the exit side

enc, err := transport.NewEncryptedTransport(raw, secret, context, exitNode)
if err != nil {
    panic(err)
}

// 3️⃣ Send data (ciphertext only leaves the inner transport)
payload := []byte("Hello, encrypted world!")
if err := enc.Send(payload); err != nil {
    panic(err)
}

// 4️⃣ Receive data (decrypted automatically)
enc.Receive(func(plain []byte) {
    fmt.Printf("Received plaintext: %s\n", plain)
})

The same code runs on the exit node with exitNode = true, which swaps the send/receive keys automatically. Any transport implementing the Transport interface—such as those in transport/yandex/yandex.go or transport/oneme/max_transport.go—can be encrypted using this wrapper without modifying the underlying transport logic.

Summary

  • Scrypt key derivation uses N=32768, r=8, p=1 with SHA-256 salts to generate 256-bit master keys from shared secrets
  • Directional isolation via HMAC-SHA-256 ensures client-to-exit and exit-to-client traffic use distinct AES keys
  • AES-256-GCM provides authenticated encryption for all payload data with 12-byte random nonces
  • 5-byte authenticated header includes magic bytes, version, and direction byte protected as AAD
  • Replay protection via 4096-entry LRU cache (seen map) in rememberNonce rejects duplicate nonces
  • Interface compatibility allows EncryptedTransport to wrap any Transport implementation transparently using NewEncryptedTransport

Frequently Asked Questions

What encryption algorithm does OpenFlux use for transport security?

OpenFlux uses AES-256-GCM (Galois/Counter Mode) as implemented in the Go standard library's crypto/cipher package. The newGCM function in transport/encrypted.go creates the AEAD instance that provides both confidentiality and integrity verification for all tunnel packets.

How does OpenFlux prevent replay attacks in encrypted transports?

Replay protection is implemented in the rememberNonce function (lines 42-55) using a bounded LRU map that stores up to 4096 recent nonces. Upon receiving a packet, the nonce is extracted and checked against this cache; if the nonce already exists in the map, the packet is dropped immediately. The LRU eviction ensures memory usage remains constant during long sessions.

What is the purpose of the exitNode parameter in NewEncryptedTransport?

The exitNode boolean parameter controls directional key assignment. When set to false (client side), the transport uses the "client-to-exit" key for sending and "exit-to-client" for receiving. When set to true (exit node side), these assignments are swapped. This ensures both endpoints agree on which key encrypts which direction without manual key management.

Can EncryptedTransport wrap any transport implementation in OpenFlux?

Yes. EncryptedTransport implements the generic Transport interface defined in transport/transport.go, requiring only Send and Receive methods. This design allows the encryption wrapper to compose with any concrete transport—including TCP, UDP, Yandex-based, or MEV-aware implementations—without requiring changes to the underlying transport code or breaking interface contracts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →