cryptolab

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package cryptolab is GopherTrunk's optional cryptographic-research toolkit: a set of byte-oriented analysis and brute-force tools for the kinds of obfuscation and weak/keyless ciphers found in RF traffic. It ships statistical triage (entropy/IC plus autocorrelation period detection), a NIST SP 800-22 randomness battery, an obfuscation-class classifier, keyspace brute force, LFSR/keystream analysis, keystream-reuse / many-time-pad recovery, CRC parameter recovery, analog voice descrambling, and a pluggable "subject" framework for studying specific byte-oriented obfuscators.

Optional at install

The toolkit is gated out of the default gophertrunk binary. The CLI wiring in cmd/gophertrunk is split into a //go:build cryptolab pair: the default build links a stub for the "cryptolab" subcommand that prints how to rebuild with the toolkit; a build with -tags cryptolab links the real dispatch. The generic engine and subject packages under this directory carry no build tag so they always compile and are exercised by the test suite, but they are only linked into the shipped binary when the operator opts in (see the Makefile's test-cryptolab target and `make build TAGS=cryptolab`).

Honesty

These are research tools for security testing. The toolkit actively attempts to break captured encryption — the assess harness runs every applicable method (keystream reuse, known-plaintext recovery, default/weak keys against the real ADP/DES/AES ciphers, keystream-LFSR prediction) and grades each one's effectiveness, because attempting decryption IS the security test. A complete decryption means the deployment FAILED the test; recovering nothing means it held.

Honesty about limits: the toolkit cannot conjure a strong key out of a strong cipher. AES/DES with a non-default key and correctly-rotated IVs has an infeasible keyspace, and the assess harness reports that plainly as RESISTANT rather than pretending otherwise. What it does break is the things that actually fail in the field: reused IVs, default/test keys, keyless obfuscation, and structurally weak keystreams.

Index

Constants

View Source
const SubcommandName = "cryptolab"

SubcommandName is the gophertrunk subcommand under which the toolkit is exposed (`gophertrunk cryptolab <verb>`). It is referenced from the always-linked CLI usage text so the command name is documented even in a default build that does not link the toolkit itself.

Variables

This section is empty.

Functions

func LookupMode

func LookupMode(toolName, modeName string) (Tool, Mode, error)

LookupMode resolves a tool and one of its modes. When the tool has a single mode, modeName may be empty to select it.

func Register

func Register(t Tool)

Register adds a tool to the global registry. It panics on a duplicate name, which can only happen from a programming error at init time.

func WriteResult

func WriteResult(w io.Writer, r *Result, f Format) error

WriteResult renders r to w in the requested format.

Types

type Env

type Env struct {
	// Logger receives structured progress. Never nil inside a mode (the CLI
	// substitutes a discard logger when logging is off).
	Logger *slog.Logger
	// OutDir is the directory for append-only *.jsonl survivor logs and
	// resumable checkpoints. Empty means "no artifacts, stdout only".
	OutDir string
	// ResumePath points at a prior checkpoint to continue from (cell solver
	// and any other resumable mode). Empty starts fresh.
	ResumePath string
	// Format selects how the returned Result is rendered to Stdout.
	Format Format
	// Stdout is where the rendered Result and human text go.
	Stdout io.Writer
}

Env carries the shared run context a Mode needs: where to log, where to write artifacts, the structured-output format, and the stream for human-facing text. It is built once by the CLI from the global flags and passed to whichever mode runs.

func (Env) Logf

func (e Env) Logf(msg string, args ...any)

Logf is a convenience that logs at info level when a logger is present.

type Field

type Field struct {
	Key   string `json:"key" yaml:"key"`
	Value any    `json:"value" yaml:"value"`
}

Field is one named structured fact.

type Finding

type Finding struct {
	Label  string         `json:"label" yaml:"label"`
	Score  float64        `json:"score" yaml:"score"`
	Detail map[string]any `json:"detail,omitempty" yaml:"detail,omitempty"`
}

Finding is one ranked candidate output.

type Format

type Format int

Format selects how a Result is serialized. Mirrors the siglab export surface (text summary plus structured json/jsonl/yaml/csv).

const (
	// FormatText is the human-readable summary (default).
	FormatText Format = iota
	// FormatJSON is a single pretty JSON object.
	FormatJSON
	// FormatJSONL is one JSON object per finding, then a summary object —
	// convenient for streaming/grep over large survivor sets.
	FormatJSONL
	// FormatYAML is a single YAML document.
	FormatYAML
	// FormatCSV is one row per finding (label,score,detail-json).
	FormatCSV
)

func ParseFormat

func ParseFormat(s string) (Format, error)

ParseFormat maps a CLI string to a Format.

type Mode

type Mode interface {
	Name() string
	Synopsis() string
	// Run parses mode-specific args and executes against env. It returns a
	// structured Result for uniform export; a nil Result is allowed for
	// modes whose only output is the live progress log.
	Run(ctx context.Context, args []string, env Env) (*Result, error)
}

Mode is one runnable operation within a Tool. It parses its own flag-style arguments so each mode owns its knobs, the same way the siglab subcommands do.

type ModeSchema

type ModeSchema struct {
	Tool     string  `json:"tool"`
	Mode     string  `json:"mode"`
	Synopsis string  `json:"synopsis"`
	Params   []Param `json:"params"`
}

ModeSchema is the web-facing description of one tool/mode and its inputs.

func Schema

func Schema() []ModeSchema

Schema returns the web-facing description of every registered tool/mode, sorted by tool then mode. It joins the live registry (so every registered mode appears with its synopsis) with the parameter table above.

type Param

type Param struct {
	Name     string   `json:"name"`
	Label    string   `json:"label"`
	Kind     string   `json:"kind"` // file | outfile | string | int | bool | select
	Required bool     `json:"required"`
	Default  string   `json:"default,omitempty"`
	Help     string   `json:"help,omitempty"`
	Options  []string `json:"options,omitempty"`
}

Param describes one input of a mode, enough for a web UI to render a form control and for the web server to translate the submitted value into a CLI flag. Name is the flag name (without the leading dash), so the same value reaches the mode's own flag parser unchanged.

type Result

type Result struct {
	Tool    string `json:"tool" yaml:"tool"`
	Mode    string `json:"mode" yaml:"mode"`
	Summary string `json:"summary" yaml:"summary"`

	// Fields holds the headline structured facts (counts, coverage,
	// recovered parameters). Ordered for stable rendering.
	Fields []Field `json:"fields,omitempty" yaml:"fields,omitempty"`

	// Findings are ranked candidate outputs (recovered keys, surviving
	// wirings, decoded messages). Highest score first.
	Findings []Finding `json:"findings,omitempty" yaml:"findings,omitempty"`

	// Notes are honest caveats: what is and is not established, and what
	// additional data would close the remaining gap.
	Notes []string `json:"notes,omitempty" yaml:"notes,omitempty"`
}

Result is the uniform structured output every mode returns, so the CLI can render any tool's output as text, JSON, JSONL, YAML, or CSV without knowing the tool's internals.

func (*Result) AddField

func (r *Result) AddField(key string, value any)

AddField appends a structured fact.

func (*Result) AddFinding

func (r *Result) AddFinding(label string, score float64, detail map[string]any)

AddFinding appends a ranked candidate.

func (*Result) Note

func (r *Result) Note(s string)

Note appends an honest caveat.

type Tool

type Tool interface {
	// Name is the verb used on the command line (`cryptolab <name>`).
	Name() string
	// Synopsis is a one-line description for help output.
	Synopsis() string
	// Modes are the runnable operations under this tool. A tool with a
	// single mode may be invoked without naming the mode.
	Modes() []Mode
}

Tool is one named research tool in the toolkit — e.g. "alias", "brute", "lfsr". A tool owns one or more Modes. Tools register themselves from an init() (mirroring the SDR and vocoder registries), so adding a tool is a new package plus a blank import in the CLI wiring.

func Lookup

func Lookup(name string) (Tool, bool)

Lookup returns the tool registered under name.

func Tools

func Tools() []Tool

Tools returns every registered tool sorted by name.

Directories

Path Synopsis
engine
assess
Package assess is a cryptographic security-test harness for captured RF ciphertext.
Package assess is a cryptographic security-test harness for captured RF ciphertext.
brute
Package brute is the toolkit's generic keyspace brute-force engine: pluggable Cipher, KeySpace, and Scorer interfaces driving an ordered, resumable sweep that keeps the top-scoring candidates.
Package brute is the toolkit's generic keyspace brute-force engine: pluggable Cipher, KeySpace, and Scorer interfaces driving an ordered, resumable sweep that keeps the top-scoring candidates.
cipherinfo
Package cipherinfo is a knowledge base of the link-layer encryption algorithms used across the trunking protocols GopherTrunk decodes (P25, TETRA, DMR) and their published cryptographic weaknesses.
Package cipherinfo is a knowledge base of the link-layer encryption algorithms used across the trunking protocols GopherTrunk decodes (P25, TETRA, DMR) and their published cryptographic weaknesses.
crc
Package crc provides parameterized CRC computation and recovery of CRC parameters from sample (data, crc) frames — the kind of task that comes up identifying the framing/FEC check on an unfamiliar RF protocol.
Package crc provides parameterized CRC computation and recovery of CRC parameters from sample (data, crc) frames — the kind of task that comes up identifying the framing/FEC check on an unfamiliar RF protocol.
dmrcrypto
Package dmrcrypto generates the keystreams DMR's link-layer privacy algorithms produce, so the assessment harness and recipe pipeline can attempt DMR decryption the same way p25crypto handles P25.
Package dmrcrypto generates the keystreams DMR's link-layer privacy algorithms produce, so the assessment harness and recipe pipeline can attempt DMR decryption the same way p25crypto handles P25.
extcipher
Package extcipher bridges to an external, operator-supplied cipher program so the toolkit can decrypt and brute-force ciphers it does not (and should not) bundle itself — most importantly TETRA TEA1, whose only public implementations are licence-incompatible (AGPL) with this Apache-2.0 project and which must not be re-authored unverified inside a security-test tool.
Package extcipher bridges to an external, operator-supplied cipher program so the toolkit can decrypt and brute-force ciphers it does not (and should not) bundle itself — most importantly TETRA TEA1, whose only public implementations are licence-incompatible (AGPL) with this Apache-2.0 project and which must not be re-authored unverified inside a security-test tool.
fit
Package fit holds closed-form byte-function fitters over Z/256: given observed (input → output) byte pairs, find the affine coefficients that best explain them and report how many observations conflict.
Package fit holds closed-form byte-function fitters over Z/256: given observed (input → output) byte pairs, find the affine coefficients that best explain them and report how many observations conflict.
gauge
Package gauge models the global affine gauge ambiguity that shows up when a byte-oriented obfuscator's state is recovered from output only: the recovered high byte and multiplier are pinned just up to an affine change of coordinates (Mg·x + Cg with Mg odd, hence invertible mod 256).
Package gauge models the global affine gauge ambiguity that shows up when a byte-oriented obfuscator's state is recovered from output only: the recovered high byte and multiplier are pinned just up to an affine change of coordinates (Mg·x + Cg with Mg odd, hence invertible mod 256).
keystream
Package keystream implements keystream-reuse / many-time-pad analysis — the real-world break against additive stream ciphers (P25 DES-OFB and ADP/RC4, TETRA AIE) when a transmitter reuses an initialisation vector.
Package keystream implements keystream-reuse / many-time-pad analysis — the real-world break against additive stream ciphers (P25 DES-OFB and ADP/RC4, TETRA AIE) when a transmitter reuses an initialisation vector.
lang
Package lang holds a small embedded English language model used to score candidate plaintexts during cipher solving (e.g.
Package lang holds a small embedded English language model used to score candidate plaintexts during cipher solving (e.g.
lfsr
Package lfsr provides stream-cipher / LFSR analysis primitives relevant to RF scramblers and keystream study: Berlekamp–Massey recovery of the shortest LFSR that produces an observed bit sequence, Fibonacci-LFSR generation, and known-plaintext keystream extraction.
Package lfsr provides stream-cipher / LFSR analysis primitives relevant to RF scramblers and keystream study: Berlekamp–Massey recovery of the shortest LFSR that produces an observed bit sequence, Fibonacci-LFSR generation, and known-plaintext keystream extraction.
p25crypto
Package p25crypto generates the keystreams P25's link-layer encryption algorithms produce from a key and a Message Indicator (IV).
Package p25crypto generates the keystreams P25's link-layer encryption algorithms produce from a key and a Message Indicator (IV).
propagate
Package propagate is the toolkit's fast constraint propagator for the "is the next state a table lookup of some combined index?" family of hypotheses.
Package propagate is the toolkit's fast constraint propagator for the "is the next state a table lookup of some combined index?" family of hypotheses.
randomness
Package randomness implements a battery of statistical randomness tests drawn from NIST SP 800-22 (the "STS" suite), specialised for the question an RF analyst actually asks of a captured payload or a recovered keystream: is this stream indistinguishable from random (strong keyed encryption — no weak structure to exploit), or does it carry exploitable structure (a keyless scrambler, a short LFSR, a biased generator)?
Package randomness implements a battery of statistical randomness tests drawn from NIST SP 800-22 (the "STS" suite), specialised for the question an RF analyst actually asks of a captured payload or a recovered keystream: is this stream indistinguishable from random (strong keyed encryption — no weak structure to exploit), or does it carry exploitable structure (a keyless scrambler, a short LFSR, a biased generator)?
recipe
Package recipe is a CyberChef-style operation pipeline for RF payloads.
Package recipe is a CyberChef-style operation pipeline for RF payloads.
stats
Package stats holds the cipher-agnostic statistical primitives the toolkit uses to triage a captured payload: is it plaintext, a weak classical cipher, an obfuscation, or strong encryption? Plus the repeating-key-XOR key-length estimators (Friedman/Hamming) and a crib-dragging helper for many-time-pad / keystream-reuse analysis.
Package stats holds the cipher-agnostic statistical primitives the toolkit uses to triage a captured payload: is it plaintext, a weak classical cipher, an obfuscation, or strong encryption? Plus the repeating-key-XOR key-length estimators (Friedman/Hamming) and a crib-dragging helper for many-time-pad / keystream-reuse analysis.
subst
Package subst solves monoalphabetic substitution ciphers by hill-climbing over the 26! key space, scored by an embedded English n-gram model.
Package subst solves monoalphabetic substitution ciphers by hill-climbing over the 26! key space, scored by an embedded English n-gram model.
voice
Package voice provides analog voice-privacy descramblers — the keyless / weak-key spectral schemes still found on RF voice channels.
Package voice provides analog voice-privacy descramblers — the keyless / weak-key spectral schemes still found on RF voice channels.
Package progress provides the shared progress-logging and resumable checkpoint helpers used by every cryptolab tool: throttled structured logging for high-volume search loops, an append-only JSONL survivor log, and an atomically-written JSON checkpoint so multi-hour runs survive a kill and resume where they left off.
Package progress provides the shared progress-logging and resumable checkpoint helpers used by every cryptolab tool: throttled structured logging for high-volume search loops, an append-only JSONL survivor log, and an atomically-written JSON checkpoint so multi-hour runs survive a kill and resume where they left off.
subjects
motorola
Package motorola implements a cryptolab subject for a length-seeded, keyless, byte-oriented alias obfuscator: the output substitution table and the per-character decode equation are established, while the per-character state update is not.
Package motorola implements a cryptolab subject for a length-seeded, keyless, byte-oriented alias obfuscator: the output substitution table and the per-character decode equation are established, while the per-character state update is not.
nxdn
Package nxdn is a cryptolab subject: it descrambles NXDN's optional 15-bit scrambler and brute-forces the scrambling key.
Package nxdn is a cryptolab subject: it descrambles NXDN's optional 15-bit scrambler and brute-forces the scrambling key.
Package tools registers the generic (cipher-agnostic) cryptolab tools — statistical triage, keyspace brute force, LFSR/keystream analysis, CRC parameter recovery, and analog voice descrambling — into the cryptolab registry.
Package tools registers the generic (cipher-agnostic) cryptolab tools — statistical triage, keyspace brute force, LFSR/keystream analysis, CRC parameter recovery, and analog voice descrambling — into the cryptolab registry.
Package webserver is the optional cryptolab web console backend: a self-contained HTTP server that stages uploaded files, runs a selected cryptolab tool/mode with form-supplied settings, streams progress, and returns the structured Result and any artifacts.
Package webserver is the optional cryptolab web console backend: a self-contained HTTP server that stages uploaded files, runs a selected cryptolab tool/mode with form-supplied settings, streams progress, and returns the structured Result and any artifacts.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL