Pure-Go GOST cryptographic primitives — Streebog (GOST R 34.11-2012), Kuznyechik and Magma (GOST R 34.12-2015), GOST 28147-89, GOST R 34.10 sign/verify, VKO key agreement, MGM, OMAC, CTR-ACPKM, KDFTree, TLSTree, KEG, KExp15, CryptoPro key wrap, and GOST R 34.11-94 — plus GOST-signed X.509 parsing and verification.
Pure-Go, BSD-2-Clause, zero third-party dependencies (CGO_ENABLED=0).
Every primitive is a clean-room re-implementation; no GPL code is linked and
none appears in this module's go.mod/go.sum.
go get github.com/tarantool/go-gostcryptoimport "github.com/tarantool/go-gostcrypto"
// Hash with Streebog-256.
digest := gostcrypto.Streebog256([]byte("hello"))
// Encrypt and decrypt with Kuznyechik.
ciphertext, err := gostcrypto.KuznyechikEncrypt(key, plaintext)
if err != nil {
// handle error
}
plaintext, err = gostcrypto.KuznyechikDecrypt(key, ciphertext)The root package is a stable []byte-in/[]byte-out facade; for the idiomatic
cipher.Block / hash.Hash API import the primitive packages directly (see
below). Full API reference:
pkg.go.dev.
gostcrypto/ package gostcrypto — the public facade (clean-room)
*.go stable []byte-in/[]byte-out API, delegates to the primitives
streebog/ kuznyechik/ … BSD clean-room primitives, each importable directly;
each has a README.md (overview) and DESIGN.md (detail)
x509gost/… GOST-signed X.509 parse/verify
internal/ct/ shared branch-free masking primitives for the constant-time paths
- Facade (root
gostcryptopackage): a stable[]byte-in/[]byte-out API. Consumers that want a simple call surface import this. - Primitive packages (
streebog/,kuznyechik/, …): each primitive as its own package with an idiomaticcipher.Block/hash.HashAPI, importable directly. x509gost: GOST X.509.ParseCertificatereturns a*Certificatewrapping the stdlib cert plus GOST metadata; non-GOST DER passes through unchanged.
Each package name links to its README.md — a short overview with the public
API and a usage example — which in turn links to the package's DESIGN.md:
the full algorithm description, specification, implementation notes, and test
vectors.
The Spec(s) column links to the copy of each standard committed alongside the
code, under that package's rfc/ directory.
| Package | Primitive | Spec(s) |
|---|---|---|
gost28147 |
GOST 28147-89 block cipher core (ECB, key schedule, S-boxes) | RFC 5830, RFC 4357 |
magma |
Magma — GOST R 34.12-2015, 64-bit block | RFC 8891 |
kuznyechik |
Kuznyechik — GOST R 34.12-2015, 128-bit block | RFC 7801 |
gost28147cnt |
GOST 28147-89 CNT counter/gamma stream | RFC 5830, RFC 4357 |
gost28147imit |
GOST 28147-89 IMIT MAC + CryptoPro key meshing | RFC 5830, RFC 4357 |
ctracpkm |
CTR mode + ACPKM key meshing | RFC 8645; GOST R 34.13-2015 |
omac |
OMAC / CMAC (GOST R 34.13-2015 MAC) | RFC 4493; GOST R 34.13-2015 |
mgm |
MGM AEAD (Multilinear Galois Mode) | RFC 9058; R 1323565.1.026-2019 |
streebog |
Streebog hash — GOST R 34.11-2012, 256 & 512 | RFC 6986 |
gostr341194 |
GOST R 34.11-94 legacy hash (CryptoPro param set) | RFC 5831, RFC 4357 |
kdftree |
KDF_TREE_GOSTR3411_2012_256 | RFC 7836 |
tlstree |
TLSTree per-record key derivation | RFC 9189, RFC 7836 |
gost3410sign |
GOST R 34.10-2001/2012 signature (sign + verify) | RFC 7091, RFC 5832 |
gost3410curves |
GOST R 34.10 curve parameter sets (CryptoPro + TC26) | RFC 4357, RFC 7836 |
vko |
VKO key agreement (GOST 34.10-2001 & 2012) | RFC 4357, RFC 7836 |
keywrap |
CryptoPro KeyWrap + key diversification | RFC 4357 §6 |
keg |
KEG — key export generation (TLS GOST KEX) | RFC 9189; R 1323565.1.020-2018 |
kexp15 |
KExp15 / KImp15 key export wrapping | RFC 9189; R 1323565.1.017-2018 |
x509gost |
GOST-signed X.509 parse/verify | RFC 9215, RFC 4491 |
A byte-order trap that cuts across all of them: GOST serializes integers,
keys, public-key coordinates, and signatures little-endian on the wire
(public keys are LE(X) || LE(Y), signatures are s || r), while the
underlying math and the RFC constant tables are big-endian. When a test
vector fails, check byte order first — each package's DESIGN.md
implementation notes list the traps for that primitive.
The default primitives are table-driven and not constant-time — they leak
the key/plaintext through cache timing, matching the GOST software norm
(gogost, gost-engine) and the table-driven AES shipped everywhere. Two
experimental, leak-free paths exist alongside them, sharing the branch-free
masking vocabulary in internal/ct:
kuznyechik.NewCipherCT(key)— a constant-time Kuznyechik whoseEncrypt/Decryptand key schedule have no secret-dependent memory access (SWAR full-scan S-box + GF(2)-linearLcolumns, no fused 64 KiB tables). Byte-for-byte identical to the table cipher; ≈36× slower. Seekuznyechik/SECURITY.md.gost3410curves.(*Curve).ScalarMultCT(k, p)— a constant-time EC scalar multiply for secret scalars (signing nonce, private key), built on fixed-limb Montgomery field arithmetic and complete short-Weierstrass formulas. The variable-timebig.IntScalarMultremains the default; opt in perCurvevia theConstantTimeflag. Seegost3410curves/SECURITY.mdandgost3410curves/EXPERIMENT-ct.md.
Both are exercised by a verification harness in CI: ctgrind (valgrind/memcheck, instruction-level — fails if any branch/address depends on the poisoned secret) and dudect (statistical timing-leak sweep). Each runs a variable-time positive control that must be flagged, so a broken detector can't pass silently.
CGO_ENABLED=0 go build ./...
CGO_ENABLED=0 go test ./...
make lint # golangci-lint v2 (config in .golangci.yml)
make fuzz # drive every Fuzz target (FUZZTIME=1m by default)The KAT tests run oracle-free. CI (GitHub Actions) runs the test, lint, and
fuzz workflows (status shown by the badges above), plus parity / parity-fuzz
differentials and the ctgrind + dudect constant-time checks on every pull
request.
Contributions are welcome. See CONTRIBUTING.md for the development workflow, coding conventions, and the pre-push checklist. Notable changes are tracked in CHANGELOG.md.
BSD 2-Clause — see LICENSE.
<package>/README.md→<package>/DESIGN.md— per-package overview and the full algorithm description, specification, implementation notes, and test vectors (see the Packages table above).gost3410curves/SECURITY.md— constant-time status ofScalarMultand the experimentalScalarMultCT.gost3410curves/EXPERIMENT-ct.md— design and verification methodology for the constant-time EC scalar multiply (shared by both CT paths and the CI harness).kuznyechik/SECURITY.md— cache-timing of the table-driven S-L rounds and the experimental constant-timeNewCipherCTpath.
Known gogost/gost-engine vector divergences (S-box row order, GOST R 34.11-94
empty-input finalization, CryptoPro key meshing) are described in the relevant
package DESIGN.md files, next to the code they affect.