Skip to content

Commit 71bca15

Browse files
authored
double keccak speed (#80)
nim-lang/Nim#23688 causes the implementation to fall into the `when nimvm` versions of THETA1, CHI etc - these operate on openArray and get interspersed with range checks and other random inefficiencies. This fix doubles the speed of the 256-bit keccak.
1 parent 485f7b3 commit 71bca15

File tree

1 file changed

+54
-53
lines changed

1 file changed

+54
-53
lines changed

nimcrypto/keccak.nim

+54-53
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,30 @@ type
5757
# This difference in implementation was made because Nim VM do not support more
5858
# then 256 registers and so it is not enough for it to perform round in
5959
# template.
60+
# See also https://github.com/nim-lang/Nim/issues/23688
6061
when nimvm:
61-
proc THETA1(a: var openArray[uint64], b: openArray[uint64],
62-
c: int) {.inline.} =
62+
proc THETA1V(a: var openArray[uint64], b: openArray[uint64],
63+
c: int) {.inline.} =
6364
a[c] = b[c] xor b[c + 5] xor b[c + 10] xor b[c + 15] xor b[c + 20]
6465

65-
proc THETA2(a: var uint64, b: openArray[uint64], c: int) {.inline.} =
66+
proc THETA2V(a: var uint64, b: openArray[uint64], c: int) {.inline.} =
6667
a = b[(c + 4) mod 5] xor ROL(uint64(b[(c + 1) mod 5]), 1)
6768

68-
proc THETA3(a: var openArray[uint64], b: int, c: uint64) {.inline.} =
69+
proc THETA3V(a: var openArray[uint64], b: int, c: uint64) {.inline.} =
6970
a[b] = a[b] xor c
7071
a[b + 5] = a[b + 5] xor c
7172
a[b + 10] = a[b + 10] xor c
7273
a[b + 15] = a[b + 15] xor c
7374
a[b + 20] = a[b + 20] xor c
7475

75-
proc RHOPI(a: var openArray[uint64], b: var openArray[uint64], c: var uint64,
76+
proc RHOPIV(a: var openArray[uint64], b: var openArray[uint64], c: var uint64,
7677
d, e: int) {.inline.} =
7778
a[0] = b[d]
7879
b[d] = ROL(c, e)
7980
c = uint64(a[0])
8081

81-
proc CHI(a: var openArray[uint64], b: var openArray[uint64],
82-
c: int) {.inline.} =
82+
proc CHIV(a: var openArray[uint64], b: var openArray[uint64],
83+
c: int) {.inline.} =
8384
a[0] = b[c]
8485
a[1] = b[c + 1]
8586
a[2] = b[c + 2]
@@ -94,54 +95,54 @@ when nimvm:
9495

9596
proc KECCAKROUNDP(a: var openArray[uint64], b: var openArray[uint64],
9697
c: var uint64, r: int) {.inline.} =
97-
THETA1(b, a, 0)
98-
THETA1(b, a, 1)
99-
THETA1(b, a, 2)
100-
THETA1(b, a, 3)
101-
THETA1(b, a, 4)
102-
103-
THETA2(c, b, 0)
104-
THETA3(a, 0, c)
105-
THETA2(c, b, 1)
106-
THETA3(a, 1, c)
107-
THETA2(c, b, 2)
108-
THETA3(a, 2, c)
109-
THETA2(c, b, 3)
110-
THETA3(a, 3, c)
111-
THETA2(c, b, 4)
112-
THETA3(a, 4, c)
98+
THETA1V(b, a, 0)
99+
THETA1V(b, a, 1)
100+
THETA1V(b, a, 2)
101+
THETA1V(b, a, 3)
102+
THETA1V(b, a, 4)
103+
104+
THETA2V(c, b, 0)
105+
THETA3V(a, 0, c)
106+
THETA2V(c, b, 1)
107+
THETA3V(a, 1, c)
108+
THETA2V(c, b, 2)
109+
THETA3V(a, 2, c)
110+
THETA2V(c, b, 3)
111+
THETA3V(a, 3, c)
112+
THETA2V(c, b, 4)
113+
THETA3V(a, 4, c)
113114

114115
c = a[1]
115-
RHOPI(b, a, c, 10, 1)
116-
RHOPI(b, a, c, 7, 3)
117-
RHOPI(b, a, c, 11, 6)
118-
RHOPI(b, a, c, 17, 10)
119-
RHOPI(b, a, c, 18, 15)
120-
RHOPI(b, a, c, 3, 21)
121-
RHOPI(b, a, c, 5, 28)
122-
RHOPI(b, a, c, 16, 36)
123-
RHOPI(b, a, c, 8, 45)
124-
RHOPI(b, a, c, 21, 55)
125-
RHOPI(b, a, c, 24, 2)
126-
RHOPI(b, a, c, 4, 14)
127-
RHOPI(b, a, c, 15, 27)
128-
RHOPI(b, a, c, 23, 41)
129-
RHOPI(b, a, c, 19, 56)
130-
RHOPI(b, a, c, 13, 8)
131-
RHOPI(b, a, c, 12, 25)
132-
RHOPI(b, a, c, 2, 43)
133-
RHOPI(b, a, c, 20, 62)
134-
RHOPI(b, a, c, 14, 18)
135-
RHOPI(b, a, c, 22, 39)
136-
RHOPI(b, a, c, 9, 61)
137-
RHOPI(b, a, c, 6, 20)
138-
RHOPI(b, a, c, 1, 44)
139-
140-
CHI(b, a, 0)
141-
CHI(b, a, 5)
142-
CHI(b, a, 10)
143-
CHI(b, a, 15)
144-
CHI(b, a, 20)
116+
RHOPIV(b, a, c, 10, 1)
117+
RHOPIV(b, a, c, 7, 3)
118+
RHOPIV(b, a, c, 11, 6)
119+
RHOPIV(b, a, c, 17, 10)
120+
RHOPIV(b, a, c, 18, 15)
121+
RHOPIV(b, a, c, 3, 21)
122+
RHOPIV(b, a, c, 5, 28)
123+
RHOPIV(b, a, c, 16, 36)
124+
RHOPIV(b, a, c, 8, 45)
125+
RHOPIV(b, a, c, 21, 55)
126+
RHOPIV(b, a, c, 24, 2)
127+
RHOPIV(b, a, c, 4, 14)
128+
RHOPIV(b, a, c, 15, 27)
129+
RHOPIV(b, a, c, 23, 41)
130+
RHOPIV(b, a, c, 19, 56)
131+
RHOPIV(b, a, c, 13, 8)
132+
RHOPIV(b, a, c, 12, 25)
133+
RHOPIV(b, a, c, 2, 43)
134+
RHOPIV(b, a, c, 20, 62)
135+
RHOPIV(b, a, c, 14, 18)
136+
RHOPIV(b, a, c, 22, 39)
137+
RHOPIV(b, a, c, 9, 61)
138+
RHOPIV(b, a, c, 6, 20)
139+
RHOPIV(b, a, c, 1, 44)
140+
141+
CHIV(b, a, 0)
142+
CHIV(b, a, 5)
143+
CHIV(b, a, 10)
144+
CHIV(b, a, 15)
145+
CHIV(b, a, 20)
145146

146147
a[0] = a[0] xor RNDC[r]
147148

0 commit comments

Comments
 (0)