1
0
mirror of https://github.com/henrydcase/nobs.git synced 2024-11-25 00:21:29 +00:00
nobs/hash/sm3/sm3.go
Henry Case 820906b7c7
sha3: optimizations and cleanup (#41)
* complate reset of the SHA-3 code. Affects mostly the code in sha3.go
* fixes a bug  which causes SHAKE implementation to crash
* implementation of Read()/Write() avoid unnecessary buffering as much
  as possible
* NOTE: at some point I've done separated implementation for SumXXX,
  functions, but after optimizing implementation of Read/Write/Sum, the
  gain wasn't that big

Current speed on Initial speed on i7-8665U@1.90

BenchmarkPermutationFunction 	 			 1592787	       736 ns/op	 271.90 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x01/SHA-3/224         	   98752	     11630 ns/op	 176.02 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x01/SHA-3/256         	   92508	     12447 ns/op	 164.46 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x01/SHA-3/384         	   76765	     15206 ns/op	 134.62 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x01/SHA-3/512         	   54333	     21932 ns/op	  93.33 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x16/SHA-3/224         	   10000	    102161 ns/op	 160.37 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x16/SHA-3/256         	   10000	    106531 ns/op	 153.80 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x16/SHA-3/384         	    8641	    137272 ns/op	 119.35 MB/s	       0 B/op	       0 allocs/op
BenchmarkSha3Chunk_x16/SHA-3/512         	    6340	    189124 ns/op	  86.63 MB/s	       0 B/op	       0 allocs/op
BenchmarkShake_x01/SHAKE-128             	  167062	      7149 ns/op	 188.83 MB/s	       0 B/op	       0 allocs/op
BenchmarkShake_x01/SHAKE-256             	  151982	      7748 ns/op	 174.24 MB/s	       0 B/op	       0 allocs/op
BenchmarkShake_x16/SHAKE-128             	   12963	     87770 ns/op	 186.67 MB/s	       0 B/op	       0 allocs/op
BenchmarkShake_x16/SHAKE-256             	   10000	    105554 ns/op	 155.22 MB/s	       0 B/op	       0 allocs/op
BenchmarkCShake/cSHAKE-128               	  109148	     10940 ns/op	 187.11 MB/s	       0 B/op	       0 allocs/op
BenchmarkCShake/cSHAKE-256               	   90324	     13211 ns/op	 154.94 MB/s	       0 B/op	       0 allocs/op
PASS
2020-08-29 02:12:49 +01:00

111 lines
2.0 KiB
Go

// Package sm3 implements the SM-3 hash algorithm as defined in "SM3 Hash
// function draft-shen-sm3-hash-01" draft
//
package sm3
import (
"hash"
)
const (
init0 = 0x7380166F
init1 = 0x4914B2B9
init2 = 0x172442D7
init3 = 0xDA8A0600
init4 = 0xA96F30BC
init5 = 0x163138AA
init6 = 0xE38DEE4D
init7 = 0xB0FB0E4E
)
// The size of a SM-3 checksum in bytes.
const Size = 32
// The blocksize of SM-3 in bytes.
const BlockSize int = 64
// digest represents the partial evaluation of a checksum.
type digest struct {
h [8]uint32
len uint64
b [BlockSize]byte
}
func New() hash.Hash {
d := new(digest)
d.Reset()
return d
}
func (d *digest) BlockSize() int { return BlockSize }
func (d *digest) Size() int { return Size }
func (d *digest) Init() { d.Reset() }
func (d *digest) Reset() {
d.h[0] = init0
d.h[1] = init1
d.h[2] = init2
d.h[3] = init3
d.h[4] = init4
d.h[5] = init5
d.h[6] = init6
d.h[7] = init7
d.len = 0
}
func (d *digest) Write(input []byte) (nn int, err error) {
// current possition in the buffer
idx := int(d.len & uint64((d.BlockSize() - 1)))
d.len += uint64(len(input))
if len(input)+idx < d.BlockSize() {
copy(d.b[idx:], input)
return
}
c := d.BlockSize() - idx
copy(d.b[idx:], input[:c])
d.compress(d.b[:], 1)
input = input[c:]
nblocks := int(len(input) / d.BlockSize())
d.compress(input[:], nblocks)
// this eventually could be done in d.compress
copy(d.b[:], input[nblocks*d.BlockSize():])
return len(input), nil
}
func (d *digest) Sum(in []byte) []byte {
var output [32]byte
// Copy context so that caller can keep updating
dc := *d
dc.Write(in)
idx := int(dc.len & uint64(dc.BlockSize()-1))
for i := idx + 1; i < len(dc.b); i++ {
dc.b[i] = 0
}
dc.b[idx] = 0x80
if idx >= 56 {
dc.compress(dc.b[:], 1)
for i := range dc.b {
dc.b[i] = 0
}
}
// add total bits
store64Be(dc.b[56:], dc.len*8)
dc.compress(dc.b[:], 1)
for i := 0; i < Size/4; i++ {
store32Be(output[4*i:], dc.h[i])
}
return output[:]
}