camellia

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2026 License: BSD-3-Clause Imports: 4 Imported by: 0

README

go-encryptions/camellia

go-encryptions/camellia

ci Go Reference

Pure-Go Camellia block cipher (RFC 3713) as a standard crypto/cipher.Block: 16-byte blocks, 16-, 24- or 32-byte keys. Table-driven, no cgo, no dependency outside the standard library.

Its first consumer is go-fde/veracrypt, which needs Camellia in XTS mode with 256-bit keys (via go-encryptions/xts) to open VeraCrypt volumes.

Install

go get github.com/go-encryptions/camellia

Usage

import "github.com/go-encryptions/camellia"

block, err := camellia.NewCipher(key) // 16, 24 or 32 bytes
if err != nil {
	// a camellia.KeySizeError for any other length
}
block.Encrypt(dst[:16], src[:16]) // dst and src may be the same slice
block.Decrypt(dst[:16], src[:16]) // a buffer under 16 bytes panics

The contract is that of cipher.Block: in-place operation is allowed and short buffers panic. camellia.BlockSize is 16.

Byte order

Camellia is big-endian by specification: the key and the block are read as big-endian 64-bit words (the 24-byte key's KR is the last 8 bytes followed by their complement, as in RFC 3713 section 2.2). The ciphertext is therefore the same on every architecture; CI checks it on big-endian s390x.

Verification

  • RFC 3713 Appendix A: the three example vectors (128-, 192- and 256-bit keys), encrypted and decrypted.
  • testdata/botan-camellia.vec: Botan's own src/tests/data/block/camellia.vec, 17 vectors (7 at 128 bits, 4 at 192, 6 at 256), encrypted and decrypted.
  • testdata/botan-diff.vec: a differential corpus of 750 random keys and blocks (250 per key size, plus all-zero and all-one keys) generated from the Botan 3.14.1 command line by internal/genbotan (go run ./internal/genbotan). Regenerating needs botan on the PATH.
  • FuzzRoundTrip cross-checks Encrypt and Decrypt round trips on every key length and the refusal of other lengths; CI runs it for 60 seconds, and its corpus is in testdata/fuzz.
  • CI: race detector and a 100 % statement-coverage gate on amd64 and arm64; the same tests under QEMU on big-endian s390x and on riscv64; govulncheck.

I did not obtain the NESSIE Camellia vector files or the NTT specification itself, so no NESSIE vector is claimed beyond what Botan's file contains.

Implementation

The structure follows RFC 3713: the key schedule of section 2.2 (KL, KR, KA, KB, the six Sigma constants, subkeys by rotation), the 18- or 24-round Feistel network with FL/FLINV every six rounds of section 2.3, and the F-function, FL and FLINV of section 2.4. SBOX1 is the table of the RFC; SBOX2, SBOX3, SBOX4 and the linear layer are folded at start-up into eight 256-entry uint64 tables, so one F-function is eight look-ups and seven XORs. Decryption runs the same network over the reversed subkeys, as section 2.3.3 describes. Botan's camellia.cpp was read for the overall structure; Linux's GPL camellia_generic.c was not used.

Bibliography opened for this work: RFC 3713 (sections 2.2 to 2.4 and Appendix A); Botan camellia.cpp and camellia.vec.

Performance

BenchmarkEncrypt and BenchmarkDecrypt loop the block over a 4 KiB buffer, the shape of one XTS sector, with a 256-bit key and no allocation. The reference is Botan 3.14.1 (botan speed --buf-size=4096 Camellia-256, wrapped as Go benchmarks by internal/botanbench so that abbench can interleave it). Apple M4 Max (arm64), one core (GOMAXPROCS=1), 6 interleaved rounds by abbench --max-load 8, compared with benchstat; every result file holds ^Benchmark lines.

4 KiB, per call this package Botan, ARMv8 AES (default) Botan, scalar (--clear-cpuid=armv8aes)
Encrypt 23.96 µs ± 4 % (163 MiB/s) 26.82 µs ± 2 % (146 MiB/s), this package 1.12x faster 25.49 µs ± 4 %, this package 1.06x faster
Decrypt 24.03 µs ± 10 % (163 MiB/s) 26.95 µs ± 17 % (145 MiB/s), this package 1.12x faster 25.34 µs ± 5 %, this package 1.06x faster

Times are per 4 KiB call, so lower is better. The package is at or ahead of the reference in every column, with 0 allocations; the spreads of the Botan columns overlap the gaps in the last two cells, so read the scalar column as "level", not as a precise ratio. The two Botan columns were measured in separate abbench runs (1 round discarded for load in the first). internal/botanbench reports Botan's rate as ns/op, and benchstat does not join benchmarks of two different packages, so the ratios above are computed from the two result files' medians.

Reproduce: go test -c -o camellia.test ., go test -c -o botan.test ./internal/botanbench, then abbench --base ./camellia.test --head ./botan.test --max-load 8 -n 6 -- -test.bench . -test.run '^$' (add --head-arg=-botan.clear-cpuid=armv8aes for the scalar column).

License

BSD-3-Clause © the go-encryptions/camellia authors.

Documentation

Overview

Package camellia implements the Camellia block cipher (Aoki, Ichikawa, Kanda, Matsui, Moriai, Nakajima and Tokita; RFC 3713) as a crypto/cipher.Block.

Camellia is big-endian by specification: the 16-byte block and the key are read as big-endian 64-bit words, so the ciphertext is the same on every architecture.

The implementation is plain Go: the F-function is eight 64-bit table look-ups, the tables being derived at start-up from SBOX1 of RFC 3713.

Index

Constants

View Source
const BlockSize = 16

BlockSize is the Camellia block size in bytes.

Variables

This section is empty.

Functions

func NewCipher

func NewCipher(key []byte) (cipher.Block, error)

NewCipher returns a Camellia cipher.Block for a 16, 24 or 32 byte key. Other lengths return a KeySizeError.

Types

type KeySizeError

type KeySizeError int

KeySizeError is returned by NewCipher for a key length other than 16, 24 or 32 bytes.

func (KeySizeError) Error

func (k KeySizeError) Error() string

Directories

Path Synopsis
internal
genbotan command
Command genbotan writes testdata/botan-diff.vec, a differential corpus of Camellia single-block vectors produced by the installed Botan command line (`botan cipher --cipher=Camellia-<bits>/CBC/NoPadding` with a zero IV, which on one block is plain ECB).
Command genbotan writes testdata/botan-diff.vec, a differential corpus of Camellia single-block vectors produced by the installed Botan command line (`botan cipher --cipher=Camellia-<bits>/CBC/NoPadding` with a zero IV, which on one block is plain ECB).

Jump to

Keyboard shortcuts

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