1
2
3
4
5 package sha3
6
7
8
9
10
11
12
13 import (
14 "bytes"
15 "compress/flate"
16 "encoding/hex"
17 "encoding/json"
18 "fmt"
19 "math/rand"
20 "os"
21 "strings"
22 "testing"
23 )
24
25 const (
26 katFilename = "testdata/keccakKats.json.deflate"
27 )
28
29
30
31
32 var testDigests = map[string]func() State{
33 "SHA3-224": New224,
34 "SHA3-256": New256,
35 "SHA3-384": New384,
36 "SHA3-512": New512,
37 }
38
39
40 type KeccakKats struct {
41 Kats map[string][]struct {
42 Digest string `json:"digest"`
43 Length int64 `json:"length"`
44 Message string `json:"message"`
45
46
47 N string `json:"N"`
48 S string `json:"S"`
49 }
50 }
51
52
53
54
55 func TestKeccakKats(t *testing.T) {
56
57 deflated, err := os.Open(katFilename)
58 if err != nil {
59 t.Errorf("error opening %s: %s", katFilename, err)
60 }
61 file := flate.NewReader(deflated)
62 dec := json.NewDecoder(file)
63 var katSet KeccakKats
64 err = dec.Decode(&katSet)
65 if err != nil {
66 t.Errorf("error decoding KATs: %s", err)
67 }
68
69 for algo, function := range testDigests {
70 d := function()
71 for _, kat := range katSet.Kats[algo] {
72 d.Reset()
73 in, err := hex.DecodeString(kat.Message)
74 if err != nil {
75 t.Errorf("error decoding KAT: %s", err)
76 }
77 _, _ = d.Write(in[:kat.Length/8])
78 got := strings.ToUpper(hex.EncodeToString(d.Sum(nil)))
79 if got != kat.Digest {
80 t.Errorf("function=%s, length=%d\nmessage:\n %s\ngot:\n %s\nwanted:\n %s",
81 algo, kat.Length, kat.Message, got, kat.Digest)
82 t.Logf("wanted %+v", kat)
83 t.FailNow()
84 }
85 continue
86 }
87 }
88 }
89
90
91
92 func TestUnalignedWrite(t *testing.T) {
93 buf := sequentialBytes(0x10000)
94 for alg, df := range testDigests {
95 d := df()
96 d.Reset()
97 _, _ = d.Write(buf)
98 want := d.Sum(nil)
99 d.Reset()
100 for i := 0; i < len(buf); {
101
102
103 offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1}
104 for _, j := range offsets {
105 if v := len(buf) - i; v < j {
106 j = v
107 }
108 _, _ = d.Write(buf[i : i+j])
109 i += j
110 }
111 }
112 got := d.Sum(nil)
113 if !bytes.Equal(got, want) {
114 t.Errorf("Unaligned writes, alg=%s\ngot %q, want %q", alg, got, want)
115 }
116 }
117 }
118
119
120 func TestAppend(t *testing.T) {
121 d := New224()
122
123 for capacity := 2; capacity <= 66; capacity += 64 {
124
125
126 buf := make([]byte, 2, capacity)
127 d.Reset()
128 _, _ = d.Write([]byte{0xcc})
129 buf = d.Sum(buf)
130 expected := "0000DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
131 if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
132 t.Errorf("got %s, want %s", got, expected)
133 }
134 }
135 }
136
137
138 func TestAppendNoRealloc(t *testing.T) {
139 buf := make([]byte, 1, 200)
140 d := New224()
141 _, _ = d.Write([]byte{0xcc})
142 buf = d.Sum(buf)
143 expected := "00DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
144 if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
145 t.Errorf("got %s, want %s", got, expected)
146 }
147 }
148
149
150
151
152
153
154
155 func sequentialBytes(size int) []byte {
156 alignmentOffset := rand.Intn(8)
157 result := make([]byte, size+alignmentOffset)[alignmentOffset:]
158 for i := range result {
159 result[i] = byte(i)
160 }
161 return result
162 }
163
164
165
166 func BenchmarkPermutationFunctionTurbo(b *testing.B) {
167 b.SetBytes(int64(200))
168 var lanes [25]uint64
169 for i := 0; i < b.N; i++ {
170 KeccakF1600(&lanes, true)
171 }
172 }
173
174
175
176 func BenchmarkPermutationFunction(b *testing.B) {
177 b.SetBytes(int64(200))
178 var lanes [25]uint64
179 for i := 0; i < b.N; i++ {
180 KeccakF1600(&lanes, false)
181 }
182 }
183
184
185 func benchmarkHash(b *testing.B, h State, size, num int) {
186 b.StopTimer()
187 h.Reset()
188 data := sequentialBytes(size)
189 b.SetBytes(int64(size * num))
190 b.StartTimer()
191
192 var state []byte
193 for i := 0; i < b.N; i++ {
194 for j := 0; j < num; j++ {
195 _, _ = h.Write(data)
196 }
197 state = h.Sum(state[:0])
198 }
199 b.StopTimer()
200 h.Reset()
201 }
202
203
204
205 func benchmarkShake(b *testing.B, h State, size, num int) {
206 b.StopTimer()
207 h.Reset()
208 data := sequentialBytes(size)
209 d := make([]byte, 32)
210
211 b.SetBytes(int64(size * num))
212 b.StartTimer()
213
214 for i := 0; i < b.N; i++ {
215 h.Reset()
216 for j := 0; j < num; j++ {
217 _, _ = h.Write(data)
218 }
219 _, _ = h.Read(d)
220 }
221 }
222
223 func BenchmarkSha3_512_MTU(b *testing.B) { benchmarkHash(b, New512(), 1350, 1) }
224 func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) }
225 func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) }
226 func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) }
227
228 func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 1350, 1) }
229 func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) }
230 func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) }
231 func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) }
232
233 func BenchmarkTurboShake128_1MiB(b *testing.B) { benchmarkShake(b, NewTurboShake128(0x37), 1024, 1024) }
234 func BenchmarkTurboShake256_1MiB(b *testing.B) { benchmarkShake(b, NewTurboShake256(0x37), 1024, 1024) }
235
236 func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) }
237
238 func Example_sum() {
239 buf := []byte("some data to hash")
240
241 h := make([]byte, 64)
242
243 ShakeSum256(h, buf)
244 fmt.Printf("%x\n", h)
245
246 }
247
248 func Example_mac() {
249 k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long")
250 buf := []byte("and this is some data to authenticate")
251
252 h := make([]byte, 32)
253 d := NewShake256()
254
255 _, _ = d.Write(k)
256
257 _, _ = d.Write(buf)
258
259 _, _ = d.Read(h)
260 fmt.Printf("%x\n", h)
261
262 }
263
264 func TestTurboShake128(t *testing.T) {
265 out := make([]byte, 64)
266 TurboShakeSum128(out, []byte{}, 0x07)
267 if hex.EncodeToString(out) != "5a223ad30b3b8c66a243048cfced430f54e7529287d15150b973133adfac6a2ffe2708e73061e09a4000168ba9c8ca1813198f7bbed4984b4185f2c2580ee623" {
268 t.Fatal()
269 }
270
271 h := NewTurboShake128(0x07)
272 out = make([]byte, 10032)
273 _, _ = h.Read(out)
274 if hex.EncodeToString(out[len(out)-32:]) != "7593a28020a3c4ae0d605fd61f5eb56eccd27cc3d12ff09f78369772a460c55d" {
275 t.Fatal()
276 }
277
278 out = make([]byte, 32)
279 TurboShakeSum128(out, []byte{0xff}, 0x06)
280 if hex.EncodeToString(out) != "8ec9c66465ed0d4a6c35d13506718d687a25cb05c74cca1e42501abd83874a67" {
281 t.Fatal()
282 }
283
284
285 }
286
View as plain text