pkg/cryptstate/ocb2: add documentation.

This commit is contained in:
Mikkel Krautz 2012-12-01 17:26:17 +01:00
parent 2ffd43f26b
commit 94c7cc2be0

View file

@ -1,3 +1,13 @@
// Package ocb2 implements the version 2 of the OCB authenticated-encryption algorithm.
// OCB2 is specified in http://www.cs.ucdavis.edu/~rogaway/papers/draft-krovetz-ocb-00.txt.
//
// It should be noted that OCB's author, Phil Rogaway <rogaway@cs.ucdavis.edu>, holds
// several US patents on the algorithm. This should be considered before using this code
// in your own projects. See OCB's FAQ for more info:
// http://www.cs.ucdavis.edu/~rogaway/ocb/ocb-faq.htm#patent:phil
//
// The Mumble Project has a license to use OCB mode in its BSD licensed code on a royalty
// free basis.
package ocb2 package ocb2
import ( import (
@ -5,21 +15,48 @@ import (
"crypto/cipher" "crypto/cipher"
) )
// TagSize specifies the length in bytes of an OCB2 tag. const (
const TagSize = aes.BlockSize // TagSize specifies the length in bytes of a full OCB2 tag.
// As per the specification, applications may truncate their
// tags to a given length, but advocates that typical applications
// should use a tag length of at least 8 bytes (64 bits).
TagSize = aes.BlockSize
// NonceSize specifies the length in bytes of an OCB2 nonce.
NonceSize = aes.BlockSize
)
// zeros fills block with zero bytes.
func zeros(block []byte) { func zeros(block []byte) {
for i := range block { for i := range block {
block[i] = 0 block[i] = 0
} }
} }
// xor outputs the bitwise exclusive-or of a and b to dst.
func xor(dst []byte, a []byte, b []byte) { func xor(dst []byte, a []byte, b []byte) {
for i := 0; i < aes.BlockSize; i++ { for i := 0; i < aes.BlockSize; i++ {
dst[i] = a[i] ^ b[i] dst[i] = a[i] ^ b[i]
} }
} }
// times2 performs the times2 operation, defined as:
//
// times2(S)
// S << 1 if S[1] = 0, and (S << 1) xor const(bitlength(S)) if S[1] = 1.
//
// where const(n) is defined as
//
// const(n)
// The lexicographically first n-bit string C among all
// strings that have a minimal possible number of "1"
// bits and which name a polynomial x^n + C[1] *
// x^{n-1} + ... + C[n-1] * x^1 + C[n] * x^0 that is
// irreducible over the field with two elements. In
// particular, const(128) = num2str(135, 128). For
// other values of n, refer to a standard table of
// irreducible polynomials [G. Seroussi,
// "Table of low-weight binary irreducible polynomials",
// HP Labs Technical Report HPL-98-135, 1998.].
func times2(block []byte) { func times2(block []byte) {
carry := (block[0] >> 7) & 0x1 carry := (block[0] >> 7) & 0x1
for i := 0; i < aes.BlockSize-1; i++ { for i := 0; i < aes.BlockSize-1; i++ {
@ -28,6 +65,10 @@ func times2(block []byte) {
block[aes.BlockSize-1] = (block[aes.BlockSize-1] << 1) ^ (carry * 135) block[aes.BlockSize-1] = (block[aes.BlockSize-1] << 1) ^ (carry * 135)
} }
// times3 performs the times3 operation, defined as:
//
// times3(S)
// times2(S) xor S
func times3(block []byte) { func times3(block []byte) {
carry := (block[0] >> 7) & 0x1 carry := (block[0] >> 7) & 0x1
for i := 0; i < aes.BlockSize-1; i++ { for i := 0; i < aes.BlockSize-1; i++ {
@ -36,6 +77,14 @@ func times3(block []byte) {
block[aes.BlockSize-1] ^= ((block[aes.BlockSize-1] << 1) ^ (carry * 135)) block[aes.BlockSize-1] ^= ((block[aes.BlockSize-1] << 1) ^ (carry * 135))
} }
// Encrypt encrypts the plaintext src and outputs the corresponding ciphertext into dst.
// Besides outputting a ciphertext into dst, Encrypt also outputs an authentication tag
// of ocb2.TagSize bytes into tag, which should be used to verify the authenticity of the
// message on the receiving side.
//
// To ensure both authenticity and secrecy of messages, each invocation to this function must
// be given an unique nonce of ocb2.NonceSize bytes. The nonce need not be secret (it can be
// a counter), but it needs to be unique.
func Encrypt(cipher cipher.Block, dst []byte, src []byte, nonce []byte, tag []byte) { func Encrypt(cipher cipher.Block, dst []byte, src []byte, nonce []byte, tag []byte) {
var delta [aes.BlockSize]byte var delta [aes.BlockSize]byte
var checksum [aes.BlockSize]byte var checksum [aes.BlockSize]byte
@ -82,6 +131,13 @@ func Encrypt(cipher cipher.Block, dst []byte, src []byte, nonce []byte, tag []by
cipher.Encrypt(tag[0:], tmp[0:]) cipher.Encrypt(tag[0:], tmp[0:])
} }
// Decrypt takes a ciphertext and a nonce as its input and outputs a decrypted plaintext
// and corresponding authentication tag.
//
// Before using the decrpyted plaintext, the application
// should verify that the computed authentication tag matches the tag that was produced when
// encrypting the message (taking into consideration that OCB tags are allowed to be truncated
// to a length less than ocb.TagSize).
func Decrypt(cipher cipher.Block, plain []byte, encrypted []byte, nonce []byte, tag []byte) { func Decrypt(cipher cipher.Block, plain []byte, encrypted []byte, nonce []byte, tag []byte) {
var checksum [aes.BlockSize]byte var checksum [aes.BlockSize]byte
var delta [aes.BlockSize]byte var delta [aes.BlockSize]byte