Files
crypto/sha3/keccakf.go
T
Eric Roshan-Eisner d52ec73510 go.crypto/sha3: change keccakF to stateless function
Taken from my implementation: https://bitbucket.org/ede/sha3
Performance gain from using less memory and more registers.

benchmark                       old ns/op    new ns/op    delta
BenchmarkPermutationFunction         1484         1118  -24.66%
BenchmarkBulkKeccak512             374993       295178  -21.28%
BenchmarkBulkKeccak256             215496       172335  -20.03%

benchmark                        old MB/s     new MB/s  speedup
BenchmarkPermutationFunction       134.76       178.80    1.33x
BenchmarkBulkKeccak512              43.69        55.51    1.27x
BenchmarkBulkKeccak256              76.03        95.07    1.25x

R=jcb, agl
CC=golang-dev, nigeltao
https://golang.org/cl/8088044
2013-04-02 10:41:35 -04:00

166 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright 2013 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.
package sha3
// This file implements the core Keccak permutation function necessary for computing SHA3.
// This is implemented in a separate file to allow for replacement by an optimized implementation.
// Nothing in this package is exported.
// For the detailed specification, refer to the Keccak web site (http://keccak.noekeon.org/).
// rc stores the round constants for use in the ι step.
var rc = [...]uint64{
0x0000000000000001,
0x0000000000008082,
0x800000000000808A,
0x8000000080008000,
0x000000000000808B,
0x0000000080000001,
0x8000000080008081,
0x8000000000008009,
0x000000000000008A,
0x0000000000000088,
0x0000000080008009,
0x000000008000000A,
0x000000008000808B,
0x800000000000008B,
0x8000000000008089,
0x8000000000008003,
0x8000000000008002,
0x8000000000000080,
0x000000000000800A,
0x800000008000000A,
0x8000000080008081,
0x8000000000008080,
0x0000000080000001,
0x8000000080008008,
}
// keccakF computes the complete Keccak-f function consisting of 24 rounds with a different
// constant (rc) in each round. This implementation fully unrolls the round function to avoid
// inner loops, as well as pre-calculating shift offsets.
func keccakF(a *[numLanes]uint64) {
var t, bc0, bc1, bc2, bc3, bc4 uint64
for _, roundConstant := range rc {
// θ step
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
t = bc4 ^ (bc1<<1 ^ bc1>>63)
a[0] ^= t
a[5] ^= t
a[10] ^= t
a[15] ^= t
a[20] ^= t
t = bc0 ^ (bc2<<1 ^ bc2>>63)
a[1] ^= t
a[6] ^= t
a[11] ^= t
a[16] ^= t
a[21] ^= t
t = bc1 ^ (bc3<<1 ^ bc3>>63)
a[2] ^= t
a[7] ^= t
a[12] ^= t
a[17] ^= t
a[22] ^= t
t = bc2 ^ (bc4<<1 ^ bc4>>63)
a[3] ^= t
a[8] ^= t
a[13] ^= t
a[18] ^= t
a[23] ^= t
t = bc3 ^ (bc0<<1 ^ bc0>>63)
a[4] ^= t
a[9] ^= t
a[14] ^= t
a[19] ^= t
a[24] ^= t
// ρ and π steps
t = a[1]
t, a[10] = a[10], t<<1^t>>(64-1)
t, a[7] = a[7], t<<3^t>>(64-3)
t, a[11] = a[11], t<<6^t>>(64-6)
t, a[17] = a[17], t<<10^t>>(64-10)
t, a[18] = a[18], t<<15^t>>(64-15)
t, a[3] = a[3], t<<21^t>>(64-21)
t, a[5] = a[5], t<<28^t>>(64-28)
t, a[16] = a[16], t<<36^t>>(64-36)
t, a[8] = a[8], t<<45^t>>(64-45)
t, a[21] = a[21], t<<55^t>>(64-55)
t, a[24] = a[24], t<<2^t>>(64-2)
t, a[4] = a[4], t<<14^t>>(64-14)
t, a[15] = a[15], t<<27^t>>(64-27)
t, a[23] = a[23], t<<41^t>>(64-41)
t, a[19] = a[19], t<<56^t>>(64-56)
t, a[13] = a[13], t<<8^t>>(64-8)
t, a[12] = a[12], t<<25^t>>(64-25)
t, a[2] = a[2], t<<43^t>>(64-43)
t, a[20] = a[20], t<<62^t>>(64-62)
t, a[14] = a[14], t<<18^t>>(64-18)
t, a[22] = a[22], t<<39^t>>(64-39)
t, a[9] = a[9], t<<61^t>>(64-61)
t, a[6] = a[6], t<<20^t>>(64-20)
a[1] = t<<44 ^ t>>(64-44)
// χ step
bc0 = a[0]
bc1 = a[1]
bc2 = a[2]
bc3 = a[3]
bc4 = a[4]
a[0] ^= bc2 &^ bc1
a[1] ^= bc3 &^ bc2
a[2] ^= bc4 &^ bc3
a[3] ^= bc0 &^ bc4
a[4] ^= bc1 &^ bc0
bc0 = a[5]
bc1 = a[6]
bc2 = a[7]
bc3 = a[8]
bc4 = a[9]
a[5] ^= bc2 &^ bc1
a[6] ^= bc3 &^ bc2
a[7] ^= bc4 &^ bc3
a[8] ^= bc0 &^ bc4
a[9] ^= bc1 &^ bc0
bc0 = a[10]
bc1 = a[11]
bc2 = a[12]
bc3 = a[13]
bc4 = a[14]
a[10] ^= bc2 &^ bc1
a[11] ^= bc3 &^ bc2
a[12] ^= bc4 &^ bc3
a[13] ^= bc0 &^ bc4
a[14] ^= bc1 &^ bc0
bc0 = a[15]
bc1 = a[16]
bc2 = a[17]
bc3 = a[18]
bc4 = a[19]
a[15] ^= bc2 &^ bc1
a[16] ^= bc3 &^ bc2
a[17] ^= bc4 &^ bc3
a[18] ^= bc0 &^ bc4
a[19] ^= bc1 &^ bc0
bc0 = a[20]
bc1 = a[21]
bc2 = a[22]
bc3 = a[23]
bc4 = a[24]
a[20] ^= bc2 &^ bc1
a[21] ^= bc3 &^ bc2
a[22] ^= bc4 &^ bc3
a[23] ^= bc0 &^ bc4
a[24] ^= bc1 &^ bc0
// ι step
a[0] ^= roundConstant
}
}