-
Notifications
You must be signed in to change notification settings - Fork 3
/
core_generic.go
107 lines (87 loc) · 2.03 KB
/
core_generic.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//go:build !amd64 || purego
// +build !amd64 purego
package chaskey
import (
"encoding/binary"
"math/bits"
)
func chaskeyCore(h *H, m []byte, tag []byte) {
v0, v1, v2, v3 := h.k[0], h.k[1], h.k[2], h.k[3]
for ; len(m) > 16; m = m[16:] {
v0 ^= binary.LittleEndian.Uint32(m[0:4])
v1 ^= binary.LittleEndian.Uint32(m[4:8])
v2 ^= binary.LittleEndian.Uint32(m[8:12])
v3 ^= binary.LittleEndian.Uint32(m[12:16])
// permute
for i := 0; i < h.r; i++ {
// round
v0 += v1
v2 += v3
v1 = bits.RotateLeft32(v1, 5)
v3 = bits.RotateLeft32(v3, 8)
v1 ^= v0
v3 ^= v2
v0 = bits.RotateLeft32(v0, 16)
v0 += v3
v2 += v1
v3 = bits.RotateLeft32(v3, 13)
v1 = bits.RotateLeft32(v1, 7)
v3 ^= v0
v1 ^= v2
v2 = bits.RotateLeft32(v2, 16)
}
}
var l [4]uint32
var lastblock [4]uint32
if len(m) == 16 {
l = h.k1
lastblock[0] = binary.LittleEndian.Uint32(m[0:4])
lastblock[1] = binary.LittleEndian.Uint32(m[4:8])
lastblock[2] = binary.LittleEndian.Uint32(m[8:12])
lastblock[3] = binary.LittleEndian.Uint32(m[12:16])
} else {
l = h.k2
var lb [16]byte
copy(lb[:], m)
lb[len(m)] = 0x01
lastblock[0] = binary.LittleEndian.Uint32(lb[0:4])
lastblock[1] = binary.LittleEndian.Uint32(lb[4:8])
lastblock[2] = binary.LittleEndian.Uint32(lb[8:12])
lastblock[3] = binary.LittleEndian.Uint32(lb[12:16])
}
v0 ^= lastblock[0]
v1 ^= lastblock[1]
v2 ^= lastblock[2]
v3 ^= lastblock[3]
v0 ^= l[0]
v1 ^= l[1]
v2 ^= l[2]
v3 ^= l[3]
// permute
for i := 0; i < h.r; i++ {
// round
v0 += v1
v2 += v3
v1 = bits.RotateLeft32(v1, 5)
v3 = bits.RotateLeft32(v3, 8)
v1 ^= v0
v3 ^= v2
v0 = bits.RotateLeft32(v0, 16)
v0 += v3
v2 += v1
v3 = bits.RotateLeft32(v3, 13)
v1 = bits.RotateLeft32(v1, 7)
v3 ^= v0
v1 ^= v2
v2 = bits.RotateLeft32(v2, 16)
}
v0 ^= l[0]
v1 ^= l[1]
v2 ^= l[2]
v3 ^= l[3]
_ = tag[15]
binary.LittleEndian.PutUint32(tag[0:4], v0)
binary.LittleEndian.PutUint32(tag[4:8], v1)
binary.LittleEndian.PutUint32(tag[8:12], v2)
binary.LittleEndian.PutUint32(tag[12:16], v3)
}