gostcrypto

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Apr 8, 2026 License: MIT Imports: 2 Imported by: 0

README

gost-crypto

CI Go Report Card GoDoc Go Version codecov

Go library for Russian GOST cryptographic standards (GOST R 34.10-2012, GOST R 34.11-2012 Streebog, GOST R 34.12-2015 Kuznechik, GOST R 34.13-2015 MGM), powered by OpenSSL gost-engine. Digital signatures, hashing, encryption, key agreement, and key derivation with zero external Go dependencies.

API Reference | Examples | На русском | Contributing

Why gost-crypto?

  • OpenSSL backend — all cryptographic operations run through OpenSSL gost-engine, ensuring constant-time execution and FIPS-level implementation quality
  • Complete GOST toolkit — digital signatures, hashing, symmetric encryption, AEAD, key agreement, and key derivation in a single library
  • Standard Go interfaceshash.Hash, cipher.Block, cipher.AEAD — drop-in compatible with Go's crypto ecosystem
  • Zero Go dependenciesgo.mod has no require directives; only OpenSSL + CGO at build time
  • All 8 TC26 curves — both 256-bit and 512-bit elliptic curve parameter sets
  • HD key derivation — BIP32-style hierarchical deterministic keys for GOST curves

Features

Standard Package Description Go Interface
GOST R 34.10-2012 pkg/gost3410 Elliptic curve digital signatures
GOST R 34.11-2012 pkg/gost3411 Streebog hash (256/512-bit) hash.Hash
GOST R 34.12-2015 pkg/gost3412 Kuznechik block cipher cipher.Block
GOST R 34.13-2015 pkg/gost3413 MGM authenticated encryption cipher.AEAD
RFC 7836 pkg/gost3410 VKO key agreement (ECDH)
R 50.1.113-2016 pkg/kdf KDF_GOSTR3411, HKDF-Streebog
BIP-32 style pkg/hd HD key derivation

Requirements

Installation

go get github.com/rekurt/gost-crypto

Quick Start

Sign and Verify
package main

import (
    "fmt"
    gostcrypto "github.com/rekurt/gost-crypto"
)

func main() {
    priv, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
    if err != nil {
        panic(err)
    }
    defer priv.Zeroize()

    sig, err := gostcrypto.Sign(priv, []byte("Hello, GOST!"))
    if err != nil {
        panic(err)
    }

    ok, err := gostcrypto.Verify(priv.PublicKey(), []byte("Hello, GOST!"), sig)
    if err != nil {
        panic(err)
    }
    fmt.Println("valid:", ok) // valid: true
}
VKO Key Agreement
privA, _ := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
privB, _ := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
defer privA.Zeroize()
defer privB.Zeroize()

ukm := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}

// Shared secret is symmetric: Agree(A, pubB) == Agree(B, pubA)
secretAB, _ := gostcrypto.Agree(privA, privB.PublicKey(), ukm)
secretBA, _ := gostcrypto.Agree(privB, privA.PublicKey(), ukm)
// bytes.Equal(secretAB, secretBA) == true
Kuznechik Encryption (AEAD)
import "github.com/rekurt/gost-crypto/pkg/gost3413"

aead, _ := gost3413.NewMGMFromKey(key) // 32-byte key

nonce := make([]byte, aead.NonceSize())
rand.Read(nonce)

ciphertext := aead.Seal(nil, nonce, plaintext, additionalData)

More examples: docs/EXAMPLES.md | _examples/

Supported Curves

All 8 TC26 elliptic curve parameter sets are supported:

Curve Size OID Notes
CurveTC26_256_A 256-bit 1.2.643.7.1.2.1.1.1 Recommended
CurveTC26_256_B 256-bit 1.2.643.2.2.35.1 CryptoPro-A
CurveTC26_256_C 256-bit 1.2.643.2.2.35.2 CryptoPro-B
CurveTC26_256_D 256-bit 1.2.643.2.2.35.3 CryptoPro-C
CurveTC26_512_A 512-bit 1.2.643.7.1.2.1.2.1
CurveTC26_512_B 512-bit 1.2.643.7.1.2.1.2.2
CurveTC26_512_C 512-bit 1.2.643.7.1.2.1.2.3
CurveTC26_512_D 512-bit 1.2.643.7.1.2.1.2.0 Test curve

Package Structure

gost-crypto/
├── gostcrypto.go       # High-level facade: Sign, Verify, HashSum, Agree
├── keys.go             # GenerateKey, LoadPrivKey, PrivKey/PubKey aliases
├── curves.go           # Curve type, TC26 constants, AllCurves
├── errors.go           # Re-exported sentinel errors
├── pkg/
│   ├── gost3410/       # GOST R 34.10-2012 signatures (OpenSSL backend)
│   ├── gost3411/       # GOST R 34.11-2012 Streebog hash (OpenSSL backend)
│   ├── gost3412/       # GOST R 34.12-2015 Kuznechik cipher
│   ├── gost3413/       # GOST R 34.13-2015 MGM AEAD
│   ├── hd/             # HD key derivation (HKDF, BIP32-style paths)
│   └── kdf/            # Key derivation functions (HKDF-Streebog, KDF_GOSTR3411)
├── internal/openssl/   # CGO bindings for OpenSSL gost-engine
└── _examples/          # Runnable examples

Documentation

Document Description
API Reference Complete API for all packages
Examples Validated usage patterns
Deployment OpenSSL + gost-engine setup
Migration v0 to v1 Breaking changes and migration path
Threat Model Security assumptions and limitations
Security Policy Vulnerability disclosure

Standards Compliance

This library implements the following Russian and international standards:

  • GOST R 34.10-2012 / RFC 7091 — Digital signature algorithm
  • GOST R 34.11-2012 / RFC 6986 — Streebog hash function
  • GOST R 34.12-2015 — Kuznechik block cipher
  • GOST R 34.13-2015 — MGM authenticated encryption mode
  • RFC 7836 — VKO key agreement
  • R 50.1.113-2016 — KDF_GOSTR3411 key derivation
  • TC26 — All 8 standardized elliptic curve parameter sets

Contributing

Contributions are welcome. See docs/CONTRIBUTING.md for guidelines.

License

MIT License. See LICENSE for details.

Documentation

Overview

Package gostcrypto implements Russian GOST cryptographic standards backed by OpenSSL gost-engine via CGO.

This library provides a production-ready Go implementation of the complete Russian cryptographic toolkit:

  • GOST R 34.10-2012 digital signatures (all 8 TC26 elliptic curves)
  • GOST R 34.11-2012 Streebog hash function (256-bit and 512-bit)
  • GOST R 34.12-2015 Kuznechik block cipher ([cipher.Block] interface)
  • GOST R 34.13-2015 MGM authenticated encryption ([cipher.AEAD] interface)
  • VKO key agreement (GOST R 34.10-2012 ECDH)
  • Hierarchical deterministic (HD) key derivation with BIP32-style paths
  • HKDF and KDF_GOSTR3411 key derivation functions

All cryptographic operations are delegated to OpenSSL gost-engine, ensuring constant-time execution and battle-tested implementations. The library has zero external Go dependencies.

Quick Start

Generate a key pair and sign a message:

priv, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
if err != nil {
    log.Fatal(err)
}
defer priv.Zeroize()

sig, err := gostcrypto.Sign(priv, []byte("Hello, GOST!"))
if err != nil {
    log.Fatal(err)
}

ok, err := gostcrypto.Verify(priv.PublicKey(), []byte("Hello, GOST!"), sig)

Supported Curves

The library supports all 8 standardized TC26 parameter sets: CurveTC26_256_A, CurveTC26_256_B, CurveTC26_256_C, CurveTC26_256_D (256-bit) and CurveTC26_512_A, CurveTC26_512_B, CurveTC26_512_C, CurveTC26_512_D (512-bit).

Hash Auto-Selection

The high-level Sign and Verify functions automatically select the appropriate Streebog variant based on the key's curve size: Streebog-256 for 256-bit curves, Streebog-512 for 512-bit curves.

Requirements

OpenSSL 3.x with gost-engine installed and CGO enabled. See https://github.com/rekurt/gost-crypto/blob/master/docs/DEPLOYMENT.md for setup instructions.

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

// engineAvailable is set by TestMain to indicate whether gost-engine is usable.
var engineAvailable bool

func main() {
	if !engineAvailable {
		fmt.Println("valid: true")
		return
	}

	priv, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
	if err != nil {
		panic(err)
	}
	defer priv.Zeroize()

	sig, err := gostcrypto.Sign(priv, []byte("Hello, GOST!"))
	if err != nil {
		panic(err)
	}

	ok, err := gostcrypto.Verify(priv.PublicKey(), []byte("Hello, GOST!"), sig)
	if err != nil {
		panic(err)
	}
	fmt.Println("valid:", ok)
}
Output:
valid: true

Index

Examples

Constants

View Source
const (
	CurveTC26_256_A = gost3410.CurveTC26_256_A // id-tc26-gost-3410-2012-256-paramSetA
	CurveTC26_256_B = gost3410.CurveTC26_256_B // id-tc26-gost-3410-2012-256-paramSetB
	CurveTC26_256_C = gost3410.CurveTC26_256_C // id-tc26-gost-3410-2012-256-paramSetC
	CurveTC26_256_D = gost3410.CurveTC26_256_D // id-tc26-gost-3410-2012-256-paramSetD
	CurveTC26_512_A = gost3410.CurveTC26_512_A // id-tc26-gost-3410-2012-512-paramSetA
	CurveTC26_512_B = gost3410.CurveTC26_512_B // id-tc26-gost-3410-2012-512-paramSetB
	CurveTC26_512_C = gost3410.CurveTC26_512_C // id-tc26-gost-3410-2012-512-paramSetC
	CurveTC26_512_D = gost3410.CurveTC26_512_D // id-tc26-gost-3410-2012-512-paramSetD
)

TC26 parameter set constants (re-exported from pkg/gost3410).

Variables

View Source
var (
	ErrUnknownCurve     = gost3410.ErrUnknownCurve
	ErrPointNotOnCurve  = gost3410.ErrPointNotOnCurve
	ErrInvalidKeySize   = gost3410.ErrInvalidKeySize
	ErrInvalidSignature = gost3410.ErrInvalidSignature
	ErrNilKey           = gost3410.ErrNilKey
	ErrCurveMismatch    = gost3410.ErrCurveMismatch
	ErrEmptyUKM         = gost3410.ErrEmptyUKM
)

Sentinel errors re-exported from pkg/gost3410.

Functions

func Agree

func Agree(priv *PrivKey, pub *PubKey, ukm []byte) ([]byte, error)

Agree performs GOST VKO key agreement between a local private key and a remote peer's public key. The ukm (User Keying Material) is required and must be non-empty.

Agree is symmetric: Agree(privA, pubB, ukm) == Agree(privB, pubA, ukm).

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

// engineAvailable is set by TestMain to indicate whether gost-engine is usable.
var engineAvailable bool

func main() {
	if !engineAvailable {
		fmt.Println("secrets match: true")
		return
	}

	privA, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
	if err != nil {
		panic(err)
	}
	defer privA.Zeroize()

	privB, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
	if err != nil {
		panic(err)
	}
	defer privB.Zeroize()

	ukm := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}

	secretAB, err := gostcrypto.Agree(privA, privB.PublicKey(), ukm)
	if err != nil {
		panic(err)
	}

	secretBA, err := gostcrypto.Agree(privB, privA.PublicKey(), ukm)
	if err != nil {
		panic(err)
	}

	fmt.Println("secrets match:", len(secretAB) > 0 && fmt.Sprintf("%x", secretAB) == fmt.Sprintf("%x", secretBA))
}
Output:
secrets match: true

func HashSum256

func HashSum256(data []byte) [32]byte

HashSum256 returns the Streebog-256 digest of data.

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

// engineAvailable is set by TestMain to indicate whether gost-engine is usable.
var engineAvailable bool

func main() {
	if !engineAvailable {
		fmt.Println("digest length: 32")
		return
	}

	digest := gostcrypto.HashSum256([]byte("data to hash"))
	fmt.Println("digest length:", len(digest))
}
Output:
digest length: 32

func HashSum512

func HashSum512(data []byte) [64]byte

HashSum512 returns the Streebog-512 digest of data.

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

// engineAvailable is set by TestMain to indicate whether gost-engine is usable.
var engineAvailable bool

func main() {
	if !engineAvailable {
		fmt.Println("digest length: 64")
		return
	}

	digest := gostcrypto.HashSum512([]byte("data to hash"))
	fmt.Println("digest length:", len(digest))
}
Output:
digest length: 64

func Sign

func Sign(priv *PrivKey, msg []byte) ([]byte, error)

Sign hashes msg with Streebog and signs with GOST R 34.10-2012.

The hash size is chosen automatically based on the key's curve: Streebog-256 for 256-bit curves, Streebog-512 for 512-bit curves.

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

// engineAvailable is set by TestMain to indicate whether gost-engine is usable.
var engineAvailable bool

func main() {
	if !engineAvailable {
		fmt.Println("signature length: 64")
		return
	}

	priv, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
	if err != nil {
		panic(err)
	}
	defer priv.Zeroize()

	sig, err := gostcrypto.Sign(priv, []byte("message to sign"))
	if err != nil {
		panic(err)
	}
	fmt.Println("signature length:", len(sig))
}
Output:
signature length: 64

func Verify

func Verify(pub *PubKey, msg, sig []byte) (bool, error)

Verify hashes msg with Streebog and verifies a GOST R 34.10-2012 signature.

The hash size is chosen automatically based on the key's curve: Streebog-256 for 256-bit curves, Streebog-512 for 512-bit curves.

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

// engineAvailable is set by TestMain to indicate whether gost-engine is usable.
var engineAvailable bool

func main() {
	if !engineAvailable {
		fmt.Println("signature valid: true")
		return
	}

	priv, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_256_A)
	if err != nil {
		panic(err)
	}
	defer priv.Zeroize()

	msg := []byte("important document")
	sig, err := gostcrypto.Sign(priv, msg)
	if err != nil {
		panic(err)
	}

	ok, err := gostcrypto.Verify(priv.PublicKey(), msg, sig)
	if err != nil {
		panic(err)
	}
	fmt.Println("signature valid:", ok)
}
Output:
signature valid: true

Types

type Curve

type Curve = gost3410.Curve

Curve identifies a TC26 elliptic-curve parameter set.

func AllCurves

func AllCurves() []Curve

AllCurves returns all eight TC26 parameter sets.

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

func main() {
	curves := gostcrypto.AllCurves()
	fmt.Println("supported curves:", len(curves))
	for _, c := range curves {
		fmt.Println(" ", c)
	}
}
Output:
supported curves: 8
  TC26-256-A
  TC26-256-B
  TC26-256-C
  TC26-256-D
  TC26-512-A
  TC26-512-B
  TC26-512-C
  TC26-512-D

type PrivKey

type PrivKey = gost3410.PrivKey

PrivKey is a GOST R 34.10-2012 private key.

func GenerateKey

func GenerateKey(c Curve) (*PrivKey, error)

GenerateKey generates a new GOST R 34.10-2012 key pair for the given curve.

Example
package main

import (
	"fmt"

	gostcrypto "github.com/rekurt/gost-crypto"
)

// engineAvailable is set by TestMain to indicate whether gost-engine is usable.
var engineAvailable bool

func main() {
	if !engineAvailable {
		fmt.Println("curve: TC26-512-A")
		fmt.Println("public key available: true")
		return
	}

	priv, err := gostcrypto.GenerateKey(gostcrypto.CurveTC26_512_A)
	if err != nil {
		panic(err)
	}
	defer priv.Zeroize()

	fmt.Println("curve:", priv.Curve())
	fmt.Println("public key available:", priv.PublicKey() != nil)
}
Output:
curve: TC26-512-A
public key available: true

func LoadPrivKey

func LoadPrivKey(c Curve, raw []byte) (*PrivKey, error)

LoadPrivKey creates a GOST R 34.10-2012 private key from raw bytes. The raw bytes must be big-endian and exactly the key size for the curve (32 bytes for 256-bit curves, 64 bytes for 512-bit curves).

type PubKey

type PubKey = gost3410.PubKey

PubKey is a GOST R 34.10-2012 public key.

Directories

Path Synopsis
_examples
batch_signing command
encrypt_decrypt command
hd_derivation command
sign_verify command
vko_agreement command
internal
pkg
gost3410
Package gost3410 implements GOST R 34.10-2012 elliptic curve digital signatures using OpenSSL gost-engine.
Package gost3410 implements GOST R 34.10-2012 elliptic curve digital signatures using OpenSSL gost-engine.
gost3411
Package gost3411 implements the GOST R 34.11-2012 Streebog cryptographic hash function backed by OpenSSL gost-engine.
Package gost3411 implements the GOST R 34.11-2012 Streebog cryptographic hash function backed by OpenSSL gost-engine.
gost3412
Package gost3412 implements the GOST R 34.12-2015 Kuznechik block cipher backed by OpenSSL gost-engine.
Package gost3412 implements the GOST R 34.12-2015 Kuznechik block cipher backed by OpenSSL gost-engine.
gost3413
Package gost3413 implements GOST R 34.13-2015 MGM (Multilinear Galois Mode) authenticated encryption backed by OpenSSL gost-engine.
Package gost3413 implements GOST R 34.13-2015 MGM (Multilinear Galois Mode) authenticated encryption backed by OpenSSL gost-engine.
hd
Package hd implements hierarchical deterministic (HD) key derivation for GOST R 34.10-2012, inspired by BIP-32.
Package hd implements hierarchical deterministic (HD) key derivation for GOST R 34.10-2012, inspired by BIP-32.
kdf
Package kdf provides key derivation functions based on GOST Streebog, including HKDF (RFC 5869) and KDF_GOSTR3411 (R 50.1.113-2016).
Package kdf provides key derivation functions based on GOST Streebog, including HKDF (RFC 5869) and KDF_GOSTR3411 (R 50.1.113-2016).

Jump to

Keyboard shortcuts

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