blob: 83bd6195d6cd13f81502f28e0fbf473927c6ccdf [file] [log] [blame]
David Leon Gil1b32d8b2014-09-03 12:04:00 -07001// Copyright 2014 The Go Authors. All rights reserved.
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -04002// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package sha3
6
David Leon Gil1b32d8b2014-09-03 12:04:00 -07007// Tests include all the ShortMsgKATs provided by the Keccak team at
8// https://github.com/gvanas/KeccakCodePackage
9//
David Leon Gil4ed45ec2014-12-26 19:04:10 -080010// They only include the zero-bit case of the bitwise testvectors
11// published by NIST in the draft of FIPS-202.
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -040012
13import (
14 "bytes"
David Leon Gil1b32d8b2014-09-03 12:04:00 -070015 "compress/flate"
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -040016 "encoding/hex"
David Leon Gil1b32d8b2014-09-03 12:04:00 -070017 "encoding/json"
sbuss7f7c0c22017-07-15 10:57:27 -070018 "fmt"
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -040019 "hash"
Bryan C. Millsf7b00552020-03-11 09:15:05 -040020 "math/rand"
David Leon Gil1b32d8b2014-09-03 12:04:00 -070021 "os"
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -040022 "strings"
23 "testing"
24)
25
David Leon Gil1b32d8b2014-09-03 12:04:00 -070026const (
27 testString = "brekeccakkeccak koax koax"
David Leon Gilbfc28692015-01-24 13:42:34 -080028 katFilename = "testdata/keccakKats.json.deflate"
David Leon Gil1b32d8b2014-09-03 12:04:00 -070029)
30
David Leon Gil1b32d8b2014-09-03 12:04:00 -070031// testDigests contains functions returning hash.Hash instances
Leon Klingele4ec37c62018-05-05 00:22:42 +000032// with output-length equal to the KAT length for SHA-3, Keccak
33// and SHAKE instances.
David Leon Gil1b32d8b2014-09-03 12:04:00 -070034var testDigests = map[string]func() hash.Hash{
Leon Klingele4ec37c62018-05-05 00:22:42 +000035 "SHA3-224": New224,
36 "SHA3-256": New256,
37 "SHA3-384": New384,
38 "SHA3-512": New512,
39 "Keccak-256": NewLegacyKeccak256,
Péter Szilágyiff983b92018-07-25 14:53:45 +030040 "Keccak-512": NewLegacyKeccak512,
David Leon Gil1b32d8b2014-09-03 12:04:00 -070041}
42
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +010043// testShakes contains functions that return sha3.ShakeHash instances for
44// with output-length equal to the KAT length.
45var testShakes = map[string]struct {
46 constructor func(N []byte, S []byte) ShakeHash
47 defAlgoName string
48 defCustomStr string
49}{
50 // NewCShake without customization produces same result as SHAKE
51 "SHAKE128": {NewCShake128, "", ""},
52 "SHAKE256": {NewCShake256, "", ""},
53 "cSHAKE128": {NewCShake128, "CSHAKE128", "CustomStrign"},
54 "cSHAKE256": {NewCShake256, "CSHAKE256", "CustomStrign"},
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -040055}
56
David Leon Gil4ed45ec2014-12-26 19:04:10 -080057// decodeHex converts a hex-encoded string into a raw byte string.
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -040058func decodeHex(s string) []byte {
59 b, err := hex.DecodeString(s)
60 if err != nil {
61 panic(err)
62 }
63 return b
64}
65
David Leon Gil1b32d8b2014-09-03 12:04:00 -070066// structs used to marshal JSON test-cases.
67type KeccakKats struct {
68 Kats map[string][]struct {
69 Digest string `json:"digest"`
70 Length int64 `json:"length"`
71 Message string `json:"message"`
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +010072
73 // Defined only for cSHAKE
74 N string `json:"N"`
75 S string `json:"S"`
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -040076 }
David Leon Gil1b32d8b2014-09-03 12:04:00 -070077}
78
David Leon Gil4ed45ec2014-12-26 19:04:10 -080079func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) {
80 xorInOrig, copyOutOrig := xorIn, copyOut
81 xorIn, copyOut = xorInGeneric, copyOutGeneric
82 testf("generic")
83 if xorImplementationUnaligned != "generic" {
84 xorIn, copyOut = xorInUnaligned, copyOutUnaligned
85 testf("unaligned")
86 }
87 xorIn, copyOut = xorInOrig, copyOutOrig
88}
89
David Leon Gil1b32d8b2014-09-03 12:04:00 -070090// TestKeccakKats tests the SHA-3 and Shake implementations against all the
91// ShortMsgKATs from https://github.com/gvanas/KeccakCodePackage
92// (The testvectors are stored in keccakKats.json.deflate due to their length.)
93func TestKeccakKats(t *testing.T) {
David Leon Gil4ed45ec2014-12-26 19:04:10 -080094 testUnalignedAndGeneric(t, func(impl string) {
95 // Read the KATs.
96 deflated, err := os.Open(katFilename)
97 if err != nil {
98 t.Errorf("error opening %s: %s", katFilename, err)
99 }
100 file := flate.NewReader(deflated)
101 dec := json.NewDecoder(file)
102 var katSet KeccakKats
103 err = dec.Decode(&katSet)
104 if err != nil {
105 t.Errorf("error decoding KATs: %s", err)
106 }
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700107
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100108 for algo, function := range testDigests {
109 d := function()
110 for _, kat := range katSet.Kats[algo] {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800111 d.Reset()
112 in, err := hex.DecodeString(kat.Message)
113 if err != nil {
114 t.Errorf("error decoding KAT: %s", err)
115 }
116 d.Write(in[:kat.Length/8])
117 got := strings.ToUpper(hex.EncodeToString(d.Sum(nil)))
118 if got != kat.Digest {
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100119 t.Errorf("function=%s, implementation=%s, length=%d\nmessage:\n %s\ngot:\n %s\nwanted:\n %s",
120 algo, impl, kat.Length, kat.Message, got, kat.Digest)
121 t.Logf("wanted %+v", kat)
122 t.FailNow()
123 }
124 continue
125 }
126 }
127
128 for algo, v := range testShakes {
129 for _, kat := range katSet.Kats[algo] {
130 N, err := hex.DecodeString(kat.N)
131 if err != nil {
132 t.Errorf("error decoding KAT: %s", err)
133 }
134
135 S, err := hex.DecodeString(kat.S)
136 if err != nil {
137 t.Errorf("error decoding KAT: %s", err)
138 }
139 d := v.constructor(N, S)
140 in, err := hex.DecodeString(kat.Message)
141 if err != nil {
142 t.Errorf("error decoding KAT: %s", err)
143 }
144
145 d.Write(in[:kat.Length/8])
146 out := make([]byte, len(kat.Digest)/2)
147 d.Read(out)
148 got := strings.ToUpper(hex.EncodeToString(out))
149 if got != kat.Digest {
150 t.Errorf("function=%s, implementation=%s, length=%d N:%s\n S:%s\nmessage:\n %s \ngot:\n %s\nwanted:\n %s",
151 algo, impl, kat.Length, kat.N, kat.S, kat.Message, got, kat.Digest)
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800152 t.Logf("wanted %+v", kat)
153 t.FailNow()
154 }
155 continue
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400156 }
157 }
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800158 })
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400159}
160
Leon Klingele4ec37c62018-05-05 00:22:42 +0000161// TestKeccak does a basic test of the non-standardized Keccak hash functions.
162func TestKeccak(t *testing.T) {
163 tests := []struct {
164 fn func() hash.Hash
165 data []byte
166 want string
167 }{
168 {
169 NewLegacyKeccak256,
170 []byte("abc"),
171 "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45",
172 },
Péter Szilágyiff983b92018-07-25 14:53:45 +0300173 {
174 NewLegacyKeccak512,
175 []byte("abc"),
176 "18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96",
177 },
Leon Klingele4ec37c62018-05-05 00:22:42 +0000178 }
179
180 for _, u := range tests {
181 h := u.fn()
182 h.Write(u.data)
183 got := h.Sum(nil)
184 want := decodeHex(u.want)
185 if !bytes.Equal(got, want) {
186 t.Errorf("unexpected hash for size %d: got '%x' want '%s'", h.Size()*8, got, u.want)
187 }
188 }
189}
190
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700191// TestUnalignedWrite tests that writing data in an arbitrary pattern with
192// small input buffers.
Kris Kwiatkowski76a95462018-05-03 14:03:53 +0100193func TestUnalignedWrite(t *testing.T) {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800194 testUnalignedAndGeneric(t, func(impl string) {
195 buf := sequentialBytes(0x10000)
196 for alg, df := range testDigests {
197 d := df()
198 d.Reset()
199 d.Write(buf)
200 want := d.Sum(nil)
201 d.Reset()
202 for i := 0; i < len(buf); {
203 // Cycle through offsets which make a 137 byte sequence.
204 // Because 137 is prime this sequence should exercise all corner cases.
205 offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1}
206 for _, j := range offsets {
207 if v := len(buf) - i; v < j {
208 j = v
209 }
210 d.Write(buf[i : i+j])
211 i += j
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700212 }
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800213 }
214 got := d.Sum(nil)
215 if !bytes.Equal(got, want) {
216 t.Errorf("Unaligned writes, implementation=%s, alg=%s\ngot %q, want %q", impl, alg, got, want)
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400217 }
218 }
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100219
220 // Same for SHAKE
221 for alg, df := range testShakes {
222 want := make([]byte, 16)
223 got := make([]byte, 16)
224 d := df.constructor([]byte(df.defAlgoName), []byte(df.defCustomStr))
225
226 d.Reset()
227 d.Write(buf)
228 d.Read(want)
229 d.Reset()
230 for i := 0; i < len(buf); {
231 // Cycle through offsets which make a 137 byte sequence.
232 // Because 137 is prime this sequence should exercise all corner cases.
233 offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1}
234 for _, j := range offsets {
235 if v := len(buf) - i; v < j {
236 j = v
237 }
238 d.Write(buf[i : i+j])
239 i += j
240 }
241 }
242 d.Read(got)
243 if !bytes.Equal(got, want) {
244 t.Errorf("Unaligned writes, implementation=%s, alg=%s\ngot %q, want %q", impl, alg, got, want)
245 }
246 }
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800247 })
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400248}
249
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800250// TestAppend checks that appending works when reallocation is necessary.
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400251func TestAppend(t *testing.T) {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800252 testUnalignedAndGeneric(t, func(impl string) {
253 d := New224()
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400254
Glenn Brownbc65b902015-04-15 17:38:08 -0700255 for capacity := 2; capacity <= 66; capacity += 64 {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800256 // The first time around the loop, Sum will have to reallocate.
257 // The second time, it will not.
258 buf := make([]byte, 2, capacity)
259 d.Reset()
260 d.Write([]byte{0xcc})
261 buf = d.Sum(buf)
262 expected := "0000DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
263 if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
264 t.Errorf("got %s, want %s", got, expected)
265 }
266 }
267 })
268}
269
270// TestAppendNoRealloc tests that appending works when no reallocation is necessary.
271func TestAppendNoRealloc(t *testing.T) {
272 testUnalignedAndGeneric(t, func(impl string) {
273 buf := make([]byte, 1, 200)
274 d := New224()
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400275 d.Write([]byte{0xcc})
276 buf = d.Sum(buf)
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800277 expected := "00DF70ADC49B2E76EEE3A6931B93FA41841C3AF2CDF5B32A18B5478C39"
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400278 if got := strings.ToUpper(hex.EncodeToString(buf)); got != expected {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800279 t.Errorf("%s: got %s, want %s", impl, got, expected)
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400280 }
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800281 })
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400282}
283
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700284// TestSqueezing checks that squeezing the full output a single time produces
285// the same output as repeatedly squeezing the instance.
286func TestSqueezing(t *testing.T) {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800287 testUnalignedAndGeneric(t, func(impl string) {
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100288 for algo, v := range testShakes {
289 d0 := v.constructor([]byte(v.defAlgoName), []byte(v.defCustomStr))
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800290 d0.Write([]byte(testString))
291 ref := make([]byte, 32)
292 d0.Read(ref)
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700293
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100294 d1 := v.constructor([]byte(v.defAlgoName), []byte(v.defCustomStr))
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800295 d1.Write([]byte(testString))
296 var multiple []byte
Kevin Burke94eea522017-11-27 17:43:40 -0800297 for range ref {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800298 one := make([]byte, 1)
299 d1.Read(one)
300 multiple = append(multiple, one...)
301 }
302 if !bytes.Equal(ref, multiple) {
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100303 t.Errorf("%s (%s): squeezing %d bytes one at a time failed", algo, impl, len(ref))
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800304 }
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700305 }
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800306 })
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700307}
308
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400309// sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing.
Bryan C. Millsf7b00552020-03-11 09:15:05 -0400310//
311// The alignment of each slice is intentionally randomized to detect alignment
312// issues in the implementation. See https://golang.org/issue/37644.
313// Ideally, the compiler should fuzz the alignment itself.
314// (See https://golang.org/issue/35128.)
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400315func sequentialBytes(size int) []byte {
Bryan C. Millsf7b00552020-03-11 09:15:05 -0400316 alignmentOffset := rand.Intn(8)
317 result := make([]byte, size+alignmentOffset)[alignmentOffset:]
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400318 for i := range result {
319 result[i] = byte(i)
320 }
321 return result
322}
323
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100324func TestReset(t *testing.T) {
325 out1 := make([]byte, 32)
326 out2 := make([]byte, 32)
327
328 for _, v := range testShakes {
329 // Calculate hash for the first time
330 c := v.constructor(nil, []byte{0x99, 0x98})
331 c.Write(sequentialBytes(0x100))
332 c.Read(out1)
333
334 // Calculate hash again
335 c.Reset()
336 c.Write(sequentialBytes(0x100))
337 c.Read(out2)
338
339 if !bytes.Equal(out1, out2) {
340 t.Error("\nExpected:\n", out1, "\ngot:\n", out2)
341 }
342 }
343}
344
345func TestClone(t *testing.T) {
346 out1 := make([]byte, 16)
347 out2 := make([]byte, 16)
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100348
Conrado P. L. Gouvea22d7a772019-04-19 13:04:53 -0300349 // Test for sizes smaller and larger than block size.
350 for _, size := range []int{0x1, 0x100} {
351 in := sequentialBytes(size)
352 for _, v := range testShakes {
353 h1 := v.constructor(nil, []byte{0x01})
354 h1.Write([]byte{0x01})
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100355
Conrado P. L. Gouvea22d7a772019-04-19 13:04:53 -0300356 h2 := h1.Clone()
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100357
Conrado P. L. Gouvea22d7a772019-04-19 13:04:53 -0300358 h1.Write(in)
359 h1.Read(out1)
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100360
Conrado P. L. Gouvea22d7a772019-04-19 13:04:53 -0300361 h2.Write(in)
362 h2.Read(out2)
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100363
Conrado P. L. Gouvea22d7a772019-04-19 13:04:53 -0300364 if !bytes.Equal(out1, out2) {
365 t.Error("\nExpected:\n", hex.EncodeToString(out1), "\ngot:\n", hex.EncodeToString(out2))
366 }
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100367 }
368 }
369}
370
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700371// BenchmarkPermutationFunction measures the speed of the permutation function
372// with no input data.
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400373func BenchmarkPermutationFunction(b *testing.B) {
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700374 b.SetBytes(int64(200))
375 var lanes [25]uint64
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400376 for i := 0; i < b.N; i++ {
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700377 keccakF1600(&lanes)
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400378 }
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400379}
380
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800381// benchmarkHash tests the speed to hash num buffers of buflen each.
382func benchmarkHash(b *testing.B, h hash.Hash, size, num int) {
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400383 b.StopTimer()
384 h.Reset()
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400385 data := sequentialBytes(size)
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800386 b.SetBytes(int64(size * num))
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400387 b.StartTimer()
388
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700389 var state []byte
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400390 for i := 0; i < b.N; i++ {
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800391 for j := 0; j < num; j++ {
392 h.Write(data)
393 }
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700394 state = h.Sum(state[:0])
Joseph Bonneau0bc0bcc2013-03-22 14:59:59 -0400395 }
396 b.StopTimer()
397 h.Reset()
398}
399
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800400// benchmarkShake is specialized to the Shake instances, which don't
401// require a copy on reading output.
402func benchmarkShake(b *testing.B, h ShakeHash, size, num int) {
403 b.StopTimer()
404 h.Reset()
405 data := sequentialBytes(size)
406 d := make([]byte, 32)
David Leon Gil1b32d8b2014-09-03 12:04:00 -0700407
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800408 b.SetBytes(int64(size * num))
409 b.StartTimer()
410
411 for i := 0; i < b.N; i++ {
412 h.Reset()
413 for j := 0; j < num; j++ {
414 h.Write(data)
415 }
416 h.Read(d)
417 }
418}
419
420func BenchmarkSha3_512_MTU(b *testing.B) { benchmarkHash(b, New512(), 1350, 1) }
421func BenchmarkSha3_384_MTU(b *testing.B) { benchmarkHash(b, New384(), 1350, 1) }
422func BenchmarkSha3_256_MTU(b *testing.B) { benchmarkHash(b, New256(), 1350, 1) }
423func BenchmarkSha3_224_MTU(b *testing.B) { benchmarkHash(b, New224(), 1350, 1) }
424
425func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 1350, 1) }
426func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) }
427func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) }
428func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) }
429
430func BenchmarkSha3_512_1MiB(b *testing.B) { benchmarkHash(b, New512(), 1024, 1024) }
431
432func Example_sum() {
433 buf := []byte("some data to hash")
434 // A hash needs to be 64 bytes long to have 256-bit collision resistance.
435 h := make([]byte, 64)
436 // Compute a 64-byte hash of buf and put it in h.
437 ShakeSum256(h, buf)
sbuss7f7c0c22017-07-15 10:57:27 -0700438 fmt.Printf("%x\n", h)
439 // Output: 0f65fe41fc353e52c55667bb9e2b27bfcc8476f2c413e9437d272ee3194a4e3146d05ec04a25d16b8f577c19b82d16b1424c3e022e783d2b4da98de3658d363d
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800440}
441
442func Example_mac() {
443 k := []byte("this is a secret key; you should generate a strong random key that's at least 32 bytes long")
444 buf := []byte("and this is some data to authenticate")
445 // A MAC with 32 bytes of output has 256-bit security strength -- if you use at least a 32-byte-long key.
446 h := make([]byte, 32)
447 d := NewShake256()
448 // Write the key into the hash.
449 d.Write(k)
450 // Now write the data.
451 d.Write(buf)
452 // Read 32 bytes of output from the hash into h.
453 d.Read(h)
sbuss7f7c0c22017-07-15 10:57:27 -0700454 fmt.Printf("%x\n", h)
455 // Output: 78de2974bd2711d5549ffd32b753ef0f5fa80a0db2556db60f0987eb8a9218ff
David Leon Gil4ed45ec2014-12-26 19:04:10 -0800456}
Kris Kwiatkowskif416eba2018-05-02 17:52:23 +0100457
458func ExampleNewCShake256() {
459 out := make([]byte, 32)
460 msg := []byte("The quick brown fox jumps over the lazy dog")
461
462 // Example 1: Simple cshake
463 c1 := NewCShake256([]byte("NAME"), []byte("Partition1"))
464 c1.Write(msg)
465 c1.Read(out)
466 fmt.Println(hex.EncodeToString(out))
467
468 // Example 2: Different customization string produces different digest
469 c1 = NewCShake256([]byte("NAME"), []byte("Partition2"))
470 c1.Write(msg)
471 c1.Read(out)
472 fmt.Println(hex.EncodeToString(out))
473
474 // Example 3: Longer output length produces longer digest
475 out = make([]byte, 64)
476 c1 = NewCShake256([]byte("NAME"), []byte("Partition1"))
477 c1.Write(msg)
478 c1.Read(out)
479 fmt.Println(hex.EncodeToString(out))
480
481 // Example 4: Next read produces different result
482 c1.Read(out)
483 fmt.Println(hex.EncodeToString(out))
484
485 // Output:
486 //a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b
487 //a8db03e71f3e4da5c4eee9d28333cdd355f51cef3c567e59be5beb4ecdbb28f0
488 //a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
489 //85e73a72228d08b46515553ca3a29d47df3047e5d84b12d6c2c63e579f4fd1105716b7838e92e981863907f434bfd4443c9e56ea09da998d2f9b47db71988109
490}