mirror of
https://github.com/henrydcase/nobs.git
synced 2024-11-26 09:01:20 +00:00
PoC on CShakeSum and no-heap initialization
This commit is contained in:
parent
e6439f96ab
commit
4ec6f4b876
@ -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,53 @@ 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 BenchmarkCShake256_1MiB(b *testing.B) {
|
||||||
|
benchmarkShake(b, NewCShake256([]byte("ABC"), nil), 1024, 1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCShakeSum(b *testing.B) {
|
||||||
|
//benchmarkShake(b, NewCShake256([]byte("ABC"), nil), 1024, 1024)
|
||||||
|
data := sequentialBytes(1024)
|
||||||
|
var d [32]byte
|
||||||
|
|
||||||
|
//var c CShake
|
||||||
|
//c.Init(CSHAKE_256, )
|
||||||
|
c := NewCShake256([]byte("ABC"), nil)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
c.CShakeSum(d[:], data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCShakeSum3(b *testing.B) {
|
||||||
|
//benchmarkShake(b, NewCShake256([]byte("ABC"), nil), 1024, 1024)
|
||||||
|
data := sequentialBytes(1024)
|
||||||
|
var d [32]byte
|
||||||
|
|
||||||
|
c := NewCShake256([]byte("ABC"), nil)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
c.Reset()
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
c.Write(data)
|
||||||
|
}
|
||||||
|
c.Read(d[:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCShakeSum4(b *testing.B) {
|
||||||
|
//benchmarkShake(b, NewCShake256([]byte("ABC"), nil), 1024, 1024)
|
||||||
|
data := sequentialBytes(1024)
|
||||||
|
var d [32]byte
|
||||||
|
|
||||||
|
var c CShake //:= NewCShake256([]byte("ABC"), nil)
|
||||||
|
c.Init(CSHAKE_256, []byte("ABC"), nil)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
c.Reset()
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
c.Write(data)
|
||||||
|
}
|
||||||
|
c.Read(d[:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Example_sum() {
|
func Example_sum() {
|
||||||
buf := []byte("some data to hash")
|
buf := []byte("some data to hash")
|
||||||
@ -414,3 +466,35 @@ func ExampleCShake256() {
|
|||||||
//a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
|
//a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
|
||||||
//85e73a72228d08b46515553ca3a29d47df3047e5d84b12d6c2c63e579f4fd1105716b7838e92e981863907f434bfd4443c9e56ea09da998d2f9b47db71988109
|
//85e73a72228d08b46515553ca3a29d47df3047e5d84b12d6c2c63e579f4fd1105716b7838e92e981863907f434bfd4443c9e56ea09da998d2f9b47db71988109
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDoubleInit(t *testing.T) {
|
||||||
|
var h1 CShake
|
||||||
|
|
||||||
|
h1.Init(CSHAKE_256, []byte("ABC"), []byte("DEF"))
|
||||||
|
h2 := NewCShake256([]byte("ABC"), []byte("DEF"))
|
||||||
|
|
||||||
|
h1.Write([]byte("FUCKOFF"))
|
||||||
|
h2.Write([]byte("FUCKOFF"))
|
||||||
|
|
||||||
|
var out1, out2 [32]byte
|
||||||
|
h1.Read(out1[:])
|
||||||
|
h2.Read(out2[:])
|
||||||
|
|
||||||
|
if !bytes.Equal(out1[:], out2[:]) {
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCShakeSum2(b *testing.B) {
|
||||||
|
var f = []byte{0x02, 0x00}
|
||||||
|
var o1 [32]byte
|
||||||
|
var i1 [449]byte
|
||||||
|
|
||||||
|
var c CShake
|
||||||
|
c.Init(CSHAKE_256, nil, f)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
c.CShakeSum(o1[:], i1[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -131,6 +131,65 @@ func NewCShake256(N, S []byte) *CShake {
|
|||||||
return newCShake(N, S, rate256, dsbyteCShake)
|
return newCShake(N, S, rate256, dsbyteCShake)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
CSHAKE_256 = 0
|
||||||
|
CSHAKE_128 = 1
|
||||||
|
SHAKE_128 = 2
|
||||||
|
SHAKE_256 = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *CShake) Init(id int, N, S []byte) {
|
||||||
|
// leftEncode returns max 9 bytes
|
||||||
|
initBlock := make([]byte, 0, 9*2+len(N)+len(S))
|
||||||
|
initBlock = append(initBlock, leftEncode(uint64(len(N)*8))...)
|
||||||
|
initBlock = append(initBlock, N...)
|
||||||
|
initBlock = append(initBlock, leftEncode(uint64(len(S)*8))...)
|
||||||
|
initBlock = append(initBlock, S...)
|
||||||
|
|
||||||
|
switch id {
|
||||||
|
case CSHAKE_256:
|
||||||
|
c.state.rate = rate256
|
||||||
|
c.state.dsbyte = dsbyteCShake
|
||||||
|
}
|
||||||
|
|
||||||
|
c.initBlock = bytepad(initBlock, c.state.rate)
|
||||||
|
c.Write(c.initBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs CShake) CShakeSum(out []byte, in []byte) (n int) {
|
||||||
|
d := cs.state
|
||||||
|
blocks := int(len(in) / d.rate)
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
d.buf = d.storage[:0]
|
||||||
|
d.state = spongeAbsorbing
|
||||||
|
for i, _ := range d.a {
|
||||||
|
d.a[i] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Absorb
|
||||||
|
for i := 0; i < blocks; i++ {
|
||||||
|
xorInUnaligned(&d, in[i*d.rate:(i+1)*d.rate])
|
||||||
|
keccakF1600(&d.a)
|
||||||
|
}
|
||||||
|
d.buf = append(d.buf, in[blocks*d.rate:]...)
|
||||||
|
d.padAndPermute(d.dsbyte)
|
||||||
|
|
||||||
|
// Now, do the squeezing.
|
||||||
|
n = len(out)
|
||||||
|
for len(out) > 0 {
|
||||||
|
n := copy(out[:], d.buf)
|
||||||
|
d.buf = d.buf[n:]
|
||||||
|
out = out[n:]
|
||||||
|
|
||||||
|
// Apply the permutation if we've squeezed the sponge dry.
|
||||||
|
if len(d.buf) == 0 {
|
||||||
|
d.permute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
// ShakeSum128 writes an arbitrary-length digest of data into hash.
|
// ShakeSum128 writes an arbitrary-length digest of data into hash.
|
||||||
func ShakeSum128(hash, data []byte) {
|
func ShakeSum128(hash, data []byte) {
|
||||||
h := NewShake128()
|
h := NewShake128()
|
||||||
|
@ -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"
|
|
@ -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