diff --git a/gen.go b/gen.go index f07721b..a5b7510 100644 --- a/gen.go +++ b/gen.go @@ -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 diff --git a/keccak.go b/keccak.go index ee18b14..15eaf11 100644 --- a/keccak.go +++ b/keccak.go @@ -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] } } diff --git a/keccak_gen.go b/keccak_gen.go index 9a1fd9b..a6169d6 100644 --- a/keccak_gen.go +++ b/keccak_gen.go @@ -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) } diff --git a/sponge.go b/sponge.go index 0b12c86..e1ededb 100644 --- a/sponge.go +++ b/sponge.go @@ -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 }