ctr

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 28, 2026 License: MIT Imports: 7 Imported by: 0

README

ctr — Counter-mode keystream constructions for ITB

Security notice. ITB is an experimental symmetric cipher construction without prior peer review, independent cryptanalysis, or formal certification. The construction's security properties have not been verified by independent cryptographers or mathematicians.

PRF-grade hash functions are required. No warranty is provided.

No bespoke cryptography. ITB introduces no cryptographic primitive of its own — no custom S-box, permutation, or round function. It is a construction over existing primitives, much as PGP composes standard ciphers rather than defining one. Such constructions are not the object of algorithm-level cryptographic certification: national regimes (NIST CAVP/FIPS in the US, GOST/FSB in Russia, KCMVP in South Korea, OSCCA's SM-series in China, SOG-IS/EUCC and national lists in the EU, ASD's ISM in Australia) certify primitives and the modules built on them, not compositional schemes. Eligibility for regulated use is therefore inherited from the primitives ITB is configured with, not conferred by ITB itself.

See CONSTRUCTIONS.md for the per-primitive construction descriptions. The registry names (areion256, areion512, blake2b256, blake2b512, blake2s, blake3, aescmac, siphash24, chacha20) are short identifiers shared with the hashes/ registry; here they select a counter-mode keystream construction, not the per-pixel hash wrapper of the same name. Read CONSTRUCTIONS.md before assuming a particular standard's exact byte layout.

This package builds a counter-mode keystream from a registry primitive and is the single source of truth for cipher key and nonce sizes. It is consumed by the wrapper/ package (the format-deniability outer cipher) and by the planned parallax/ package; both rely on this package's KeySize / NonceSize declarations rather than hardcoding cipher dimensions of their own.

Each supported primitive maps to a standard counter-mode keystream. The package neither defines a new cipher nor claims security beyond what the underlying construction provides.

Public API

func New(name string, key, nonce []byte) (Keystream, error)
func KeySize(name string) (int, error)
func NonceSize(name string) (int, error)
  • New constructs a Keystream from the named cipher, the caller-provided key, and a per-stream nonce. The key length must equal KeySize(name) and the nonce length must equal NonceSize(name); a mismatch is an error. An unknown name is an error.
  • KeySize returns the byte length of the key for the named cipher, or an error for an unknown name.
  • NonceSize returns the nonce byte length for the named cipher, or an error for an unknown name.

The Keystream interface is the minimal counter-mode surface:

type Keystream interface {
    XORKeyStream(dst, src []byte)
}

XORKeyStream xors a keystream segment over src into dst, advancing the internal counter. The contract matches crypto/cipher.Stream; dst must be at least as long as src. The interface stays decoupled from crypto/cipher.Stream so the SipHash construction does not have to present itself as a stdlib type. As with any counter-mode stream, decryption is the same operation as encryption: XORing a fresh keystream built from the same (name, key, nonce) over the ciphertext recovers the plaintext.

Supported primitives

Registry name Construction Key size Nonce size Notes
areion256 registry Areion-SoEM-256 keyed PRF in counter mode 32 bytes 16 bytes PRF-counter construction; 32-byte keystream blocks, keystream-block collision bound 2^128. See CONSTRUCTIONS.md.
areion512 registry Areion-SoEM-512 keyed PRF in counter mode 64 bytes 16 bytes PRF-counter construction; 64-byte keystream blocks, keystream-block collision bound 2^256. See CONSTRUCTIONS.md.
blake2b256 native keyed BLAKE2b-256 PRF in counter mode 32 bytes 16 bytes PRF-counter construction; 32-byte keystream blocks, keystream-block collision bound 2^128. See CONSTRUCTIONS.md.
blake2b512 native keyed BLAKE2b-512 PRF in counter mode 32 bytes 16 bytes PRF-counter construction; 64-byte keystream blocks, keystream-block collision bound 2^256. See CONSTRUCTIONS.md.
blake2s native keyed BLAKE2s-256 PRF in counter mode 32 bytes 16 bytes PRF-counter construction; 32-byte keystream blocks, keystream-block collision bound 2^128. See CONSTRUCTIONS.md.
blake3 native keyed BLAKE3 PRF in counter mode 32 bytes 16 bytes PRF-counter construction; 32-byte keystream blocks, keystream-block collision bound 2^128. See CONSTRUCTIONS.md.
aescmac AES-128 in CTR mode (crypto/cipher.NewCTR over crypto/aes) 16 bytes 16 bytes Standard NIST CTR mode; AES-NI accelerated on supported hosts. The 16-byte nonce is the CTR initial counter block.
siphash24 SipHash-2-4 PRF in counter mode, 128-bit output 16 bytes 16 bytes PRF-counter construction; keystream-block collision bound is 2^64. See CONSTRUCTIONS.md.
chacha20 ChaCha20 (RFC8439) keystream (golang.org/x/crypto/chacha20) 32 bytes 12 bytes Standard RFC8439 ChaCha20 keystream.

All registry primitives are supported; every entry point (New, NewAt, KeySize, NonceSize) returns an error for any name outside of supported primitives above. NewAt(name, key, nonce, byteOffset) returns a keystream positioned at byteOffset of the New stream, so one logical stream can be XORed in parallel — each worker seeks to its chunk offset and emits a byte-identical disjoint range.

Usage

import (
    "crypto/rand"

    "github.com/everanium/itb/ctr"
)

func main() {
    name := "chacha20"

    keySize, _ := ctr.KeySize(name)     // 32
    nonceSize, _ := ctr.NonceSize(name) // 12

    key := make([]byte, keySize)
    nonce := make([]byte, nonceSize)
    if _, err := rand.Read(key); err != nil {
        panic(err)
    }
    if _, err := rand.Read(nonce); err != nil {
        panic(err)
    }

    plaintext := []byte("any text or binary data - including 0x00 bytes")

    // Encrypt: XOR the keystream over the plaintext.
    enc, err := ctr.New(name, key, nonce)
    if err != nil {
        panic(err)
    }
    ciphertext := make([]byte, len(plaintext))
    enc.XORKeyStream(ciphertext, plaintext)

    // Decrypt: a fresh keystream from the same (name, key, nonce) recovers
    // the plaintext — counter-mode decryption is the same XOR operation.
    dec, err := ctr.New(name, key, nonce)
    if err != nil {
        panic(err)
    }
    recovered := make([]byte, len(ciphertext))
    dec.XORKeyStream(recovered, ciphertext)

    _ = recovered // bit-exact recovery of plaintext.
}

Documentation

Overview

Package ctr provides counter-mode keystream constructions over PRF-grade ITB registry primitives. Supports primitives with native cipher mode and PRF-counter mode, where a keystream block is the primitive's keyed-PRF output over the nonce concatenated with the block counter.

The package is the single source of truth for cipher key and nonce sizes. Each keystream satisfies the Keystream interface, whose XORKeyStream method matches the crypto/cipher.Stream contract: the keystream segment is XORed over src into dst while the internal counter advances.

Index

Constants

View Source
const (
	CipherAES128CTR = "aescmac"
	CipherSipHash24 = "siphash24"
	CipherChaCha20  = "chacha20"
)

Cipher names for the native-mode primitives, matching the ITB registry identifiers. The remaining PRF-counter-mode names are defined alongside their construction.

View Source
const (
	CipherAreion256  = "areion256"
	CipherAreion512  = "areion512"
	CipherBLAKE2b256 = "blake2b256"
	CipherBLAKE2b512 = "blake2b512"
	CipherBLAKE2s    = "blake2s"
	CipherBLAKE3     = "blake3"
)

Cipher names for the six hash-based PRF-CTR keystreams. The names match the ITB registry identifiers for these primitives.

Variables

This section is empty.

Functions

func KeySize

func KeySize(name string) (int, error)

KeySize returns the byte length of the key for the named cipher.

func NonceSize

func NonceSize(name string) (int, error)

NonceSize returns the nonce length for the named cipher.

Types

type Keystream

type Keystream interface {
	XORKeyStream(dst, src []byte)
}

Keystream is the minimal interface a counter-mode cipher exposes. The contract matches crypto/cipher.Stream — XORKeyStream xors a keystream segment over src into dst, advancing the internal counter.

Every concrete implementation — the native AES-128-CTR and ChaCha20 and the PRF-counter-mode constructions — satisfies this signature. The interface stays decoupled from crypto/cipher.Stream so the PRF-counter constructions do not have to pretend to be a stdlib type.

func New

func New(name string, key, nonce []byte) (Keystream, error)

New constructs a Keystream from the named cipher, the caller-provided key, and a per-stream nonce. The key length must equal KeySize(name); the nonce length must equal NonceSize(name).

Names outside PRF-grade registry primitives yield an unknown-cipher error.

func NewAt

func NewAt(name string, key, nonce []byte, byteOffset int) (Keystream, error)

NewAt returns a keystream positioned so its first output byte is the byte at byteOffset of the (name, key, nonce) stream produced by New. It lets one logical stream be XORed in parallel: each worker seeks to its chunk's byte offset and emits only its slice. The seek is O(1) — a whole-block counter jump plus an intra-block remainder skip of fewer than one block's bytes — never an O(byteOffset) discard.

byteOffset must be >= 0; byteOffset == 0 is exactly New.

Jump to

Keyboard shortcuts

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