mirror of
https://github.com/henrydcase/nobs.git
synced 2024-11-22 23:28:57 +00:00
SHAKE: Don't use function pointers (#20)
* xorIn and copyOut function pointers cause input and output data to be moved to heap. This degrades performance of calling code. * This change removes usage of those function pointers. We will always use unaligned implementation as it's faster (but may crash on some systems) * Benchmark compares generic vs unaligned xorIn and copyOut benchmark old ns/op new ns/op delta BenchmarkPermutationFunction-4 463 815 +76.03% BenchmarkShake128_MTU-4 4443 8180 +84.11% BenchmarkShake256_MTU-4 4739 9060 +91.18% BenchmarkShake256_16x-4 71886 132629 +84.50% BenchmarkShake256_1MiB-4 3695138 6649012 +79.94% BenchmarkCShake128_448_16x-4 21210 24611 +16.03% BenchmarkCShake128_1MiB-4 3009342 3396496 +12.87% BenchmarkCShake256_448_16x-4 26034 27785 +6.73% BenchmarkCShake256_1MiB-4 3654713 3829404 +4.78%
This commit is contained in:
parent
e6439f96ab
commit
49bf0db8fd
@ -472,19 +472,3 @@ func ExampleCShake256() {
|
|||||||
//a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
|
//a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
|
||||||
//85e73a72228d08b46515553ca3a29d47df3047e5d84b12d6c2c63e579f4fd1105716b7838e92e981863907f434bfd4443c9e56ea09da998d2f9b47db71988109
|
//85e73a72228d08b46515553ca3a29d47df3047e5d84b12d6c2c63e579f4fd1105716b7838e92e981863907f434bfd4443c9e56ea09da998d2f9b47db71988109
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestXXX(t *testing.T) {
|
|
||||||
var out1, out2 [32]byte
|
|
||||||
h := NewCShake256([]byte("CSHAKE256"), []byte("CustomStrign"))
|
|
||||||
|
|
||||||
h.Write([]byte{0x1, 0x2, 0x3})
|
|
||||||
h.Read(out1[:])
|
|
||||||
|
|
||||||
h.Reset()
|
|
||||||
|
|
||||||
h.Write([]byte{0x1, 0x2, 0x3})
|
|
||||||
h.Read(out2[:])
|
|
||||||
|
|
||||||
fmt.Println(out1)
|
|
||||||
fmt.Println(out2)
|
|
||||||
}
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
// Copyright 2017 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//+build gccgo appengine !s390x
|
|
||||||
|
|
||||||
package shake
|
|
||||||
|
|
||||||
import (
|
|
||||||
"hash"
|
|
||||||
)
|
|
||||||
|
|
||||||
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new224Asm() hash.Hash { return nil }
|
|
||||||
|
|
||||||
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new256Asm() hash.Hash { return nil }
|
|
||||||
|
|
||||||
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new384Asm() hash.Hash { return nil }
|
|
||||||
|
|
||||||
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
|
||||||
// otherwise it returns nil.
|
|
||||||
func new512Asm() hash.Hash { return nil }
|
|
@ -83,7 +83,7 @@ func (d *state) permute() {
|
|||||||
case spongeAbsorbing:
|
case spongeAbsorbing:
|
||||||
// If we're absorbing, we need to xor the input into the state
|
// If we're absorbing, we need to xor the input into the state
|
||||||
// before applying the permutation.
|
// before applying the permutation.
|
||||||
xorIn(d, d.buf)
|
xorInUnaligned(d, d.buf)
|
||||||
d.buf = d.storage[:0]
|
d.buf = d.storage[:0]
|
||||||
keccakF1600(&d.a)
|
keccakF1600(&d.a)
|
||||||
case spongeSqueezing:
|
case spongeSqueezing:
|
||||||
@ -91,7 +91,7 @@ func (d *state) permute() {
|
|||||||
// copying more output.
|
// copying more output.
|
||||||
keccakF1600(&d.a)
|
keccakF1600(&d.a)
|
||||||
d.buf = d.storage[:d.rate]
|
d.buf = d.storage[:d.rate]
|
||||||
copyOut(d, d.buf)
|
copyOutUnaligned(d, d.buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ func (d *state) padAndPermute(dsbyte byte) {
|
|||||||
d.permute()
|
d.permute()
|
||||||
d.state = spongeSqueezing
|
d.state = spongeSqueezing
|
||||||
d.buf = d.storage[:d.rate]
|
d.buf = d.storage[:d.rate]
|
||||||
copyOut(d, d.buf)
|
copyOutUnaligned(d, d.buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write absorbs more data into the hash's state. It produces an error
|
// Write absorbs more data into the hash's state. It produces an error
|
||||||
@ -136,7 +136,7 @@ func (d *state) Write(p []byte) (written int, err error) {
|
|||||||
for len(p) > 0 {
|
for len(p) > 0 {
|
||||||
if len(d.buf) == 0 && len(p) >= d.rate {
|
if len(d.buf) == 0 && len(p) >= d.rate {
|
||||||
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
|
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
|
||||||
xorIn(d, p[:d.rate])
|
xorInUnaligned(d, p[:d.rate])
|
||||||
p = p[d.rate:]
|
p = p[d.rate:]
|
||||||
keccakF1600(&d.a)
|
keccakF1600(&d.a)
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,6 +22,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
xorIn = xorInUnaligned
|
||||||
|
copyOut = copyOutUnaligned
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
testString = "brekeccakkeccak koax koax"
|
testString = "brekeccakkeccak koax koax"
|
||||||
katFilename = "testdata/keccakKats.json.deflate"
|
katFilename = "testdata/keccakKats.json.deflate"
|
||||||
@ -68,7 +73,7 @@ func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) {
|
|||||||
xorIn, copyOut = xorInGeneric, copyOutGeneric
|
xorIn, copyOut = xorInGeneric, copyOutGeneric
|
||||||
testf("generic")
|
testf("generic")
|
||||||
if xorImplementationUnaligned != "generic" {
|
if xorImplementationUnaligned != "generic" {
|
||||||
xorIn, copyOut = xorInUnaligned, copyOutUnaligned
|
xorIn, copyOut = xorInGeneric, copyOutGeneric
|
||||||
testf("unaligned")
|
testf("unaligned")
|
||||||
}
|
}
|
||||||
xorIn, copyOut = xorInOrig, copyOutOrig
|
xorIn, copyOut = xorInOrig, copyOutOrig
|
||||||
@ -336,7 +341,7 @@ func benchmarkShake(b *testing.B, h *CShake, size, num int) {
|
|||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
h.Reset()
|
h.Reset()
|
||||||
data := sequentialBytes(size)
|
data := sequentialBytes(size)
|
||||||
d := make([]byte, 32)
|
var d [32]byte
|
||||||
|
|
||||||
b.SetBytes(int64(size * num))
|
b.SetBytes(int64(size * num))
|
||||||
b.StartTimer()
|
b.StartTimer()
|
||||||
@ -346,7 +351,7 @@ func benchmarkShake(b *testing.B, h *CShake, size, num int) {
|
|||||||
for j := 0; j < num; j++ {
|
for j := 0; j < num; j++ {
|
||||||
h.Write(data)
|
h.Write(data)
|
||||||
}
|
}
|
||||||
h.Read(d)
|
h.Read(d[:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,6 +359,18 @@ func BenchmarkShake128_MTU(b *testing.B) { benchmarkShake(b, NewShake128(), 135
|
|||||||
func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) }
|
func BenchmarkShake256_MTU(b *testing.B) { benchmarkShake(b, NewShake256(), 1350, 1) }
|
||||||
func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) }
|
func BenchmarkShake256_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 1024) }
|
||||||
func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) }
|
func BenchmarkShake256_1MiB(b *testing.B) { benchmarkShake(b, NewShake256(), 1024, 1024) }
|
||||||
|
func BenchmarkCShake128_448_16x(b *testing.B) {
|
||||||
|
benchmarkShake(b, NewCShake128([]byte("ABC"), []byte("DEF")), 448, 16)
|
||||||
|
}
|
||||||
|
func BenchmarkCShake128_1MiB(b *testing.B) {
|
||||||
|
benchmarkShake(b, NewCShake128([]byte("ABC"), []byte("DEF")), 1024, 1024)
|
||||||
|
}
|
||||||
|
func BenchmarkCShake256_448_16x(b *testing.B) {
|
||||||
|
benchmarkShake(b, NewCShake256([]byte("ABC"), []byte("DEF")), 448, 16)
|
||||||
|
}
|
||||||
|
func BenchmarkCShake256_1MiB(b *testing.B) {
|
||||||
|
benchmarkShake(b, NewCShake256([]byte("ABC"), []byte("DEF")), 1024, 1024)
|
||||||
|
}
|
||||||
|
|
||||||
func Example_sum() {
|
func Example_sum() {
|
||||||
buf := []byte("some data to hash")
|
buf := []byte("some data to hash")
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64,!386,!ppc64le appengine
|
|
||||||
|
|
||||||
package shake
|
|
||||||
|
|
||||||
var (
|
|
||||||
xorIn = xorInGeneric
|
|
||||||
copyOut = copyOutGeneric
|
|
||||||
xorInUnaligned = xorInGeneric
|
|
||||||
copyOutUnaligned = copyOutGeneric
|
|
||||||
)
|
|
||||||
|
|
||||||
const xorImplementationUnaligned = "generic"
|
|
@ -26,3 +26,5 @@ func copyOutGeneric(d *state, b []byte) {
|
|||||||
b = b[8:]
|
b = b[8:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const xorImplementationGeneric = "generic"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build amd64 386 ppc64le
|
// +build amd64 arm64 386 ppc64le
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
|
|
||||||
package shake
|
package shake
|
||||||
@ -50,9 +50,4 @@ func copyOutUnaligned(d *state, buf []byte) {
|
|||||||
copy(buf, ab[:])
|
copy(buf, ab[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
xorIn = xorInUnaligned
|
|
||||||
copyOut = copyOutUnaligned
|
|
||||||
)
|
|
||||||
|
|
||||||
const xorImplementationUnaligned = "unaligned"
|
const xorImplementationUnaligned = "unaligned"
|
||||||
|
Loading…
Reference in New Issue
Block a user