eme

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2026 License: MIT Imports: 3 Imported by: 27

README

EME for Go CI Go Reference MIT License

EME (ECB-Mix-ECB or, clearer, Encrypt-Mix-Encrypt) is a wide-block encryption mode developed by Halevi and Rogaway in 2003 [eme].

EME uses multiple invocations of a block cipher to construct a new cipher of bigger block size (in multiples of 16 bytes, up to 2048 bytes).

Key advantages:

  • Deterministic encryption - no random nonce
  • Zero overhead - zero ciphertext expansion
    • But this also means there is no authentication! The application must validate decrypted data.
  • True wide-block encryption. Changing a single bit randomizes the whole ciphertext.
    • This is not the case for AES-XTS, for example.

Quoting from the original [eme] paper:

We describe a block-cipher mode of operation, EME, that turns an n-bit block cipher into a tweakable enciphering scheme that acts on strings of mn bits, where m ∈ [1..n]. The mode is parallelizable, but as serial-efficient as the non-parallelizable mode CMC [6]. EME can be used to solve the disk-sector encryption problem. The algorithm entails two layers of ECB encryption and a “lightweight mixing” in between. We prove EME secure, in the reduction-based sense of modern cryptography.

Figure 2 from the [eme] paper shows an overview of the transformation:

Figure 2 from [eme]

This is an implementation of EME in Go, complete with test vectors from IEEE [p1619-2] and Halevi [eme-32-testvec].

It has no dependencies outside the standard library.

Is it patentend?

In 2007, the UC Davis has decided to abandon [patabandon] the patent application [patappl] for EME.

EME-32 is EME with the cipher set to AES and the length set to 512. That is, EME-32 [eme-32-pdf] is a subset of EME.

EME2, also known as EME* [emestar], is an extended version of EME that has built-in handling for data that is not a multiple of 16 bytes long.
EME2 has been selected for standardization in IEEE P1619.2 [p1619.2].

How to use

Ho to use the eme in you app: Use eme.New: https://pkg.go.dev/github.com/rfjakob/eme#New

How to run the self-tests:

$ go test -v
=== RUN   TestEnc512
--- PASS: TestEnc512 (0.00s)
=== RUN   TestEnc512x100
--- PASS: TestEnc512x100 (0.00s)
=== RUN   TestDec512
--- PASS: TestDec512 (0.00s)
=== RUN   TestDec512x100
--- PASS: TestDec512x100 (0.00s)
=== RUN   TestEnc16
--- PASS: TestEnc16 (0.00s)
=== RUN   TestEnc2048
--- PASS: TestEnc2048 (0.00s)
PASS
ok  	github.com/rfjakob/eme	0.005s

How to run the benchmarks:

$ ./benchmark.bash
goos: linux
goarch: amd64
pkg: github.com/rfjakob/eme
cpu: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
BenchmarkEnc512-4   	  142634	      8161 ns/op	  62.73 MB/s
BenchmarkDec512-4   	  140930	      8245 ns/op	  62.09 MB/s
PASS
ok  	github.com/rfjakob/eme	2.508s

Other implementations

Some other EME implementations I am aware of (PRs for more accepted):

References

[eme]

A Parallelizable Enciphering Mode
Shai Halevi, Phillip Rogaway, 28 Jul 2003
https://eprint.iacr.org/2003/147.pdf (archive.org snapshot)

Note: This is the original EME paper. EME is specified for an arbitrary number of block-cipher blocks. EME-32 is a concrete implementation of EME with a fixed length of 32 AES blocks.

[eme-32-email]

Re: EME-32-AES with editorial comments (announcement email with [eme-32-pdf] attachments)
Shai Halevi, 07 Jun 2005
http://grouper.ieee.org/groups/1619/email/msg00310.html (broken link as of July 2021, archive.org snapshot) (attachment: EME-32-AES-Jun-05.pdf=pdf00020.pdf),
http://grouper.ieee.org/groups/1619/email/msg00309.html (broken link as of July 2021, archive.org snapshot) (attachment: EME-32-AES-Jun-05.doc=doc00011.doc)

[eme-32-pdf]

Draft Standard for Tweakable Wide-block Encryption, EME-32-AES-Jun-05.{doc,pdf} Shai Halevi, 02 June 2005
EME-32-AES-Jun-05.pdf ... http://grouper.ieee.org/groups/1619/email/pdf00020.pdf (broken link as of July 2021, no archive.org snapshot available)
EME-32-AES-Jun-05.doc ... http://grouper.ieee.org/groups/1619/email/doc00011.doc (broken link as of July 2021, archive.org snapshot of external mirror)

Note: This is the latest version of the EME-32 draft that I could find as of Dec 2015. It includes test vectors and C source code.

[eme-32-testvec]

Re: Test vectors for LRW and EME
Shai Halevi, 16 Nov 2004
http://grouper.ieee.org/groups/1619/email/msg00218.html (broken link as of July 2021, archive.org snapshot)

[emestar]

EME*: extending EME to handle arbitrary-length messages with associated data
Shai Halevi, 27 May 2004
https://eprint.iacr.org/2004/125.pdf (archive.org snapshot)

[patabandon]

Re: [P1619-2] Non-awareness patent statement made by UC Davis
Mat Ball, 26 Nov 2007
http://grouper.ieee.org/groups/1619/email-2/msg00005.html (broken link as of July 2021, archive.org snapshot)

[patappl]

Block cipher mode of operation for constructing a wide-blocksize block cipher from a conventional block cipher
US patent application US20040131182
http://www.google.com/patents/US20040131182

[p1619-2]

IEEE P1619.2™/D9 Draft Standard for Wide-Block Encryption for Shared Storage Media
IEEE, Dec 2008
http://siswg.net/index2.php?option=com_docman&task=doc_view&gid=156&Itemid=41 (broken link as of July 2021, archive.org snapshot)

Note: This is a draft version. The final version is not freely available and must be bought from IEEE.

Package Changelog

v1.2.0, 2026-01-25

  • Convert if conditions in multByTwo() to constant-time operations (#8)
  • Update broken links in README, add links to other EME implementions
  • Switch to subtle.XORBytes (45802ed4fb60f60)

v1.1.2, 2021-06-27

  • Add go.mod file
  • Switch from Travis CI to Github Actions
  • No code changes

v1.1.1, 2020-04-13

  • Update go vet call in test.bash to work on recent Go versions
  • No code changes

v1.1, 2017-03-05

  • Add eme.New() / *EMECipher convenience wrapper
  • Improve panic message and parameter wording

v1.0, 2015-12-08

  • Stable release

Documentation

Overview

EME (ECB-Mix-ECB or, clearer, Encrypt-Mix-Encrypt) is a wide-block encryption mode developed by Halevi and Rogaway.

It was presented in the 2003 paper "A Parallelizable Enciphering Mode" by Halevi and Rogaway.

EME uses multiple invocations of a block cipher to construct a new cipher of bigger block size (in multiples of 16 bytes, up to 2048 bytes).

Index

Constants

View Source
const (
	// Encrypt "inputData"
	DirectionEncrypt = directionConst(true)
	// Decrypt "inputData"
	DirectionDecrypt = directionConst(false)
)

Variables

This section is empty.

Functions

func Transform

func Transform(bc cipher.Block, tweak []byte, inputData []byte, direction directionConst) []byte

Transform - EME-encrypt or EME-decrypt, according to "direction" (defined in the constants DirectionEncrypt and DirectionDecrypt). The data in "inputData" is en- or decrypted with the block ciper "bc" under "tweak" (also known as IV).

The tweak is used to randomize the encryption in the same way as an IV. A use of this encryption mode envisioned by the authors of the algorithm was to encrypt each sector of a disk, with the tweak being the sector number. If you encipher the same data with the same tweak you will get the same ciphertext.

The result is returned in a freshly allocated slice of the same size as inputData.

Limitations: * The block cipher must have block size 16 (usually AES). * The size of "tweak" must be 16 * "inputData" must be a multiple of 16 bytes long If any of these pre-conditions are not met, the function will panic.

Note that you probably don't want to call this function directly and instead use eme.New(), which provides convenient wrappers.

Types

type EMECipher

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

EMECipher provides EME-Encryption and -Decryption functions that are more convenient than calling Transform directly.

func New

func New(bc cipher.Block) *EMECipher

New returns a new EMECipher object. "bc" must have a block size of 16, or subsequent calls to Encrypt and Decrypt will panic.

func (*EMECipher) Decrypt

func (e *EMECipher) Decrypt(tweak []byte, inputData []byte) []byte

Decrypt is equivalent to calling Transform with direction=DirectionDecrypt.

func (*EMECipher) Encrypt

func (e *EMECipher) Encrypt(tweak []byte, inputData []byte) []byte

Encrypt is equivalent to calling Transform with direction=DirectionEncrypt.

Jump to

Keyboard shortcuts

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