@@ -27,14 +27,6 @@ const (
2727 katFilename = "testdata/keccakKats.json.deflate"
2828)
2929
30- // Internal-use instances of SHAKE used to test against KATs.
31- func newHashShake128 () hash.Hash {
32- return & state {rate : 168 , dsbyte : 0x1f , outputLen : 512 }
33- }
34- func newHashShake256 () hash.Hash {
35- return & state {rate : 136 , dsbyte : 0x1f , outputLen : 512 }
36- }
37-
3830// testDigests contains functions returning hash.Hash instances
3931// with output-length equal to the KAT length for SHA-3, Keccak
4032// and SHAKE instances.
@@ -45,15 +37,20 @@ var testDigests = map[string]func() hash.Hash{
4537 "SHA3-512" : New512 ,
4638 "Keccak-256" : NewLegacyKeccak256 ,
4739 "Keccak-512" : NewLegacyKeccak512 ,
48- "SHAKE128" : newHashShake128 ,
49- "SHAKE256" : newHashShake256 ,
5040}
5141
52- // testShakes contains functions that return ShakeHash instances for
53- // testing the ShakeHash-specific interface.
54- var testShakes = map [string ]func () ShakeHash {
55- "SHAKE128" : NewShake128 ,
56- "SHAKE256" : NewShake256 ,
42+ // testShakes contains functions that return sha3.ShakeHash instances for
43+ // with output-length equal to the KAT length.
44+ var testShakes = map [string ]struct {
45+ constructor func (N []byte , S []byte ) ShakeHash
46+ defAlgoName string
47+ defCustomStr string
48+ }{
49+ // NewCShake without customization produces same result as SHAKE
50+ "SHAKE128" : {NewCShake128 , "" , "" },
51+ "SHAKE256" : {NewCShake256 , "" , "" },
52+ "cSHAKE128" : {NewCShake128 , "CSHAKE128" , "CustomStrign" },
53+ "cSHAKE256" : {NewCShake256 , "CSHAKE256" , "CustomStrign" },
5754}
5855
5956// decodeHex converts a hex-encoded string into a raw byte string.
@@ -71,6 +68,10 @@ type KeccakKats struct {
7168 Digest string `json:"digest"`
7269 Length int64 `json:"length"`
7370 Message string `json:"message"`
71+
72+ // Defined only for cSHAKE
73+ N string `json:"N"`
74+ S string `json:"S"`
7475 }
7576}
7677
@@ -103,10 +104,9 @@ func TestKeccakKats(t *testing.T) {
103104 t .Errorf ("error decoding KATs: %s" , err )
104105 }
105106
106- // Do the KATs.
107- for functionName , kats := range katSet .Kats {
108- d := testDigests [functionName ]()
109- for _ , kat := range kats {
107+ for algo , function := range testDigests {
108+ d := function ()
109+ for _ , kat := range katSet .Kats [algo ] {
110110 d .Reset ()
111111 in , err := hex .DecodeString (kat .Message )
112112 if err != nil {
@@ -115,8 +115,39 @@ func TestKeccakKats(t *testing.T) {
115115 d .Write (in [:kat .Length / 8 ])
116116 got := strings .ToUpper (hex .EncodeToString (d .Sum (nil )))
117117 if got != kat .Digest {
118- t .Errorf ("function=%s, implementation=%s, length=%d\n message:\n %s\n got:\n %s\n wanted:\n %s" ,
119- functionName , impl , kat .Length , kat .Message , got , kat .Digest )
118+ t .Errorf ("function=%s, implementation=%s, length=%d\n message:\n %s\n got:\n %s\n wanted:\n %s" ,
119+ algo , impl , kat .Length , kat .Message , got , kat .Digest )
120+ t .Logf ("wanted %+v" , kat )
121+ t .FailNow ()
122+ }
123+ continue
124+ }
125+ }
126+
127+ for algo , v := range testShakes {
128+ for _ , kat := range katSet .Kats [algo ] {
129+ N , err := hex .DecodeString (kat .N )
130+ if err != nil {
131+ t .Errorf ("error decoding KAT: %s" , err )
132+ }
133+
134+ S , err := hex .DecodeString (kat .S )
135+ if err != nil {
136+ t .Errorf ("error decoding KAT: %s" , err )
137+ }
138+ d := v .constructor (N , S )
139+ in , err := hex .DecodeString (kat .Message )
140+ if err != nil {
141+ t .Errorf ("error decoding KAT: %s" , err )
142+ }
143+
144+ d .Write (in [:kat .Length / 8 ])
145+ out := make ([]byte , len (kat .Digest )/ 2 )
146+ d .Read (out )
147+ got := strings .ToUpper (hex .EncodeToString (out ))
148+ if got != kat .Digest {
149+ t .Errorf ("function=%s, implementation=%s, length=%d N:%s\n S:%s\n message:\n %s \n got:\n %s\n wanted:\n %s" ,
150+ algo , impl , kat .Length , kat .N , kat .S , kat .Message , got , kat .Digest )
120151 t .Logf ("wanted %+v" , kat )
121152 t .FailNow ()
122153 }
@@ -184,6 +215,34 @@ func TestUnalignedWrite(t *testing.T) {
184215 t .Errorf ("Unaligned writes, implementation=%s, alg=%s\n got %q, want %q" , impl , alg , got , want )
185216 }
186217 }
218+
219+ // Same for SHAKE
220+ for alg , df := range testShakes {
221+ want := make ([]byte , 16 )
222+ got := make ([]byte , 16 )
223+ d := df .constructor ([]byte (df .defAlgoName ), []byte (df .defCustomStr ))
224+
225+ d .Reset ()
226+ d .Write (buf )
227+ d .Read (want )
228+ d .Reset ()
229+ for i := 0 ; i < len (buf ); {
230+ // Cycle through offsets which make a 137 byte sequence.
231+ // Because 137 is prime this sequence should exercise all corner cases.
232+ offsets := [17 ]int {1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 1 }
233+ for _ , j := range offsets {
234+ if v := len (buf ) - i ; v < j {
235+ j = v
236+ }
237+ d .Write (buf [i : i + j ])
238+ i += j
239+ }
240+ }
241+ d .Read (got )
242+ if ! bytes .Equal (got , want ) {
243+ t .Errorf ("Unaligned writes, implementation=%s, alg=%s\n got %q, want %q" , impl , alg , got , want )
244+ }
245+ }
187246 })
188247}
189248
@@ -225,13 +284,13 @@ func TestAppendNoRealloc(t *testing.T) {
225284// the same output as repeatedly squeezing the instance.
226285func TestSqueezing (t * testing.T ) {
227286 testUnalignedAndGeneric (t , func (impl string ) {
228- for functionName , newShakeHash := range testShakes {
229- d0 := newShakeHash ( )
287+ for algo , v := range testShakes {
288+ d0 := v . constructor ([] byte ( v . defAlgoName ), [] byte ( v . defCustomStr ) )
230289 d0 .Write ([]byte (testString ))
231290 ref := make ([]byte , 32 )
232291 d0 .Read (ref )
233292
234- d1 := newShakeHash ( )
293+ d1 := v . constructor ([] byte ( v . defAlgoName ), [] byte ( v . defCustomStr ) )
235294 d1 .Write ([]byte (testString ))
236295 var multiple []byte
237296 for range ref {
@@ -240,7 +299,7 @@ func TestSqueezing(t *testing.T) {
240299 multiple = append (multiple , one ... )
241300 }
242301 if ! bytes .Equal (ref , multiple ) {
243- t .Errorf ("%s (%s): squeezing %d bytes one at a time failed" , functionName , impl , len (ref ))
302+ t .Errorf ("%s (%s): squeezing %d bytes one at a time failed" , algo , impl , len (ref ))
244303 }
245304 }
246305 })
@@ -255,6 +314,50 @@ func sequentialBytes(size int) []byte {
255314 return result
256315}
257316
317+ func TestReset (t * testing.T ) {
318+ out1 := make ([]byte , 32 )
319+ out2 := make ([]byte , 32 )
320+
321+ for _ , v := range testShakes {
322+ // Calculate hash for the first time
323+ c := v .constructor (nil , []byte {0x99 , 0x98 })
324+ c .Write (sequentialBytes (0x100 ))
325+ c .Read (out1 )
326+
327+ // Calculate hash again
328+ c .Reset ()
329+ c .Write (sequentialBytes (0x100 ))
330+ c .Read (out2 )
331+
332+ if ! bytes .Equal (out1 , out2 ) {
333+ t .Error ("\n Expected:\n " , out1 , "\n got:\n " , out2 )
334+ }
335+ }
336+ }
337+
338+ func TestClone (t * testing.T ) {
339+ out1 := make ([]byte , 16 )
340+ out2 := make ([]byte , 16 )
341+ in := sequentialBytes (0x100 )
342+
343+ for _ , v := range testShakes {
344+ h1 := v .constructor (nil , []byte {0x01 })
345+ h1 .Write ([]byte {0x01 })
346+
347+ h2 := h1 .Clone ()
348+
349+ h1 .Write (in )
350+ h1 .Read (out1 )
351+
352+ h2 .Write (in )
353+ h2 .Read (out2 )
354+
355+ if ! bytes .Equal (out1 , out2 ) {
356+ t .Error ("\n Expected:\n " , hex .EncodeToString (out1 ), "\n got:\n " , hex .EncodeToString (out2 ))
357+ }
358+ }
359+ }
360+
258361// BenchmarkPermutationFunction measures the speed of the permutation function
259362// with no input data.
260363func BenchmarkPermutationFunction (b * testing.B ) {
@@ -341,3 +444,37 @@ func Example_mac() {
341444 fmt .Printf ("%x\n " , h )
342445 // Output: 78de2974bd2711d5549ffd32b753ef0f5fa80a0db2556db60f0987eb8a9218ff
343446}
447+
448+ func ExampleNewCShake256 () {
449+ out := make ([]byte , 32 )
450+ msg := []byte ("The quick brown fox jumps over the lazy dog" )
451+
452+ // Example 1: Simple cshake
453+ c1 := NewCShake256 ([]byte ("NAME" ), []byte ("Partition1" ))
454+ c1 .Write (msg )
455+ c1 .Read (out )
456+ fmt .Println (hex .EncodeToString (out ))
457+
458+ // Example 2: Different customization string produces different digest
459+ c1 = NewCShake256 ([]byte ("NAME" ), []byte ("Partition2" ))
460+ c1 .Write (msg )
461+ c1 .Read (out )
462+ fmt .Println (hex .EncodeToString (out ))
463+
464+ // Example 3: Longer output length produces longer digest
465+ out = make ([]byte , 64 )
466+ c1 = NewCShake256 ([]byte ("NAME" ), []byte ("Partition1" ))
467+ c1 .Write (msg )
468+ c1 .Read (out )
469+ fmt .Println (hex .EncodeToString (out ))
470+
471+ // Example 4: Next read produces different result
472+ c1 .Read (out )
473+ fmt .Println (hex .EncodeToString (out ))
474+
475+ // Output:
476+ //a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b
477+ //a8db03e71f3e4da5c4eee9d28333cdd355f51cef3c567e59be5beb4ecdbb28f0
478+ //a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
479+ //85e73a72228d08b46515553ca3a29d47df3047e5d84b12d6c2c63e579f4fd1105716b7838e92e981863907f434bfd4443c9e56ea09da998d2f9b47db71988109
480+ }
0 commit comments