Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(831)

Delta Between Two Patch Sets: sha3/sha3_test.go

Issue 7760044: go.crypto/sha3: new package
Left Patch Set: Created 11 years ago
Right Patch Set: diff -r 8dd5caec1eae https://code.google.com/p/go.crypto/ Created 11 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « sha3/sha3.go ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package sha3
6
7 // These tests are a subset of those provided by the Keccak web site(http://kecc ak.noekeon.org/).
8
9 import (
10 "bytes"
11 "encoding/hex"
12 "fmt"
13 "hash"
14 "strings"
15 "testing"
16 )
17
18 // testDigests maintains a digest state of each standard type.
19 var testDigests = map[string]*digest{
20 "Keccak224": {outputSize: 224 / 8, capacity: 2 * 224 / 8},
21 "Keccak256": {outputSize: 256 / 8, capacity: 2 * 256 / 8},
22 "Keccak384": {outputSize: 384 / 8, capacity: 2 * 384 / 8},
23 "Keccak512": {outputSize: 512 / 8, capacity: 2 * 512 / 8},
24 }
25
26 // testVector represents a test input and expected outputs from multiple algorit hm variants.
27 type testVector struct {
28 desc string
29 input []byte
30 repeat int // input will be concatenated the input this many times.
31 want map[string]string
32 }
33
34 // decodeHex converts an hex-encoded string into a raw byte string.
35 func decodeHex(s string) []byte {
36 b, err := hex.DecodeString(s)
37 if err != nil {
38 panic(err)
39 }
40 return b
41 }
42
43 // shortTestVectors stores a series of short testVectors.
44 // Inputs of 8, 248, and 264 bits from http://keccak.noekeon.org/ are included b elow.
45 // The standard defines additional test inputs of all sizes between 0 and 2047 b its.
46 // Because the current implementation can only handle an integral number of byte s,
47 // most of the standard test inputs can't be used.
48 var shortKeccakTestVectors = []testVector{
49 {
50 desc: "short-8b",
51 input: decodeHex("CC"),
52 repeat: 1,
53 want: map[string]string{
54 "Keccak224": "A9CAB59EB40A10B246290F2D6086E32E3689FAF1D2 6B470C899F2802",
55 "Keccak256": "EEAD6DBFC7340A56CAEDC044696A168870549A6A7F 6F56961E84A54BD9970B8A",
56 "Keccak384": "1B84E62A46E5A201861754AF5DC95C4A1A69CAF4A7 96AE405680161E29572641F5FA1E8641D7958336EE7B11C58F73E9",
57 "Keccak512": "8630C13CBD066EA74BBE7FE468FEC1DEE10EDC1254 FB4C1B7C5FD69B646E44160B8CE01D05A0908CA790DFB080F4B513BC3B6225ECE7A810371441A5AC 666EB9",
58 },
59 },
60 {
61 desc: "short-248b",
62 input: decodeHex("84FB51B517DF6C5ACCB5D022F8F28DA09B10232D42320 FFC32DBECC3835B29"),
63 repeat: 1,
64 want: map[string]string{
65 "Keccak224": "81AF3A7A5BD4C1F948D6AF4B96F93C3B0CF9C0E7A6 DA6FCD71EEC7F6",
66 "Keccak256": "D477FB02CAAA95B3280EC8EE882C29D9E8A654B21E F178E0F97571BF9D4D3C1C",
67 "Keccak384": "503DCAA4ADDA5A9420B2E436DD62D9AB2E0254295C 2982EF67FCE40F117A2400AB492F7BD5D133C6EC2232268BC27B42",
68 "Keccak512": "9D8098D8D6EDBBAA2BCFC6FB2F89C3EAC67FEC25CD FE75AA7BD570A648E8C8945FF2EC280F6DCF73386109155C5BBC444C707BB42EAB873F5F7476657B 1BC1A8",
69 },
70 },
71 {
72 desc: "short-264b",
73 input: decodeHex("DE8F1B3FAA4B7040ED4563C3B8E598253178E87E4D0DF 75E4FF2F2DEDD5A0BE046"),
74 repeat: 1,
75 want: map[string]string{
76 "Keccak224": "F217812E362EC64D4DC5EACFABC165184BFA456E5C 32C2C7900253D0",
77 "Keccak256": "E78C421E6213AFF8DE1F025759A4F2C943DB62BBDE 359C8737E19B3776ED2DD2",
78 "Keccak384": "CF38764973F1EC1C34B5433AE75A3AAD1AAEF6AB19 7850C56C8617BCD6A882F6666883AC17B2DCCDBAA647075D0972B5",
79 "Keccak512": "9A7688E31AAF40C15575FC58C6B39267AAD3722E69 6E518A9945CF7F7C0FEA84CB3CB2E9F0384A6B5DC671ADE7FB4D2B27011173F3EEEAF17CB451CF26 542031",
80 },
81 },
82 }
83
84 // longTestVectors stores a single 64 MiB long testVector.
85 // This is a prefix of the "very long" 1 GiB test vector defined in the Keccak s tandard at
86 // http://keccak.noekeon.org/. We truncate here to keep the running time on the order of seconds.
87 var longKeccakTestVectors = []testVector{
88 {
89 desc: "long-64MiB",
90 input: []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklm ghijklmnhijklmno"),
91 repeat: 1024 * 1024,
92 want: map[string]string{
93 "Keccak224": "50E35E40980FEEFF1EA490957B0E970257F75EA0D4 10EE0F0B8A7A58",
94 "Keccak256": "5015A4935F0B51E091C6550A94DCD262C08998232C CAA22E7F0756DEAC0DC0D0",
95 "Keccak384": "7907A8D0FAA7BC6A90FE14C6C958C956A0877E7514 55D8F13ACDB96F144B5896E716C06EC0CB56557A94EF5C3355F6F3",
96 "Keccak512": "3EC327D6759F769DEB74E80CA70C831BC29CAB048A 4BF4190E4A1DD5C6507CF2B4B58937FDE81D36014E7DFE1B1DD8B0F27CB7614F9A645FEC114F1DAA EFC056",
97 },
98 },
99 }
100
101 // TestKeccakVectors checks that correct output is produced for a set of known t estVectors.
102 func TestKeccakVectors(t *testing.T) {
103 testCases := append([]testVector{}, shortKeccakTestVectors...)
104 if !testing.Short() {
105 testCases = append(testCases, longKeccakTestVectors...)
106 }
107 for _, tc := range testCases {
108 for alg, want := range tc.want {
109 testDigests[alg].Reset()
110 // Write input data each digests, based on the test spec ification t.
111 for i := 0; i < tc.repeat; i++ {
112 testDigests[alg].Write(tc.input)
113 }
114 // Verify that each algorithm version produced the expec ted output.
115 got := strings.ToUpper(hex.EncodeToString(testDigests[al g].Sum(nil)))
116 if got != want {
117 t.Errorf("%s, alg=%s\ngot %q, want %q", tc.desc, alg, got, want)
118 }
119 }
120 }
121 }
122
123 // dumpState is a debugging function to pretty-print the internal state of the h ash.
124 func (d *digest) dumpState() {
125 fmt.Printf("SHA3 hash, %d B output, %d B capacity (%d B rate)\n", d.outp utSize, d.capacity, d.rate())
126 fmt.Printf("Internal state after absorbing %d B:\n", d.absorbed)
127
128 for x := 0; x < sliceSize; x++ {
129 for y := 0; y < sliceSize; y++ {
130 fmt.Printf("%v, ", d.a[x*sliceSize+y])
131 }
132 fmt.Println("")
133 }
134 }
135
136 // TestUnalignedWrite tests that writing data in an arbitrary pattern with small input buffers.
137 func TestUnalignedWrite(t *testing.T) {
138 buf := sequentialBytes(0x10000)
139 for alg, d := range testDigests {
140 d.Reset()
141 d.Write(buf)
142 want := d.Sum(nil)
143 d.Reset()
144 for i := 0; i < len(buf); {
145 // Cycle through offsets which make a 137 byte sequence.
146 // Because 137 is prime this sequence should exercise al l corner cases.
147 offsets := [17]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 , 13, 14, 15, 16, 1}
148 for _, j := range offsets {
149 j = minInt(j, len(buf)-i)
150 d.Write(buf[i : i+j])
151 i += j
152 }
153 }
154 got := d.Sum(nil)
155 if !bytes.Equal(got, want) {
156 t.Errorf("Unaligned writes, alg=%s\ngot %q, want %q", al g, got, want)
157 }
158 }
159 }
160
161 // sequentialBytes produces a buffer of size consecutive bytes 0x00, 0x01, ..., used for testing.
162 func sequentialBytes(size int) []byte {
163 result := make([]byte, size)
164 for i := range result {
165 result[i] = byte(i)
166 }
167 return result
168 }
169
170 // benchmarkBlockWrite tests the speed of writing data and never calling the per mutation function.
171 func benchmarkBlockWrite(b *testing.B, d *digest) {
172 b.StopTimer()
173 d.Reset()
174 // Write all but the last byte of a block, to ensure that the permutatio n is not called.
175 data := sequentialBytes(d.rate() - 1)
176 b.SetBytes(int64(len(data)))
177 b.StartTimer()
178 for i := 0; i < b.N; i++ {
179 d.absorbed = 0 // Reset absorbed to avoid ever calling the permu tation function
180 d.Write(data)
181 }
182 b.StopTimer()
183 d.Reset()
184 }
185
186 // BenchmarkPermutationFunction measures the speed of the permutation function w ith no input data.
187 func BenchmarkPermutationFunction(b *testing.B) {
188 b.StopTimer()
189 d := testDigests["Keccak512"]
190 d.Reset()
191 b.SetBytes(int64(stateSize))
192 b.StartTimer()
193 for i := 0; i < b.N; i++ {
194 d.keccakF()
195 }
196 b.StopTimer()
197 d.Reset()
198 }
199
200 // BenchmarkSingleByteWrite tests the latency from writing a single byte
201 func BenchmarkSingleByteWrite(b *testing.B) {
202 b.StopTimer()
203 d := testDigests["Keccak512"]
204 d.Reset()
205 data := sequentialBytes(1) //1 byte buffer
206 b.SetBytes(int64(d.rate()) - 1)
207 b.StartTimer()
208 for i := 0; i < b.N; i++ {
209 d.absorbed = 0 // Reset absorbed to avoid ever calling the permu tation function
210
211 // Write all but the last byte of a block, one byte at a time.
212 for j := 0; j < d.rate()-1; j++ {
213 d.Write(data)
214 }
215 }
216 b.StopTimer()
217 d.Reset()
218 }
219
220 // BenchmarkSingleByteX measures the block write speed for each size of the dige st.
221 func BenchmarkBlockWrite512(b *testing.B) { benchmarkBlockWrite(b, testDigests[" Keccak512"]) }
222 func BenchmarkBlockWrite384(b *testing.B) { benchmarkBlockWrite(b, testDigests[" Keccak384"]) }
223 func BenchmarkBlockWrite256(b *testing.B) { benchmarkBlockWrite(b, testDigests[" Keccak256"]) }
224 func BenchmarkBlockWrite224(b *testing.B) { benchmarkBlockWrite(b, testDigests[" Keccak224"]) }
225
226 // benchmarkBulkHash tests the speed to hash a 16 KiB buffer.
227 func benchmarkBulkHash(b *testing.B, h hash.Hash) {
228 b.StopTimer()
229 h.Reset()
230 size := 1 << 14
231 data := sequentialBytes(size)
232 b.SetBytes(int64(size))
233 b.StartTimer()
234
235 for i := 0; i < b.N; i++ {
236 h.Write(data)
237 h.Sum(nil)
238 }
239 b.StopTimer()
240 h.Reset()
241 }
242
243 // benchmarkBulkKeccakX test the speed to hash a 16 KiB buffer by calling benchm arkBulkHash.
244 func BenchmarkBulkKeccak512(b *testing.B) { benchmarkBulkHash(b, NewKeccak512()) }
245 func BenchmarkBulkKeccak384(b *testing.B) { benchmarkBulkHash(b, NewKeccak384()) }
246 func BenchmarkBulkKeccak256(b *testing.B) { benchmarkBulkHash(b, NewKeccak256()) }
247 func BenchmarkBulkKeccak224(b *testing.B) { benchmarkBulkHash(b, NewKeccak224()) }
LEFTRIGHT
« sha3/sha3.go ('k') | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b