diff --git a/keccak_asm.go b/keccak_asm.go index 37ce284..fc22b4f 100644 --- a/keccak_asm.go +++ b/keccak_asm.go @@ -36,6 +36,15 @@ func (s *sponge) Write(p []byte) (int, error) { panic("keccak: Write after Read") } n := len(p) + if n == 1 { + s.buf[s.absorbed] = p[0] + s.absorbed++ + if s.absorbed == rate { + xorAndPermute(&s.state, &s.buf[0]) + s.absorbed = 0 + } + return 1, nil + } if s.absorbed > 0 { x := copy(s.buf[s.absorbed:rate], p) s.absorbed += x diff --git a/keccak_write_bench_test.go b/keccak_write_bench_test.go new file mode 100644 index 0000000..7304e31 --- /dev/null +++ b/keccak_write_bench_test.go @@ -0,0 +1,23 @@ +package keccak + +import ( + "strconv" + "testing" +) + +func BenchmarkHasherOneByteWrites(b *testing.B) { + for _, size := range []int{32, 128, 256} { + b.Run(strconv.Itoa(size), func(b *testing.B) { + data := make([]byte, size) + b.SetBytes(int64(size)) + b.ReportAllocs() + for b.Loop() { + var h Hasher + for i := range data { + h.Write(data[i : i+1]) + } + h.Sum256() + } + }) + } +}