Browse Source

Add Theta go impl

master
arnaucube 3 years ago
parent
commit
bfdd4767cf
3 changed files with 142 additions and 0 deletions
  1. +51
    -0
      go-keccak256-bits-impl/ref.go
  2. +48
    -0
      go-keccak256-bits-impl/stepmappings.go
  3. +43
    -0
      go-keccak256-bits-impl/stepmappings_test.go

+ 51
- 0
go-keccak256-bits-impl/ref.go

@ -0,0 +1,51 @@
/*
This file contains the byte & uint64 implementations that are used to test the
bits implementations.
*/
package keccak
func thetaU64Version(a [25]uint64) [25]uint64 {
var c0, c1, c2, c3, c4, d uint64
var r [25]uint64
c0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
c1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
c2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
c3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
c4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
d = c4 ^ (c1<<1 | c1>>(64-1))
r[0] = a[0] ^ d
r[5] = a[5] ^ d
r[10] = a[10] ^ d
r[15] = a[15] ^ d
r[20] = a[20] ^ d
d = c0 ^ (c2<<1 | c2>>(64-1))
r[1] = a[1] ^ d
r[6] = a[6] ^ d
r[11] = a[11] ^ d
r[16] = a[16] ^ d
r[21] = a[21] ^ d
d = c1 ^ (c3<<1 | c3>>(64-1))
r[2] = a[2] ^ d
r[7] = a[7] ^ d
r[12] = a[12] ^ d
r[17] = a[17] ^ d
r[22] = a[22] ^ d
d = c2 ^ (c4<<1 | c4>>(64-1))
r[3] = a[3] ^ d
r[8] = a[8] ^ d
r[13] = a[13] ^ d
r[18] = a[18] ^ d
r[23] = a[23] ^ d
d = c3 ^ (c0<<1 | c0>>(64-1))
r[4] = a[4] ^ d
r[9] = a[9] ^ d
r[14] = a[14] ^ d
r[19] = a[19] ^ d
r[24] = a[24] ^ d
return r
}

+ 48
- 0
go-keccak256-bits-impl/stepmappings.go

@ -0,0 +1,48 @@
package keccak
func theta(a [25 * 64]bool) [25 * 64]bool {
var c0, c1, c2, c3, c4, d [64]bool
var r [25 * 64]bool
copy(c0[:], xor(xor(xor(xor(a[0:1*64], a[5*64:6*64]), a[10*64:11*64]), a[15*64:16*64]), a[20*64:21*64]))
copy(c1[:], xor(xor(xor(xor(a[1*64:2*64], a[6*64:7*64]), a[11*64:12*64]), a[16*64:17*64]), a[21*64:22*64]))
copy(c2[:], xor(xor(xor(xor(a[2*64:3*64], a[7*64:8*64]), a[12*64:13*64]), a[17*64:18*64]), a[22*64:23*64]))
copy(c3[:], xor(xor(xor(xor(a[3*64:4*64], a[8*64:9*64]), a[13*64:14*64]), a[18*64:19*64]), a[23*64:24*64]))
copy(c4[:], xor(xor(xor(xor(a[4*64:5*64], a[9*64:10*64]), a[14*64:15*64]), a[19*64:20*64]), a[24*64:25*64]))
copy(d[:], xor(c4[:], or(leftShift(c1[:], 1), rightShift(c1[:], (64-1)))))
copy(r[0:1*64], xor(a[0:1*64], d[:]))
copy(r[5*64:6*64], xor(a[5*64:6*64], d[:]))
copy(r[10*64:11*64], xor(a[10*64:11*64], d[:]))
copy(r[15*64:16*64], xor(a[15*64:16*64], d[:]))
copy(r[20*64:21*64], xor(a[20*64:21*64], d[:]))
copy(d[:], xor(c0[:], or(leftShift(c2[:], 1), rightShift(c2[:], (64-1)))))
copy(r[1*64:2*64], xor(a[1*64:2*64], d[:]))
copy(r[6*64:7*64], xor(a[6*64:7*64], d[:]))
copy(r[11*64:12*64], xor(a[11*64:12*64], d[:]))
copy(r[16*64:17*64], xor(a[16*64:17*64], d[:]))
copy(r[21*64:22*64], xor(a[21*64:22*64], d[:]))
copy(d[:], xor(c1[:], or(leftShift(c3[:], 1), rightShift(c3[:], (64-1)))))
copy(r[2*64:3*64], xor(a[2*64:3*64], d[:]))
copy(r[7*64:8*64], xor(a[7*64:8*64], d[:]))
copy(r[12*64:13*64], xor(a[12*64:13*64], d[:]))
copy(r[17*64:18*64], xor(a[17*64:18*64], d[:]))
copy(r[22*64:23*64], xor(a[22*64:23*64], d[:]))
copy(d[:], xor(c2[:], or(leftShift(c4[:], 1), rightShift(c4[:], (64-1)))))
copy(r[3*64:4*64], xor(a[3*64:4*64], d[:]))
copy(r[8*64:9*64], xor(a[8*64:9*64], d[:]))
copy(r[13*64:14*64], xor(a[13*64:14*64], d[:]))
copy(r[18*64:19*64], xor(a[18*64:19*64], d[:]))
copy(r[23*64:24*64], xor(a[23*64:24*64], d[:]))
copy(d[:], xor(c3[:], or(leftShift(c0[:], 1), rightShift(c0[:], (64-1)))))
copy(r[4*64:5*64], xor(a[4*64:5*64], d[:]))
copy(r[9*64:10*64], xor(a[9*64:10*64], d[:]))
copy(r[14*64:15*64], xor(a[14*64:15*64], d[:]))
copy(r[19*64:20*64], xor(a[19*64:20*64], d[:]))
copy(r[24*64:25*64], xor(a[24*64:25*64], d[:]))
return r
}

+ 43
- 0
go-keccak256-bits-impl/stepmappings_test.go

@ -0,0 +1,43 @@
package keccak
import (
"encoding/json"
"fmt"
"testing"
qt "github.com/frankban/quicktest"
)
func printS(n string, s []uint64) {
jS, err := json.Marshal(s)
if err != nil {
panic(err)
}
fmt.Printf("%s: %s\n", n, string(jS))
}
func newS() ([25 * 64]bool, [25]uint64) {
var s [25 * 64]bool
var sU64 [25]uint64
for i := 0; i < len(s)/64; i++ {
copy(s[i*64:i*64+64], u64ToBits(uint64(i)))
sU64[i] = uint64(i)
}
return s, sU64
}
func TestTheta(t *testing.T) {
s, sU64 := newS()
s = theta(s)
sU64 = thetaU64Version(sU64)
qt.Assert(t, bitsToU64Array(s[:]), qt.DeepEquals, sU64[:])
qt.Assert(t, bitsToU64Array(s[:]), qt.DeepEquals,
[]uint64{26, 9, 13, 29, 47, 31, 14, 8, 22, 34, 16, 3, 3,
19, 37, 21, 24, 30, 12, 56, 14, 29, 25, 9, 51})
// compute again theta on the current state
s = theta(s)
sU64 = thetaU64Version(sU64)
qt.Assert(t, bitsToU64Array(s[:]), qt.DeepEquals, sU64[:])
}

Loading…
Cancel
Save