Help us shape the future of Go! Take the 2026 Go Developer Survey

xts

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 31, 2026 License: BSD-3-Clause Imports: 6 Imported by: 2

README

go-encryptions/xts

go-encryptions/xts

ci Go Reference

Pure-Go XTS-AES tweakable block-cipher mode (IEEE P1619/D16, NIST SP 800-38E), the sector-level disk-encryption mode used by LUKS, APFS FileVault 2, BitLocker and dm-crypt.

It is a drop-in replacement for golang.org/x/crypto/xts: the Cipher type exposes the same NewCipher / Encrypt / Decrypt API and produces byte-identical ciphertext. The difference is performance. x/crypto/xts drives the block cipher one 16-byte block at a time through the cipher.Block interface, which collapses a hardware AES engine to a fraction of its throughput. This package instead ships a fused AES-XTS kernel that pipelines four AES blocks at a time and folds the tweak XOR into the round pipeline:

  • amd64 (AES-NI) and arm64 (ARMv8 AES + NEON) run the AESENC / AESE·AESMC pipeline directly in Plan 9 assembly, reaching multi-GB/s per core.
  • riscv64, loong64, ppc64le, s390x transparently fall back to the same per-block algorithm as x/crypto/xts, so behaviour is identical everywhere — only the speed differs.

Built for the go-encryptions family; the primary consumers are the full-disk-encryption backends go-fde/luks and go-fde/apfs.

Install

go get github.com/go-encryptions/xts

Usage

import (
	"crypto/aes"

	"github.com/go-encryptions/xts"
)

// key is the concatenation of two AES keys (32, 48 or 64 bytes total).
c, err := xts.NewCipher(aes.NewCipher, key)
if err != nil { /* ... */ }

c.Encrypt(ciphertext, plaintext, sectorNum) // one 512/4096-byte sector
c.Decrypt(plaintext, ciphertext, sectorNum)

Encrypt and Decrypt operate on a whole disk sector at a time; sectorNum is the tweak (the sector index). Buffers must be a whole number of 16-byte blocks and at least one block long, matching the x/crypto/xts contract.

Encrypt and Decrypt do not allocate: the tweak buffer comes from a sync.Pool, as in golang.org/x/crypto/xts; TestNoAllocPerSector pins it.

Guarantees

  • Byte-identical output to golang.org/x/crypto/xts on every architecture, verified in CI against x/crypto as a reference oracle.
  • CGO=0, no unsafe in the API surface, no external deps beyond golang.org/x/sys/cpu (AES-NI feature detection) and golang.org/x/crypto (test-only cross-check).
  • All six 64-bit Go targets — amd64, arm64, riscv64, loong64, ppc64le and big-endian s390x — are built and tested in CI (native + QEMU), with a 100%-of-statements coverage gate.

License

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

Documentation

Overview

Package xts implements the XTS-AES tweakable block-cipher mode (IEEE P1619/D16, NIST SP 800-38E) used for full-disk encryption.

It is a drop-in replacement for golang.org/x/crypto/xts: the Cipher type exposes the same NewCipher / Encrypt / Decrypt API and produces byte-identical ciphertext. The difference is performance. x/crypto/xts drives the underlying block cipher one 16-byte block at a time through the cipher.Block interface and advances the XTS tweak with a scalar GF(2^128) multiply per block; on a CPU with hardware AES this collapses a ~10 GB/s AES engine to ~600 MB/s because the per-block interface dispatch defeats the pipelined multi-block AES path.

This package instead ships a fused AES-XTS kernel that pipelines four AES blocks at a time and folds the tweak XOR into the round pipeline. On arm64 (ARMv8 AES + NEON) and amd64 (AES-NI) the kernel runs the AESE/AESMC (resp. AESENC) pipeline directly, reaching multi-GB/s per core. On the remaining architectures (riscv64, loong64, ppc64le, s390x) it transparently falls back to the same per-block algorithm as x/crypto/xts, so behaviour is identical everywhere; only the speed differs.

XTS provides confidentiality but no authentication, and does not implement ciphertext stealing, so each sector must be a multiple of 16 bytes. It is intended for disk-sector encryption only.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cipher

type Cipher struct {
	// contains filtered or unexported fields
}

Cipher is an expanded XTS key. It is safe for concurrent use.

func NewCipher

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

NewCipher creates a Cipher from a function that builds the underlying block cipher (which must have a 16-byte block size) and a key that is twice the underlying cipher's key length. For AES this is a 32-byte key (AES-128-XTS) or a 64-byte key (AES-256-XTS).

func (*Cipher) Decrypt

func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64)

Decrypt decrypts a sector of ciphertext into plaintext using the given sector number as the XTS tweak. The same overlap and length rules as Encrypt apply.

func (*Cipher) Encrypt

func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64)

Encrypt encrypts a sector of plaintext into ciphertext using the given sector number as the XTS tweak. ciphertext and plaintext must overlap entirely or not at all, and len(plaintext) must be a non-zero multiple of 16 bytes.

Jump to

Keyboard shortcuts

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