Enigma Traffic Protocol
An authenticated printable-stream codec inspired by Enigma rotor machines
ETP/1 is a Go traffic-obfuscation layer for ordered, reliable net.Conn
streams. It applies an Enigma-inspired plugboard, three rotating wheels, and a
reflector to authenticated records, then maps the result to printable ASCII
with optional ignorable padding.
ETP/1 is experimental. The repository includes fixed-target TCP/UDP, no-auth SOCKS5, HTTP CONNECT, mux, and optional HTTP/TLS client/server modes.
ETP/1 derives a 256-symbol plugboard, three rotor permutations, turnover positions, ring settings, and a fixed-point-free reflector for each direction. Every frame derives fresh starting positions from its sequence number. Applying the same machine state twice recovers the original bytes.
The rotor machine is an obfuscation transform, not cryptographic protection.
Each transformed byte is represented by two characters selected from a 64-character printable alphabet. Random synonym bits give every nibble four possible wire representations. Characters from a separate padding alphabet may be inserted between any encoded symbols without negotiating their positions.
- AES-256-GCM encrypts and authenticates every record.
- HMAC-SHA-256 derives independent traffic, rotor, length-mask, and nonce values.
- Each direction owns an independent random salt, key, sequence, and state.
- Lengths are bounded and checked before body allocation.
- Authentication or structural failure permanently terminates that read side.
internal/tunnel now provides the experimental ETPH/1 layer: a PSK-protected
ephemeral X25519 handshake, timestamp validation, and a bounded nonce replay
cache. Its derived session key replaces the static PSK before ETP/1 application
records begin.
- Go 1.26 or later;
- ordered, reliable byte streams such as TCP;
- one concurrent reader and one concurrent writer;
- serialized concurrent writes;
- automatic splitting of large writes into bounded records;
- partial reads from already authenticated records;
- custom printable cover and padding alphabets;
standard,balanced,compact, andhigh-paddingtraffic profiles;- an authenticated X25519 tunnel upgrade;
- a fixed-target TCP client/server command with explicit target negotiation.
- a no-auth SOCKS5 local listener that uses the same target negotiation.
- an HTTP CONNECT local listener with delayed success responses.
- public-API interoperability tests independent of package internals.
- Raw codec has no forward secrecy: direct
pkg/enigma.NewConnuse relies only on its configured key; use ETPH/1 when the tunnel layer is appropriate. - Replay protection is process-local: ETPH/1 rejects cached client nonces, but the bounded cache is not persistent across server restarts.
- No traffic-shape secrecy: endpoints, timing, and total byte count remain observable.
- TCP only: unordered or lossy datagram transports are not supported.
- Limited proxy protocols: the command supports fixed TCP/UDP targets, no-auth SOCKS5, HTTP CONNECT, mux, UoT, and optional HTTP/TLS wrappers. TUN, fallback, and dynamic-target SOCKS UDP associations are not included.
- Encoding overhead: printable encoding uses two symbols per transformed byte before optional padding.
go build -o enigma ./cmd/enigma
enigma keygen > enigma.keyStart a server restricted to one target:
enigma server -listen :8443 -key-file enigma.key -allow-target example.com:80Start a local fixed-target forwarder:
enigma client -listen 127.0.0.1:1080 \
-server server.example.com:8443 -target example.com:80 \
-key-file enigma.keySee the command-line guide for flags and deployment notes. The architecture guide explains the repository paths and how they relate to the reference project. The experimental mux design documents the current logical-stream core and its integration boundary. The UoT design documents the bounded UDP-over-stream packet layer. The transport wrapper guide describes optional HTTP and TLS camouflage layers.
For a local no-auth SOCKS5 listener, omit -target and use -socks5:
enigma client -socks5 -listen 127.0.0.1:1080 \
-server server.example.com:8443 -key-file enigma.keyFor an HTTP CONNECT listener, omit -target and use -http-connect:
enigma client -http-connect -listen 127.0.0.1:1080 \
-server server.example.com:8443 -key-file enigma.keyBoth peers must use the same high-entropy pre-shared key and compatible cover
configuration. Key must contain at least 32 bytes generated by a cryptographic
random source, not a human password.
package main
import (
"bytes"
"fmt"
"io"
"net"
"Enigma/pkg/enigma"
)
func main() {
rawClient, rawServer := net.Pipe()
defer rawClient.Close()
defer rawServer.Close()
cfg := enigma.Config{
// Demonstration only. Generate and distribute a random production key.
Key: bytes.Repeat([]byte{0x42}, 32),
MinPadding: 4,
MaxPadding: 16,
MinCoverPadding: 2,
MaxCoverPadding: 8,
}
client, err := enigma.NewConn(rawClient, cfg)
if err != nil {
panic(err)
}
server, err := enigma.NewConn(rawServer, cfg)
if err != nil {
panic(err)
}
received := make(chan []byte, 1)
go func() {
message := make([]byte, len("hello ETP/1"))
if _, err := io.ReadFull(server, message); err != nil {
panic(err)
}
received <- message
}()
if _, err := client.Write([]byte("hello ETP/1")); err != nil {
panic(err)
}
fmt.Println(string(<-received))
}The first non-empty Write lazily generates and sends a 16-byte directional
session salt. The first Read consumes that salt. Reads and writes therefore
need to run concurrently on unbuffered transports such as net.Pipe.
- Go configuration guide
- Command-line client/server guide
- ETP/1 wire protocol
- ETPH/1 authenticated handshake
pkg/enigmaraw-stream API- Implementation plan and roadmap
- Changelog
Initialization: PSK + random directional salt -> session keys and rotor tables
Write: payload -> padding -> AES-GCM -> Enigma -> printable cover
Read: cover filter -> Enigma -> AES-GCM verify -> validated payload
Each direction is an independent half-stream:
direction := Cover(session_salt) || Cover(frame_0) || Cover(frame_1) || ...
frame_n := Enigma_n(masked_length || aead_ciphertext)
plaintext := version || payload_length || payload || random_padding
See the protocol specification for exact derivation labels, record fields, limits, and failure behavior.
go fmt ./...
go test ./...
go vet ./...Run the race detector when CGO is available:
go test -race ./...Run a fuzz target or the performance suite explicitly:
go test -run '^$' -fuzz '^FuzzConnReadFrame$' ./pkg/enigma
go test -run '^$' -bench . -benchmem ./pkg/enigmaTests cover configuration validation, rotor involution, per-sequence state, printable padding, fragmented reads, multi-record writes, full-duplex traffic, wrong keys, modified records, invalid cover bytes, truncated streams, and the machine-readable ETP/1 compatibility vector.
pkg/enigma/
config.go public configuration and validation
derive.go domain-separated derivation helpers
rotor.go plugboard, rotors, stepping, and reflector
cover.go printable encoding and padding filter
conn.go AES-GCM records and net.Conn wrapper
*_test.go unit, duplex, tamper, and example tests
internal/tunnel/ authenticated X25519 upgrade and replay cache
internal/app/ listeners, target dialing, and bidirectional forwarding
cmd/enigma/ keygen, server, and client-mode commands
ref/sudoku-main is used only to study transport layering and documentation
organization. It is not part of this Go module; ETP/1 does not copy or import
its GPL-licensed source code or wire format.
This experimental software is intended for education and research. Users are responsible for evaluating its security properties and complying with applicable laws and network policies.
This repository includes the GNU Lesser General Public License v3.