/
lea.go
92 lines (69 loc) · 2.01 KB
/
lea.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package lea
import (
"fmt"
"crypto/cipher"
"github.com/deatil/go-cryptobin/tool/alias"
)
const BlockSize = 16
type KeySizeError int
func (k KeySizeError) Error() string {
return fmt.Sprintf("cryptobin/lea: invalid key size %d", int(k))
}
type leaCipher struct {
erk [][6]uint32
drk [][6]uint32
}
// NewCipher creates and returns a new cipher.Block.
// The key argument should be the LEA key,
// either 16, 24, or 32 bytes to select LEA-128, LEA-192, or LEA-256.
func NewCipher(key []byte) (cipher.Block, error) {
k := len(key)
switch k {
case 16, 24, 32:
break
default:
return nil, KeySizeError(k)
}
c := new(leaCipher)
c.expandKey(key)
return c, nil
}
func (this *leaCipher) BlockSize() int {
return BlockSize
}
func (this *leaCipher) Encrypt(dst, src []byte) {
if len(src) < BlockSize {
panic(fmt.Sprintf("cryptobin/lea: invalid block size %d (src)", len(src)))
}
if len(dst) < BlockSize {
panic(fmt.Sprintf("cryptobin/lea: invalid block size %d (dst)", len(dst)))
}
if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
panic("cryptobin/lea: invalid buffer overlap")
}
this.encrypt(dst, src)
}
func (this *leaCipher) Decrypt(dst, src []byte) {
if len(src) < BlockSize {
panic(fmt.Sprintf("cryptobin/lea: invalid block size %d (src)", len(src)))
}
if len(dst) < BlockSize {
panic(fmt.Sprintf("cryptobin/lea: invalid block size %d (dst)", len(dst)))
}
if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
panic("cryptobin/lea: invalid buffer overlap")
}
this.decrypt(dst, src)
}
func (this *leaCipher) encrypt(dst, src []byte) {
res := crypt(src, this.erk, true)
copy(dst, res[:])
}
func (this *leaCipher) decrypt(dst, src []byte) {
res := crypt(src, this.drk, false)
copy(dst, res[:])
}
func (this *leaCipher) expandKey(key []byte) {
this.erk = roundKey(key, true)
this.drk = roundKey(key, false)
}