2014-12-31 22:59:00 +00:00
|
|
|
package keccak
|
|
|
|
|
|
|
|
// roundGeneric implements one round of the keccak-f[1600] permutation.
|
2014-12-31 23:17:55 +00:00
|
|
|
func roundGeneric(a *[5][5]uint64) {
|
2014-12-31 23:11:40 +00:00
|
|
|
// Theta
|
2014-12-31 22:59:00 +00:00
|
|
|
var c [5]uint64
|
2014-12-31 23:17:55 +00:00
|
|
|
for x := range *a {
|
2014-12-31 23:15:49 +00:00
|
|
|
c[x] = a[0][x] ^ a[1][x] ^ a[2][x] ^ a[3][x] ^ a[4][x]
|
2014-12-31 22:59:00 +00:00
|
|
|
}
|
2014-12-31 23:15:49 +00:00
|
|
|
for x := range a[0] {
|
2014-12-31 22:59:00 +00:00
|
|
|
x0, x1 := (x+4)%5, (x+1)%5
|
2014-12-31 23:15:49 +00:00
|
|
|
a[0][x] ^= c[x0] ^ rotl(c[x1], 1)
|
|
|
|
a[1][x] ^= c[x0] ^ rotl(c[x1], 1)
|
|
|
|
a[2][x] ^= c[x0] ^ rotl(c[x1], 1)
|
|
|
|
a[3][x] ^= c[x0] ^ rotl(c[x1], 1)
|
|
|
|
a[4][x] ^= c[x0] ^ rotl(c[x1], 1)
|
2014-12-31 22:59:00 +00:00
|
|
|
}
|
|
|
|
|
2014-12-31 23:11:40 +00:00
|
|
|
// Rho and pi
|
2014-12-31 22:59:00 +00:00
|
|
|
var b [5][5]uint64
|
2014-12-31 23:17:55 +00:00
|
|
|
for y := range *a {
|
2014-12-31 23:15:49 +00:00
|
|
|
for x := range a[0] {
|
2014-12-31 22:59:00 +00:00
|
|
|
x0 := y
|
|
|
|
y0 := (x*2 + y*3) % 5
|
2014-12-31 23:15:49 +00:00
|
|
|
b[y0][x0] = rotl(a[y][x], rotc[y][x])
|
2014-12-31 22:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-31 23:11:40 +00:00
|
|
|
// Chi
|
2014-12-31 22:59:00 +00:00
|
|
|
for y := range a[0] {
|
2014-12-31 23:15:49 +00:00
|
|
|
c := [5]uint64{b[y][0], b[y][1], b[y][2], b[y][3], b[y][4]}
|
2014-12-31 23:19:23 +00:00
|
|
|
a[y][0] = b[y][0] ^ ^c[1]&c[2]
|
|
|
|
a[y][1] = b[y][1] ^ ^c[2]&c[3]
|
|
|
|
a[y][2] = b[y][2] ^ ^c[3]&c[4]
|
|
|
|
a[y][3] = b[y][3] ^ ^c[4]&c[0]
|
|
|
|
a[y][4] = b[y][4] ^ ^c[0]&c[1]
|
2014-12-31 22:59:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func rotl(a uint64, r uint) uint64 {
|
|
|
|
return a<<r | a>>(64-r)
|
|
|
|
}
|