Refactor: use [25]uint64 instead of [5][5]uint64.

master
magical 2015-01-01 02:59:03 -08:00
parent c8f826bc6a
commit f67abd3a9d
4 changed files with 135 additions and 138 deletions

8
gen.go
View File

@ -53,11 +53,11 @@ func mul(a, b int) int { return a * b }
func mod(a, b int) int { return a % b }
func afunc(x, y int) string {
return fmt.Sprintf("a[%d][%d]", y%5, x%5)
return fmt.Sprintf("a[%d]", y%5*5 + x%5)
}
func bfunc(x, y int) string {
return fmt.Sprintf("a%d%d", x%5, y%5)
return fmt.Sprintf("b%d%d", x%5, y%5)
}
var funcs = template.FuncMap{
@ -77,9 +77,9 @@ var tmpl = template.Must(template.New("keccak").Funcs(funcs).Parse(`
package keccak
// round implements one round of the keccak-f[1600] permutation.
func roundGo(a *[5][5]uint64) {
func roundGo(a *[25]uint64) {
{{ range $x := count 5 }}
var a{{$x}}0, a{{$x}}1, a{{$x}}2, a{{$x}}3, a{{$x}}4 uint64
var b{{$x}}0, b{{$x}}1, b{{$x}}2, b{{$x}}3, b{{$x}}4 uint64
{{ end }}
// Theta

View File

@ -1,38 +1,37 @@
package keccak
// roundGeneric implements one round of the keccak-f[1600] permutation.
func roundGeneric(a *[5][5]uint64) {
func roundGeneric(a *[25]uint64) {
// Theta
var c [5]uint64
for x := range *a {
c[x] = a[0][x] ^ a[1][x] ^ a[2][x] ^ a[3][x] ^ a[4][x]
for x := range c {
c[x] = a[0+x] ^ a[5+x] ^ a[10+x] ^ a[15+x] ^ a[20+x]
}
for x := range a[0] {
x0, x1 := (x+4)%5, (x+1)%5
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)
for x := 0; x < 5; x++ {
d := c[(x+4)%5] ^ rotl(c[(x+1)%5], 1)
for y := 0; y < 5; y++ {
a[y*5+x] ^= d
}
}
// Rho and pi
var b [5][5]uint64
for y := range *a {
for x := range a[0] {
for y := 0; y < 5; y++ {
for x := 0; x < 5; x++ {
x0 := y
y0 := (x*2 + y*3) % 5
b[y0][x0] = rotl(a[y][x], rotc[y][x])
b[y0][x0] = rotl(a[y*5+x], rotc[y][x])
}
}
// Chi
for y := range a[0] {
a[y][0] = b[y][0] ^ ^b[y][1]&b[y][2]
a[y][1] = b[y][1] ^ ^b[y][2]&b[y][3]
a[y][2] = b[y][2] ^ ^b[y][3]&b[y][4]
a[y][3] = b[y][3] ^ ^b[y][4]&b[y][0]
a[y][4] = b[y][4] ^ ^b[y][0]&b[y][1]
for y := 0; y < 5; y++ {
a[y*5+0] = b[y][0] ^ ^b[y][1]&b[y][2]
a[y*5+1] = b[y][1] ^ ^b[y][2]&b[y][3]
a[y*5+2] = b[y][2] ^ ^b[y][3]&b[y][4]
a[y*5+3] = b[y][3] ^ ^b[y][4]&b[y][0]
a[y*5+4] = b[y][4] ^ ^b[y][0]&b[y][1]
}
}

View File

@ -4,235 +4,235 @@
package keccak
// round implements one round of the keccak-f[1600] permutation.
func roundGo(a *[5][5]uint64) {
func roundGo(a *[25]uint64) {
var a00, a01, a02, a03, a04 uint64
var b00, b01, b02, b03, b04 uint64
var a10, a11, a12, a13, a14 uint64
var b10, b11, b12, b13, b14 uint64
var a20, a21, a22, a23, a24 uint64
var b20, b21, b22, b23, b24 uint64
var a30, a31, a32, a33, a34 uint64
var b30, b31, b32, b33, b34 uint64
var a40, a41, a42, a43, a44 uint64
var b40, b41, b42, b43, b44 uint64
// Theta
var c0, c1, c2, c3, c4 uint64
c0 = a[0][0]
c0 = a[0]
c1 = a[0][1]
c1 = a[1]
c2 = a[0][2]
c2 = a[2]
c3 = a[0][3]
c3 = a[3]
c4 = a[0][4]
c4 = a[4]
c0 ^= a[1][0]
c0 ^= a[5]
c1 ^= a[1][1]
c1 ^= a[6]
c2 ^= a[1][2]
c2 ^= a[7]
c3 ^= a[1][3]
c3 ^= a[8]
c4 ^= a[1][4]
c4 ^= a[9]
c0 ^= a[2][0]
c0 ^= a[10]
c1 ^= a[2][1]
c1 ^= a[11]
c2 ^= a[2][2]
c2 ^= a[12]
c3 ^= a[2][3]
c3 ^= a[13]
c4 ^= a[2][4]
c4 ^= a[14]
c0 ^= a[3][0]
c0 ^= a[15]
c1 ^= a[3][1]
c1 ^= a[16]
c2 ^= a[3][2]
c2 ^= a[17]
c3 ^= a[3][3]
c3 ^= a[18]
c4 ^= a[3][4]
c4 ^= a[19]
c0 ^= a[4][0]
c0 ^= a[20]
c1 ^= a[4][1]
c1 ^= a[21]
c2 ^= a[4][2]
c2 ^= a[22]
c3 ^= a[4][3]
c3 ^= a[23]
c4 ^= a[4][4]
c4 ^= a[24]
var d uint64
d = c4 ^ (c1<<1 | c1>>63)
a00 = a[0][0] ^ d
b00 = a[0] ^ d
a01 = a[1][0] ^ d
b01 = a[5] ^ d
a02 = a[2][0] ^ d
b02 = a[10] ^ d
a03 = a[3][0] ^ d
b03 = a[15] ^ d
a04 = a[4][0] ^ d
b04 = a[20] ^ d
d = c0 ^ (c2<<1 | c2>>63)
a10 = a[0][1] ^ d
b10 = a[1] ^ d
a11 = a[1][1] ^ d
b11 = a[6] ^ d
a12 = a[2][1] ^ d
b12 = a[11] ^ d
a13 = a[3][1] ^ d
b13 = a[16] ^ d
a14 = a[4][1] ^ d
b14 = a[21] ^ d
d = c1 ^ (c3<<1 | c3>>63)
a20 = a[0][2] ^ d
b20 = a[2] ^ d
a21 = a[1][2] ^ d
b21 = a[7] ^ d
a22 = a[2][2] ^ d
b22 = a[12] ^ d
a23 = a[3][2] ^ d
b23 = a[17] ^ d
a24 = a[4][2] ^ d
b24 = a[22] ^ d
d = c2 ^ (c4<<1 | c4>>63)
a30 = a[0][3] ^ d
b30 = a[3] ^ d
a31 = a[1][3] ^ d
b31 = a[8] ^ d
a32 = a[2][3] ^ d
b32 = a[13] ^ d
a33 = a[3][3] ^ d
b33 = a[18] ^ d
a34 = a[4][3] ^ d
b34 = a[23] ^ d
d = c3 ^ (c0<<1 | c0>>63)
a40 = a[0][4] ^ d
b40 = a[4] ^ d
a41 = a[1][4] ^ d
b41 = a[9] ^ d
a42 = a[2][4] ^ d
b42 = a[14] ^ d
a43 = a[3][4] ^ d
b43 = a[19] ^ d
a44 = a[4][4] ^ d
b44 = a[24] ^ d
// Rho
a00 = a00<<0 | a00>>64
b00 = b00<<0 | b00>>64
a10 = a10<<1 | a10>>63
b10 = b10<<1 | b10>>63
a20 = a20<<62 | a20>>2
b20 = b20<<62 | b20>>2
a30 = a30<<28 | a30>>36
b30 = b30<<28 | b30>>36
a40 = a40<<27 | a40>>37
b40 = b40<<27 | b40>>37
a01 = a01<<36 | a01>>28
b01 = b01<<36 | b01>>28
a11 = a11<<44 | a11>>20
b11 = b11<<44 | b11>>20
a21 = a21<<6 | a21>>58
b21 = b21<<6 | b21>>58
a31 = a31<<55 | a31>>9
b31 = b31<<55 | b31>>9
a41 = a41<<20 | a41>>44
b41 = b41<<20 | b41>>44
a02 = a02<<3 | a02>>61
b02 = b02<<3 | b02>>61
a12 = a12<<10 | a12>>54
b12 = b12<<10 | b12>>54
a22 = a22<<43 | a22>>21
b22 = b22<<43 | b22>>21
a32 = a32<<25 | a32>>39
b32 = b32<<25 | b32>>39
a42 = a42<<39 | a42>>25
b42 = b42<<39 | b42>>25
a03 = a03<<41 | a03>>23
b03 = b03<<41 | b03>>23
a13 = a13<<45 | a13>>19
b13 = b13<<45 | b13>>19
a23 = a23<<15 | a23>>49
b23 = b23<<15 | b23>>49
a33 = a33<<21 | a33>>43
b33 = b33<<21 | b33>>43
a43 = a43<<8 | a43>>56
b43 = b43<<8 | b43>>56
a04 = a04<<18 | a04>>46
b04 = b04<<18 | b04>>46
a14 = a14<<2 | a14>>62
b14 = b14<<2 | b14>>62
a24 = a24<<61 | a24>>3
b24 = b24<<61 | b24>>3
a34 = a34<<56 | a34>>8
b34 = b34<<56 | b34>>8
a44 = a44<<14 | a44>>50
b44 = b44<<14 | b44>>50
// Pi / Chi / output
a[0][0] = a00 ^ (a22 &^ a11)
a[0] = b00 ^ (b22 &^ b11)
a[0][1] = a11 ^ (a33 &^ a22)
a[1] = b11 ^ (b33 &^ b22)
a[0][2] = a22 ^ (a44 &^ a33)
a[2] = b22 ^ (b44 &^ b33)
a[0][3] = a33 ^ (a00 &^ a44)
a[3] = b33 ^ (b00 &^ b44)
a[0][4] = a44 ^ (a11 &^ a00)
a[4] = b44 ^ (b11 &^ b00)
a[1][0] = a30 ^ (a02 &^ a41)
a[5] = b30 ^ (b02 &^ b41)
a[1][1] = a41 ^ (a13 &^ a02)
a[6] = b41 ^ (b13 &^ b02)
a[1][2] = a02 ^ (a24 &^ a13)
a[7] = b02 ^ (b24 &^ b13)
a[1][3] = a13 ^ (a30 &^ a24)
a[8] = b13 ^ (b30 &^ b24)
a[1][4] = a24 ^ (a41 &^ a30)
a[9] = b24 ^ (b41 &^ b30)
a[2][0] = a10 ^ (a32 &^ a21)
a[10] = b10 ^ (b32 &^ b21)
a[2][1] = a21 ^ (a43 &^ a32)
a[11] = b21 ^ (b43 &^ b32)
a[2][2] = a32 ^ (a04 &^ a43)
a[12] = b32 ^ (b04 &^ b43)
a[2][3] = a43 ^ (a10 &^ a04)
a[13] = b43 ^ (b10 &^ b04)
a[2][4] = a04 ^ (a21 &^ a10)
a[14] = b04 ^ (b21 &^ b10)
a[3][0] = a40 ^ (a12 &^ a01)
a[15] = b40 ^ (b12 &^ b01)
a[3][1] = a01 ^ (a23 &^ a12)
a[16] = b01 ^ (b23 &^ b12)
a[3][2] = a12 ^ (a34 &^ a23)
a[17] = b12 ^ (b34 &^ b23)
a[3][3] = a23 ^ (a40 &^ a34)
a[18] = b23 ^ (b40 &^ b34)
a[3][4] = a34 ^ (a01 &^ a40)
a[19] = b34 ^ (b01 &^ b40)
a[4][0] = a20 ^ (a42 &^ a31)
a[20] = b20 ^ (b42 &^ b31)
a[4][1] = a31 ^ (a03 &^ a42)
a[21] = b31 ^ (b03 &^ b42)
a[4][2] = a42 ^ (a14 &^ a03)
a[22] = b42 ^ (b14 &^ b03)
a[4][3] = a03 ^ (a20 &^ a14)
a[23] = b03 ^ (b20 &^ b14)
a[4][4] = a14 ^ (a31 &^ a20)
a[24] = b14 ^ (b31 &^ b20)
}

View File

@ -10,7 +10,7 @@ var round = roundGo
// digest implements hash.Hash
type digest struct {
a [5][5]uint64 // a[y][x][z]
a [25]uint64 // a[y][x][z]
buf [200]byte
dsbyte byte
len int
@ -28,7 +28,7 @@ func (d *digest) BlockSize() int { return 200 - d.size*2 }
func (d *digest) Reset() {
//fmt.Println("resetting")
d.a = [5][5]uint64{}
d.a = [25]uint64{}
d.buf = [200]byte{}
d.len = 0
}
@ -51,23 +51,21 @@ func (d *digest) flush() {
//fmt.Printf("Flushing with %d bytes\n", d.len)
b := d.buf[:d.len]
loop:
for y := range d.a {
for x := range d.a[0] {
for i := range d.a {
if len(b) == 0 {
break loop
}
d.a[y][x] ^= le64dec(b)
d.a[i] ^= le64dec(b)
b = b[8:]
}
}
keccakf(&d.a)
d.len = 0
}
func keccakf(a *[5][5]uint64) {
func keccakf(a *[25]uint64) {
for i := 0; i < 24; i++ {
round(a)
a[0][0] ^= roundc[i]
a[0] ^= roundc[i]
}
}
@ -83,7 +81,7 @@ func (d0 *digest) Sum(b []byte) []byte {
d.flush()
for i := 0; i < d.size/8; i++ {
b = le64enc(b, d.a[i/5][i%5])
b = le64enc(b, d.a[i])
}
return b
}