From 47cec850c1998cdd7b112ca8f6627bd59e24e17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 29 May 2018 15:07:47 +0200 Subject: [PATCH] crypto: Add KeccakFast functions --- crypto/sha3/sha3.go | 59 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/crypto/sha3/sha3.go b/crypto/sha3/sha3.go index b12a35c87f..1140a4d266 100644 --- a/crypto/sha3/sha3.go +++ b/crypto/sha3/sha3.go @@ -4,6 +4,8 @@ package sha3 +import "encoding/binary" + // spongeDirection indicates the direction bytes are flowing through the sponge. type spongeDirection int @@ -190,3 +192,60 @@ func (d *state) Sum(in []byte) []byte { dup.Read(hash) return append(in, hash...) } + + + +func keccakFast(out []byte, bits int, data []byte) { + const wordSize = 8 + hashSize := bits / 8 + blockSize := (1600 - bits * 2) / 8 + + var state [25]uint64 + + dataIndex := 0 + + dataLen := len(data) + for dataLen >= blockSize { + for i := 0; i < (blockSize / wordSize); i++ { + state[i] ^= binary.LittleEndian.Uint64(data[dataIndex:]) + dataIndex += wordSize + } + keccakF1600(&state) + dataLen -= blockSize + } + + stateIndex := 0 + for dataLen >= wordSize { + state[stateIndex] ^= binary.LittleEndian.Uint64(data[dataIndex:]) + stateIndex++ + dataIndex += wordSize + dataLen -= wordSize + } + + var lastWord [8]byte + lastWordIndex := 0 + for dataLen > 0 { + lastWord[lastWordIndex] = data[dataIndex] + lastWordIndex++ + dataIndex++ + dataLen-- + } + lastWord[lastWordIndex] = 0x01 + state[stateIndex] ^= binary.LittleEndian.Uint64(lastWord[:]) + + state[(blockSize/wordSize) - 1] ^= 0x8000000000000000 + + keccakF1600(&state) + + for i := 0; i < (hashSize / wordSize); i++ { + binary.LittleEndian.PutUint64(out[i * 8:], state[i]) + } +} + +func KeccakFast256(dest []byte, data []byte) { + keccakFast(dest, 256, data) +} + +func KeccakFast512(dest []byte, data []byte) { + keccakFast(dest, 512, data) +}