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 mod(a, b int) int { return a % b }
func afunc(x, y int) string { 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 { 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{ var funcs = template.FuncMap{
@ -77,9 +77,9 @@ var tmpl = template.Must(template.New("keccak").Funcs(funcs).Parse(`
package keccak package keccak
// round implements one round of the keccak-f[1600] permutation. // 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 }} {{ 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 }} {{ end }}
// Theta // Theta

View File

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

View File

@ -4,235 +4,235 @@
package keccak package keccak
// round implements one round of the keccak-f[1600] permutation. // 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 // Theta
var c0, c1, c2, c3, c4 uint64 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 var d uint64
d = c4 ^ (c1<<1 | c1>>63) 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) 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) 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) 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) 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 // 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 // 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 // digest implements hash.Hash
type digest struct { type digest struct {
a [5][5]uint64 // a[y][x][z] a [25]uint64 // a[y][x][z]
buf [200]byte buf [200]byte
dsbyte byte dsbyte byte
len int len int
@ -28,7 +28,7 @@ func (d *digest) BlockSize() int { return 200 - d.size*2 }
func (d *digest) Reset() { func (d *digest) Reset() {
//fmt.Println("resetting") //fmt.Println("resetting")
d.a = [5][5]uint64{} d.a = [25]uint64{}
d.buf = [200]byte{} d.buf = [200]byte{}
d.len = 0 d.len = 0
} }
@ -51,23 +51,21 @@ func (d *digest) flush() {
//fmt.Printf("Flushing with %d bytes\n", d.len) //fmt.Printf("Flushing with %d bytes\n", d.len)
b := d.buf[:d.len] b := d.buf[:d.len]
loop: loop:
for y := range d.a { for i := range d.a {
for x := range d.a[0] {
if len(b) == 0 { if len(b) == 0 {
break loop break loop
} }
d.a[y][x] ^= le64dec(b) d.a[i] ^= le64dec(b)
b = b[8:] b = b[8:]
} }
}
keccakf(&d.a) keccakf(&d.a)
d.len = 0 d.len = 0
} }
func keccakf(a *[5][5]uint64) { func keccakf(a *[25]uint64) {
for i := 0; i < 24; i++ { for i := 0; i < 24; i++ {
round(a) round(a)
a[0][0] ^= roundc[i] a[0] ^= roundc[i]
} }
} }
@ -83,7 +81,7 @@ func (d0 *digest) Sum(b []byte) []byte {
d.flush() d.flush()
for i := 0; i < d.size/8; i++ { 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 return b
} }