1
0
mirror of https://github.com/henrydcase/nobs.git synced 2024-11-22 07:15:32 +00:00

PoC on CShakeSum and no-heap initialization

This commit is contained in:
Henry Case 2019-05-14 16:10:19 +01:00
parent e6439f96ab
commit 4ec6f4b876
6 changed files with 150 additions and 55 deletions

View File

@ -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 }

View File

@ -83,7 +83,7 @@ func (d *state) permute() {
case spongeAbsorbing:
// If we're absorbing, we need to xor the input into the state
// before applying the permutation.
xorIn(d, d.buf)
xorInUnaligned(d, d.buf)
d.buf = d.storage[:0]
keccakF1600(&d.a)
case spongeSqueezing:
@ -91,7 +91,7 @@ func (d *state) permute() {
// copying more output.
keccakF1600(&d.a)
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.state = spongeSqueezing
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
@ -136,7 +136,7 @@ func (d *state) Write(p []byte) (written int, err error) {
for len(p) > 0 {
if len(d.buf) == 0 && len(p) >= d.rate {
// 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:]
keccakF1600(&d.a)
} else {

View File

@ -22,6 +22,11 @@ import (
"testing"
)
var (
xorIn = xorInUnaligned
copyOut = copyOutUnaligned
)
const (
testString = "brekeccakkeccak koax koax"
katFilename = "testdata/keccakKats.json.deflate"
@ -68,7 +73,7 @@ func testUnalignedAndGeneric(t *testing.T, testf func(impl string)) {
xorIn, copyOut = xorInGeneric, copyOutGeneric
testf("generic")
if xorImplementationUnaligned != "generic" {
xorIn, copyOut = xorInUnaligned, copyOutUnaligned
xorIn, copyOut = xorInGeneric, copyOutGeneric
testf("unaligned")
}
xorIn, copyOut = xorInOrig, copyOutOrig
@ -336,7 +341,7 @@ func benchmarkShake(b *testing.B, h *CShake, size, num int) {
b.StopTimer()
h.Reset()
data := sequentialBytes(size)
d := make([]byte, 32)
var d [32]byte
b.SetBytes(int64(size * num))
b.StartTimer()
@ -346,7 +351,7 @@ func benchmarkShake(b *testing.B, h *CShake, size, num int) {
for j := 0; j < num; j++ {
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_16x(b *testing.B) { benchmarkShake(b, NewShake256(), 16, 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() {
buf := []byte("some data to hash")
@ -414,3 +466,35 @@ func ExampleCShake256() {
//a90a4c6ca9af2156eba43dc8398279e6b60dcd56fb21837afe6c308fd4ceb05b9dd98c6ee866ca7dc5a39d53e960f400bcd5a19c8a2d6ec6459f63696543a0d8
//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[:])
}
}

View File

@ -131,6 +131,65 @@ func NewCShake256(N, S []byte) *CShake {
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.
func ShakeSum128(hash, data []byte) {
h := NewShake128()

View File

@ -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"

View File

@ -50,9 +50,4 @@ func copyOutUnaligned(d *state, buf []byte) {
copy(buf, ab[:])
}
var (
xorIn = xorInUnaligned
copyOut = copyOutUnaligned
)
const xorImplementationUnaligned = "unaligned"