...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package tea
17
18 import (
19 "crypto/cipher"
20 "encoding/binary"
21 "errors"
22 )
23
24 const (
25
26 BlockSize = 8
27
28
29 KeySize = 16
30
31
32 delta = 0x9e3779b9
33
34
35 numRounds = 64
36 )
37
38
39 type tea struct {
40 key [16]byte
41 rounds int
42 }
43
44
45
46 func NewCipher(key []byte) (cipher.Block, error) {
47 return NewCipherWithRounds(key, numRounds)
48 }
49
50
51
52
53 func NewCipherWithRounds(key []byte, rounds int) (cipher.Block, error) {
54 if len(key) != 16 {
55 return nil, errors.New("tea: incorrect key size")
56 }
57
58 if rounds&1 != 0 {
59 return nil, errors.New("tea: odd number of rounds specified")
60 }
61
62 c := &tea{
63 rounds: rounds,
64 }
65 copy(c.key[:], key)
66
67 return c, nil
68 }
69
70
71
72 func (*tea) BlockSize() int {
73 return BlockSize
74 }
75
76
77
78
79
80 func (t *tea) Encrypt(dst, src []byte) {
81 e := binary.BigEndian
82 v0, v1 := e.Uint32(src), e.Uint32(src[4:])
83 k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
84
85 sum := uint32(0)
86 delta := uint32(delta)
87
88 for i := 0; i < t.rounds/2; i++ {
89 sum += delta
90 v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
91 v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
92 }
93
94 e.PutUint32(dst, v0)
95 e.PutUint32(dst[4:], v1)
96 }
97
98
99
100 func (t *tea) Decrypt(dst, src []byte) {
101 e := binary.BigEndian
102 v0, v1 := e.Uint32(src), e.Uint32(src[4:])
103 k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
104
105 delta := uint32(delta)
106 sum := delta * uint32(t.rounds/2)
107
108 for i := 0; i < t.rounds/2; i++ {
109 v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
110 v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
111 sum -= delta
112 }
113
114 e.PutUint32(dst, v0)
115 e.PutUint32(dst[4:], v1)
116 }
117
View as plain text