The Go Programming Language

Source file src/pkg/crypto/xtea/cipher.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package xtea implements XTEA encryption, as defined in Needham and Wheeler's
     6	// 1997 technical report, "Tea extensions."
     7	package xtea
     8	
     9	// For details, see http://www.cix.co.uk/~klockstone/xtea.pdf
    10	
    11	import (
    12		"os"
    13		"strconv"
    14	)
    15	
    16	// The XTEA block size in bytes.
    17	const BlockSize = 8
    18	
    19	// A Cipher is an instance of an XTEA cipher using a particular key.
    20	// table contains a series of precalculated values that are used each round.
    21	type Cipher struct {
    22		table [64]uint32
    23	}
    24	
    25	type KeySizeError int
    26	
    27	func (k KeySizeError) String() string {
    28		return "crypto/xtea: invalid key size " + strconv.Itoa(int(k))
    29	}
    30	
    31	// NewCipher creates and returns a new Cipher.
    32	// The key argument should be the XTEA key.
    33	// XTEA only supports 128 bit (16 byte) keys.
    34	func NewCipher(key []byte) (*Cipher, os.Error) {
    35		k := len(key)
    36		switch k {
    37		default:
    38			return nil, KeySizeError(k)
    39		case 16:
    40			break
    41		}
    42	
    43		c := new(Cipher)
    44		initCipher(c, key)
    45	
    46		return c, nil
    47	}
    48	
    49	// BlockSize returns the XTEA block size, 8 bytes.
    50	// It is necessary to satisfy the Cipher interface in the
    51	// package "crypto/cipher".
    52	func (c *Cipher) BlockSize() int { return BlockSize }
    53	
    54	// Encrypt encrypts the 8 byte buffer src using the key and stores the result in dst.
    55	// Note that for amounts of data larger than a block,
    56	// it is not safe to just call Encrypt on successive blocks;
    57	// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
    58	func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c, dst, src) }
    59	
    60	// Decrypt decrypts the 8 byte buffer src using the key k and stores the result in dst.
    61	func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c, dst, src) }
    62	
    63	// Reset zeros the table, so that it will no longer appear in the process's memory.
    64	func (c *Cipher) Reset() {
    65		for i := 0; i < len(c.table); i++ {
    66			c.table[i] = 0
    67		}
    68	}
    69	
    70	// initCipher initializes the cipher context by creating a look up table
    71	// of precalculated values that are based on the key.
    72	func initCipher(c *Cipher, key []byte) {
    73		// Load the key into four uint32s
    74		var k [4]uint32
    75		for i := 0; i < len(k); i++ {
    76			j := i << 2 // Multiply by 4
    77			k[i] = uint32(key[j+0])<<24 | uint32(key[j+1])<<16 | uint32(key[j+2])<<8 | uint32(key[j+3])
    78		}
    79	
    80		// Precalculate the table
    81		const delta = 0x9E3779B9
    82		var sum uint32 = 0
    83	
    84		// Two rounds of XTEA applied per loop
    85		for i := 0; i < numRounds; {
    86			c.table[i] = sum + k[sum&3]
    87			i++
    88			sum += delta
    89			c.table[i] = sum + k[(sum>>11)&3]
    90			i++
    91		}
    92	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.