Generate a faster round function.
parent
c9dcfb85a1
commit
df6edcd0bb
|
@ -0,0 +1,122 @@
|
|||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var roundc [24]uint64
|
||||
var rotc [5][5]int
|
||||
|
||||
func main() {
|
||||
// Round constants
|
||||
rc := uint8(1)
|
||||
for i := 0; i < 24; i++ {
|
||||
for j := 0; j <= 6; j++ {
|
||||
roundc[i] |= uint64(rc&1) << (1<<uint(j) - 1)
|
||||
rc = rc<<1 ^ 0x71&uint8(int8(rc)>>7)
|
||||
}
|
||||
}
|
||||
|
||||
// Rotation constants
|
||||
x, y := 1, 0
|
||||
for i := 1; i < 25; i++ {
|
||||
rotc[x][y] = (i*(i+1)/2) % 64
|
||||
x, y = y, (2*x+3*y)%5
|
||||
}
|
||||
|
||||
var ctx = struct {
|
||||
Rotc [5][5]int
|
||||
} {
|
||||
rotc,
|
||||
}
|
||||
err := tmpl.Execute(os.Stdout, &ctx)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func count(n int) []int {
|
||||
var out = make([]int, n)
|
||||
for i := 0; i < n; i ++ {
|
||||
out[i] = i
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func add(a, b, m int) int {
|
||||
return (a+b) % m
|
||||
}
|
||||
|
||||
func sub(a, b int) int {
|
||||
return a - b
|
||||
}
|
||||
|
||||
func mul(a, b int) int {
|
||||
return a*b
|
||||
}
|
||||
|
||||
var funcs = template.FuncMap{
|
||||
"count": count,
|
||||
"add": add,
|
||||
"sub": sub,
|
||||
"mul": mul,
|
||||
}
|
||||
|
||||
var tmpl = template.Must(template.New("keccak").Funcs(funcs).Parse(`
|
||||
// Generated from go run gen.go
|
||||
// DO NOT EDIT
|
||||
|
||||
package keccak
|
||||
|
||||
// roundGeneric implements one round of the keccak-f[1600] permutation.
|
||||
func roundGeneric(a *[5][5]uint64) {
|
||||
{{ range $x := count 5 }}
|
||||
{{ range $y := count 5 }}
|
||||
var a{{$x}}{{$y}} = a[{{$y}}][{{$x}}]
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
// Theta
|
||||
var c0, c1, c2, c3, c4 uint64
|
||||
{{ range $x := count 5 }}
|
||||
c{{$x}} = a{{$x}}0 ^ a{{$x}}1 ^ a{{$x}}2 ^ a{{$x}}3 ^ a{{$x}}4
|
||||
{{ end }}
|
||||
{{ range $x := count 5 }}
|
||||
{{ $x0 := add $x 4 5 }}
|
||||
{{ $x1 := add $x 1 5 }}
|
||||
a{{$x}}0 ^= c{{$x0}} ^ (c{{$x1}}<<1 | c{{$x1}}>>63)
|
||||
a{{$x}}1 ^= c{{$x0}} ^ (c{{$x1}}<<1 | c{{$x1}}>>63)
|
||||
a{{$x}}2 ^= c{{$x0}} ^ (c{{$x1}}<<1 | c{{$x1}}>>63)
|
||||
a{{$x}}3 ^= c{{$x0}} ^ (c{{$x1}}<<1 | c{{$x1}}>>63)
|
||||
a{{$x}}4 ^= c{{$x0}} ^ (c{{$x1}}<<1 | c{{$x1}}>>63)
|
||||
{{ end }}
|
||||
|
||||
// Rho and pi
|
||||
{{ range $y := count 5 }}
|
||||
{{ range $x := count 5 }}
|
||||
{{ $x0 := $y }}
|
||||
{{ $y0 := add (mul $x 2) (mul $y 3) 5 }}
|
||||
{{ $r := index $.Rotc $x $y }}
|
||||
var b{{$x0}}{{$y0}} = a{{$x}}{{$y}}<<{{$r}} | a{{$x}}{{$y}}>>{{sub 64 $r}}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
// Chi
|
||||
{{ range $y := count 5 }}
|
||||
{{ range $x := count 5 }}
|
||||
a{{$x}}{{$y}} = b{{$x}}{{$y}} ^ (b{{add $x 2 5}}{{$y}} &^ b{{add $x 1 5}}{{$y}})
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
// Output
|
||||
{{ range $y := count 5 }}
|
||||
{{ range $x := count 5 }}
|
||||
a[{{$y}}][{{$x}}] = a{{$x}}{{$y}}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
}
|
||||
`))
|
27
genconst.go
27
genconst.go
|
@ -1,27 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
//Round constants
|
||||
var RC [24]uint64
|
||||
rc := uint8(1)
|
||||
for i := 0; i < 24; i++ {
|
||||
for j := 0; j <= 6; j++ {
|
||||
RC[i] |= uint64(rc&1) << (1<<uint(j) - 1)
|
||||
rc = rc<<1 ^ 0x71&uint8(int8(rc)>>7)
|
||||
}
|
||||
}
|
||||
fmt.Println("package keccak")
|
||||
fmt.Printf("var RC = %#016v\n", RC)
|
||||
|
||||
var rot [5][5]uint
|
||||
x, y := 1, 0
|
||||
for i := 0; i < 24; i++ {
|
||||
rot[y][x] = uint((i+1)*(i+2)/2) % 64
|
||||
x, y = y, (2*x+3*y)%5
|
||||
}
|
||||
fmt.Printf("var rotc = %#v\n", rot)
|
||||
}
|
13
keccak.go
13
keccak.go
|
@ -28,15 +28,14 @@ func roundGeneric(a *[5][5]uint64) {
|
|||
|
||||
// Chi
|
||||
for y := range a[0] {
|
||||
c := [5]uint64{b[y][0], b[y][1], b[y][2], b[y][3], b[y][4]}
|
||||
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]
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
||||
func rotl(a uint64, r uint) uint64 {
|
||||
return a<<r | a>>(64-r)
|
||||
return a<<(r%64) | a>>(64-(r%64))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
// Generated from go run gen.go
|
||||
// DO NOT EDIT
|
||||
|
||||
package keccak
|
||||
|
||||
// roundGeneric implements one round of the keccak-f[1600] permutation.
|
||||
func roundGen(a *[5][5]uint64) {
|
||||
|
||||
var a00 = a[0][0]
|
||||
|
||||
var a01 = a[1][0]
|
||||
|
||||
var a02 = a[2][0]
|
||||
|
||||
var a03 = a[3][0]
|
||||
|
||||
var a04 = a[4][0]
|
||||
|
||||
var a10 = a[0][1]
|
||||
|
||||
var a11 = a[1][1]
|
||||
|
||||
var a12 = a[2][1]
|
||||
|
||||
var a13 = a[3][1]
|
||||
|
||||
var a14 = a[4][1]
|
||||
|
||||
var a20 = a[0][2]
|
||||
|
||||
var a21 = a[1][2]
|
||||
|
||||
var a22 = a[2][2]
|
||||
|
||||
var a23 = a[3][2]
|
||||
|
||||
var a24 = a[4][2]
|
||||
|
||||
var a30 = a[0][3]
|
||||
|
||||
var a31 = a[1][3]
|
||||
|
||||
var a32 = a[2][3]
|
||||
|
||||
var a33 = a[3][3]
|
||||
|
||||
var a34 = a[4][3]
|
||||
|
||||
var a40 = a[0][4]
|
||||
|
||||
var a41 = a[1][4]
|
||||
|
||||
var a42 = a[2][4]
|
||||
|
||||
var a43 = a[3][4]
|
||||
|
||||
var a44 = a[4][4]
|
||||
|
||||
// Theta
|
||||
var c0, c1, c2, c3, c4 uint64
|
||||
|
||||
c0 = a00 ^ a01 ^ a02 ^ a03 ^ a04
|
||||
|
||||
c1 = a10 ^ a11 ^ a12 ^ a13 ^ a14
|
||||
|
||||
c2 = a20 ^ a21 ^ a22 ^ a23 ^ a24
|
||||
|
||||
c3 = a30 ^ a31 ^ a32 ^ a33 ^ a34
|
||||
|
||||
c4 = a40 ^ a41 ^ a42 ^ a43 ^ a44
|
||||
|
||||
a00 ^= c4 ^ (c1<<1 | c1>>63)
|
||||
a01 ^= c4 ^ (c1<<1 | c1>>63)
|
||||
a02 ^= c4 ^ (c1<<1 | c1>>63)
|
||||
a03 ^= c4 ^ (c1<<1 | c1>>63)
|
||||
a04 ^= c4 ^ (c1<<1 | c1>>63)
|
||||
|
||||
a10 ^= c0 ^ (c2<<1 | c2>>63)
|
||||
a11 ^= c0 ^ (c2<<1 | c2>>63)
|
||||
a12 ^= c0 ^ (c2<<1 | c2>>63)
|
||||
a13 ^= c0 ^ (c2<<1 | c2>>63)
|
||||
a14 ^= c0 ^ (c2<<1 | c2>>63)
|
||||
|
||||
a20 ^= c1 ^ (c3<<1 | c3>>63)
|
||||
a21 ^= c1 ^ (c3<<1 | c3>>63)
|
||||
a22 ^= c1 ^ (c3<<1 | c3>>63)
|
||||
a23 ^= c1 ^ (c3<<1 | c3>>63)
|
||||
a24 ^= c1 ^ (c3<<1 | c3>>63)
|
||||
|
||||
a30 ^= c2 ^ (c4<<1 | c4>>63)
|
||||
a31 ^= c2 ^ (c4<<1 | c4>>63)
|
||||
a32 ^= c2 ^ (c4<<1 | c4>>63)
|
||||
a33 ^= c2 ^ (c4<<1 | c4>>63)
|
||||
a34 ^= c2 ^ (c4<<1 | c4>>63)
|
||||
|
||||
a40 ^= c3 ^ (c0<<1 | c0>>63)
|
||||
a41 ^= c3 ^ (c0<<1 | c0>>63)
|
||||
a42 ^= c3 ^ (c0<<1 | c0>>63)
|
||||
a43 ^= c3 ^ (c0<<1 | c0>>63)
|
||||
a44 ^= c3 ^ (c0<<1 | c0>>63)
|
||||
|
||||
// Rho and pi
|
||||
|
||||
var b00 = a00<<0 | a00>>64
|
||||
|
||||
var b02 = a10<<1 | a10>>63
|
||||
|
||||
var b04 = a20<<62 | a20>>2
|
||||
|
||||
var b01 = a30<<28 | a30>>36
|
||||
|
||||
var b03 = a40<<27 | a40>>37
|
||||
|
||||
var b13 = a01<<36 | a01>>28
|
||||
|
||||
var b10 = a11<<44 | a11>>20
|
||||
|
||||
var b12 = a21<<6 | a21>>58
|
||||
|
||||
var b14 = a31<<55 | a31>>9
|
||||
|
||||
var b11 = a41<<20 | a41>>44
|
||||
|
||||
var b21 = a02<<3 | a02>>61
|
||||
|
||||
var b23 = a12<<10 | a12>>54
|
||||
|
||||
var b20 = a22<<43 | a22>>21
|
||||
|
||||
var b22 = a32<<25 | a32>>39
|
||||
|
||||
var b24 = a42<<39 | a42>>25
|
||||
|
||||
var b34 = a03<<41 | a03>>23
|
||||
|
||||
var b31 = a13<<45 | a13>>19
|
||||
|
||||
var b33 = a23<<15 | a23>>49
|
||||
|
||||
var b30 = a33<<21 | a33>>43
|
||||
|
||||
var b32 = a43<<8 | a43>>56
|
||||
|
||||
var b42 = a04<<18 | a04>>46
|
||||
|
||||
var b44 = a14<<2 | a14>>62
|
||||
|
||||
var b41 = a24<<61 | a24>>3
|
||||
|
||||
var b43 = a34<<56 | a34>>8
|
||||
|
||||
var b40 = a44<<14 | a44>>50
|
||||
|
||||
// Chi
|
||||
|
||||
a00 = b00 ^ (b20 &^ b10)
|
||||
|
||||
a10 = b10 ^ (b30 &^ b20)
|
||||
|
||||
a20 = b20 ^ (b40 &^ b30)
|
||||
|
||||
a30 = b30 ^ (b00 &^ b40)
|
||||
|
||||
a40 = b40 ^ (b10 &^ b00)
|
||||
|
||||
a01 = b01 ^ (b21 &^ b11)
|
||||
|
||||
a11 = b11 ^ (b31 &^ b21)
|
||||
|
||||
a21 = b21 ^ (b41 &^ b31)
|
||||
|
||||
a31 = b31 ^ (b01 &^ b41)
|
||||
|
||||
a41 = b41 ^ (b11 &^ b01)
|
||||
|
||||
a02 = b02 ^ (b22 &^ b12)
|
||||
|
||||
a12 = b12 ^ (b32 &^ b22)
|
||||
|
||||
a22 = b22 ^ (b42 &^ b32)
|
||||
|
||||
a32 = b32 ^ (b02 &^ b42)
|
||||
|
||||
a42 = b42 ^ (b12 &^ b02)
|
||||
|
||||
a03 = b03 ^ (b23 &^ b13)
|
||||
|
||||
a13 = b13 ^ (b33 &^ b23)
|
||||
|
||||
a23 = b23 ^ (b43 &^ b33)
|
||||
|
||||
a33 = b33 ^ (b03 &^ b43)
|
||||
|
||||
a43 = b43 ^ (b13 &^ b03)
|
||||
|
||||
a04 = b04 ^ (b24 &^ b14)
|
||||
|
||||
a14 = b14 ^ (b34 &^ b24)
|
||||
|
||||
a24 = b24 ^ (b44 &^ b34)
|
||||
|
||||
a34 = b34 ^ (b04 &^ b44)
|
||||
|
||||
a44 = b44 ^ (b14 &^ b04)
|
||||
|
||||
// Output
|
||||
|
||||
a[0][0] = a00
|
||||
|
||||
a[0][1] = a10
|
||||
|
||||
a[0][2] = a20
|
||||
|
||||
a[0][3] = a30
|
||||
|
||||
a[0][4] = a40
|
||||
|
||||
a[1][0] = a01
|
||||
|
||||
a[1][1] = a11
|
||||
|
||||
a[1][2] = a21
|
||||
|
||||
a[1][3] = a31
|
||||
|
||||
a[1][4] = a41
|
||||
|
||||
a[2][0] = a02
|
||||
|
||||
a[2][1] = a12
|
||||
|
||||
a[2][2] = a22
|
||||
|
||||
a[2][3] = a32
|
||||
|
||||
a[2][4] = a42
|
||||
|
||||
a[3][0] = a03
|
||||
|
||||
a[3][1] = a13
|
||||
|
||||
a[3][2] = a23
|
||||
|
||||
a[3][3] = a33
|
||||
|
||||
a[3][4] = a43
|
||||
|
||||
a[4][0] = a04
|
||||
|
||||
a[4][1] = a14
|
||||
|
||||
a[4][2] = a24
|
||||
|
||||
a[4][3] = a34
|
||||
|
||||
a[4][4] = a44
|
||||
|
||||
}
|
|
@ -5,7 +5,8 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
var vector = []byte{0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c,
|
||||
var vector = []byte{
|
||||
0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c,
|
||||
0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0,
|
||||
0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b,
|
||||
0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70,
|
||||
|
|
|
@ -6,6 +6,8 @@ const Size = 256 / 8
|
|||
|
||||
const BlockSize = 1600/8 - Size*2
|
||||
|
||||
var round = roundGen
|
||||
|
||||
// digest implements hash.Hash
|
||||
type digest struct {
|
||||
a [5][5]uint64 // a[y][x][z]
|
||||
|
@ -55,7 +57,7 @@ loop:
|
|||
|
||||
func keccakf(a *[5][5]uint64) {
|
||||
for i := 0; i < 24; i++ {
|
||||
roundGeneric(a)
|
||||
round(a)
|
||||
a[0][0] ^= RC[i]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue