package util import ( "encoding/binary" "strconv" ) type teaCipher struct { key []byte } type KeySizeError int func (k KeySizeError) Error() string { return "tea: invalid key size " + strconv.Itoa(int(k)) } func NewCipher(key []byte) (*teaCipher, error) { if len(key) != 16 { return nil, KeySizeError(len(key)) } cipher := new(teaCipher) cipher.key = key return cipher, nil } func (c *teaCipher) BlockSize() int { return 8 } func (c *teaCipher) Encrypt(dst, src []byte) { var ( end = binary.BigEndian v0, v1 uint32 = end.Uint32(src), end.Uint32(src[4:]) sum uint32 = 0 delta uint32 = 0x9E3779B9 k0, k1, k2, k3 uint32 = end.Uint32(c.key[0:]), end.Uint32(c.key[4:]), end.Uint32(c.key[8:]), end.Uint32(c.key[12:]) ) for i := 0; i < 32; i++ { sum += delta v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1) v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3) } end.PutUint32(dst, v0) end.PutUint32(dst[4:], v1) } func (c *teaCipher) Decrypt(dst, src []byte) { var ( end = binary.BigEndian v0, v1 uint32 = end.Uint32(src[0:4]), end.Uint32(src[4:8]) delta uint32 = 0x9E3779B9 sum uint32 = delta << 5 k0, k1, k2, k3 uint32 = end.Uint32(c.key[0:]), end.Uint32(c.key[4:]), end.Uint32(c.key[8:]), end.Uint32(c.key[12:]) ) for i := 0; i < 32; i++ { v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3) v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1) sum -= delta } end.PutUint32(dst, v0) end.PutUint32(dst[4:], v1) } func (c *teaCipher) Clear() { for i := 0; i < len(c.key); i++ { c.key[i] = 0 } }