From a7aea7105ec97781d96eba53aa92cc26864dab68 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sun, 31 Oct 2021 12:52:16 +0100 Subject: [PATCH] Add Rho & Pi go impl --- README.md | 2 + go-keccak256-bits-impl/ref.go | 35 ++++++- go-keccak256-bits-impl/stepmappings.go | 104 ++++++++++++++++++++ go-keccak256-bits-impl/stepmappings_test.go | 20 ++++ 4 files changed, 159 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ee9b375..5e15cf9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # keccak256-circom +Spec: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + WIP repo. Once ready, will do a PR into [circomlib](https://github.com/iden3/circomlib). diff --git a/go-keccak256-bits-impl/ref.go b/go-keccak256-bits-impl/ref.go index cac71c1..52426ec 100644 --- a/go-keccak256-bits-impl/ref.go +++ b/go-keccak256-bits-impl/ref.go @@ -1,6 +1,7 @@ /* -This file contains the byte & uint64 implementations that are used to test the -bits implementations. +This file contains the byte & uint64 implementations that are used as reference +to test the bits implementations of the other files. +The methods in this file are modifyied versions of methods from: https://github.com/ebfe/keccak */ package keccak @@ -49,3 +50,33 @@ func thetaU64Version(a [25]uint64) [25]uint64 { r[24] = a[24] ^ d return r } + +func rhopiU64Version(a [25]uint64) [25]uint64 { + var t uint64 + t = a[1] + t, a[10] = a[10], t<<1|t>>(64-1) + t, a[7] = a[7], t<<3|t>>(64-3) + t, a[11] = a[11], t<<6|t>>(64-6) + t, a[17] = a[17], t<<10|t>>(64-10) + t, a[18] = a[18], t<<15|t>>(64-15) + t, a[3] = a[3], t<<21|t>>(64-21) + t, a[5] = a[5], t<<28|t>>(64-28) + t, a[16] = a[16], t<<36|t>>(64-36) + t, a[8] = a[8], t<<45|t>>(64-45) + t, a[21] = a[21], t<<55|t>>(64-55) + t, a[24] = a[24], t<<2|t>>(64-2) + t, a[4] = a[4], t<<14|t>>(64-14) + t, a[15] = a[15], t<<27|t>>(64-27) + t, a[23] = a[23], t<<41|t>>(64-41) + t, a[19] = a[19], t<<56|t>>(64-56) + t, a[13] = a[13], t<<8|t>>(64-8) + t, a[12] = a[12], t<<25|t>>(64-25) + t, a[2] = a[2], t<<43|t>>(64-43) + t, a[20] = a[20], t<<62|t>>(64-62) + t, a[14] = a[14], t<<18|t>>(64-18) + t, a[22] = a[22], t<<39|t>>(64-39) + t, a[9] = a[9], t<<61|t>>(64-61) + t, a[6] = a[6], t<<20|t>>(64-20) + a[1] = t<<44 | t>>(64-44) + return a +} diff --git a/go-keccak256-bits-impl/stepmappings.go b/go-keccak256-bits-impl/stepmappings.go index dd98b68..24ae8e4 100644 --- a/go-keccak256-bits-impl/stepmappings.go +++ b/go-keccak256-bits-impl/stepmappings.go @@ -46,3 +46,107 @@ func theta(a [25 * 64]bool) [25 * 64]bool { copy(r[24*64:25*64], xor(a[24*64:25*64], d[:])) return r } + +func rhopi(a [25 * 64]bool) [25 * 64]bool { + var t, tAux [64]bool + var r [25 * 64]bool + + copy(r[0:1*64], a[0:1*64]) + + copy(t[:], a[1*64:2*64]) + + copy(tAux[:], a[10*64:11*64]) + copy(r[10*64:11*64], or(leftShift(t[:], 1), rightShift(t[:], 64-1))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[7*64:8*64]) + copy(r[7*64:8*64], or(leftShift(t[:], 3), rightShift(t[:], 64-3))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[11*64:12*64]) + copy(r[11*64:12*64], or(leftShift(t[:], 6), rightShift(t[:], 64-6))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[17*64:18*64]) + copy(r[17*64:18*64], or(leftShift(t[:], 10), rightShift(t[:], 64-10))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[18*64:19*64]) + copy(r[18*64:19*64], or(leftShift(t[:], 15), rightShift(t[:], 64-15))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[3*64:4*64]) + copy(r[3*64:4*64], or(leftShift(t[:], 21), rightShift(t[:], 64-21))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[5*64:6*64]) + copy(r[5*64:6*64], or(leftShift(t[:], 28), rightShift(t[:], 64-28))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[16*64:17*64]) + copy(r[16*64:17*64], or(leftShift(t[:], 36), rightShift(t[:], 64-36))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[8*64:9*64]) + copy(r[8*64:9*64], or(leftShift(t[:], 45), rightShift(t[:], 64-45))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[21*64:22*64]) + copy(r[21*64:22*64], or(leftShift(t[:], 55), rightShift(t[:], 64-55))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[24*64:25*64]) + copy(r[24*64:25*64], or(leftShift(t[:], 2), rightShift(t[:], 64-2))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[4*64:5*64]) + copy(r[4*64:5*64], or(leftShift(t[:], 14), rightShift(t[:], 64-14))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[15*64:16*64]) + copy(r[15*64:16*64], or(leftShift(t[:], 27), rightShift(t[:], 64-27))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[23*64:24*64]) + copy(r[23*64:24*64], or(leftShift(t[:], 41), rightShift(t[:], 64-41))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[19*64:20*64]) + copy(r[19*64:20*64], or(leftShift(t[:], 56), rightShift(t[:], 64-56))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[13*64:14*64]) + copy(r[13*64:14*64], or(leftShift(t[:], 8), rightShift(t[:], 64-8))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[12*64:13*64]) + copy(r[12*64:13*64], or(leftShift(t[:], 25), rightShift(t[:], 64-25))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[2*64:3*64]) + copy(r[2*64:3*64], or(leftShift(t[:], 43), rightShift(t[:], 64-43))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[20*64:21*64]) + copy(r[20*64:21*64], or(leftShift(t[:], 62), rightShift(t[:], 64-62))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[14*64:15*64]) + copy(r[14*64:15*64], or(leftShift(t[:], 18), rightShift(t[:], 64-18))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[22*64:23*64]) + copy(r[22*64:23*64], or(leftShift(t[:], 39), rightShift(t[:], 64-39))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[9*64:10*64]) + copy(r[9*64:10*64], or(leftShift(t[:], 61), rightShift(t[:], 64-61))) + copy(t[:], tAux[:]) + + copy(tAux[:], a[6*64:7*64]) + copy(r[6*64:7*64], or(leftShift(t[:], 20), rightShift(t[:], 64-20))) + copy(t[:], tAux[:]) + + copy(r[1*64:2*64], or(leftShift(t[:], 44), rightShift(t[:], 64-44))) + return r +} diff --git a/go-keccak256-bits-impl/stepmappings_test.go b/go-keccak256-bits-impl/stepmappings_test.go index 04701f7..9158417 100644 --- a/go-keccak256-bits-impl/stepmappings_test.go +++ b/go-keccak256-bits-impl/stepmappings_test.go @@ -41,3 +41,23 @@ func TestTheta(t *testing.T) { sU64 = thetaU64Version(sU64) qt.Assert(t, bitsToU64Array(s[:]), qt.DeepEquals, sU64[:]) } + +func TestRhoPi(t *testing.T) { + s, sU64 := newS() + + s = rhopi(s) + sU64 = rhopiU64Version(sU64) + + qt.Assert(t, bitsToU64Array(s[:]), qt.DeepEquals, sU64[:]) + qt.Assert(t, bitsToU64Array(s[:]), qt.DeepEquals, + []uint64{0, 105553116266496, 105553116266496, 37748736, 393216, + 805306368, 9437184, 80, 562949953421312, 13835058055282163714, + 2, 448, 436207616, 4864, 5242880, 536870912, 343597383680, + 11264, 557056, 1657324662872342528, 9223372036854775808, + 288230376151711744, 7696581394432, 32985348833280, 84}) + + // compute again rhopi on the current state + s = rhopi(s) + sU64 = rhopiU64Version(sU64) + qt.Assert(t, bitsToU64Array(s[:]), qt.DeepEquals, sU64[:]) +}