123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- package tea
- import (
- "crypto/cipher"
- "encoding/binary"
- "errors"
- )
- const (
-
- BlockSize = 8
-
- KeySize = 16
-
- delta = 0x9e3779b9
-
- numRounds = 64
- )
- type tea struct {
- key [16]byte
- rounds int
- }
- func NewCipher(key []byte) (cipher.Block, error) {
- return NewCipherWithRounds(key, numRounds)
- }
- func NewCipherWithRounds(key []byte, rounds int) (cipher.Block, error) {
- if len(key) != 16 {
- return nil, errors.New("tea: incorrect key size")
- }
- if rounds&1 != 0 {
- return nil, errors.New("tea: odd number of rounds specified")
- }
- c := &tea{
- rounds: rounds,
- }
- copy(c.key[:], key)
- return c, nil
- }
- func (*tea) BlockSize() int {
- return BlockSize
- }
- func (t *tea) Encrypt(dst, src []byte) {
- e := binary.BigEndian
- v0, v1 := e.Uint32(src), e.Uint32(src[4:])
- k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
- sum := uint32(0)
- delta := uint32(delta)
- for i := 0; i < t.rounds/2; i++ {
- sum += delta
- v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
- v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
- }
- e.PutUint32(dst, v0)
- e.PutUint32(dst[4:], v1)
- }
- func (t *tea) Decrypt(dst, src []byte) {
- e := binary.BigEndian
- v0, v1 := e.Uint32(src), e.Uint32(src[4:])
- k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
- delta := uint32(delta)
- sum := delta * uint32(t.rounds/2)
- for i := 0; i < t.rounds/2; i++ {
- v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
- v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
- sum -= delta
- }
- e.PutUint32(dst, v0)
- e.PutUint32(dst[4:], v1)
- }
|