authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-03-10 10:00:07+13:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-03-10 10:00:07+13:00
log7a893691c0aedf4d7ae68a9eb06800e4094381cc
treea1f4315923fb78ff938edeb6d5bd124b47a1bb5d
parent5a7a0e8518bcb9e63c06dba21d9c9e2bb0827330

Unroll Sha3 inner loop

Issue #699 since fixed. Nearly a x3 perf improvement. Using --release-fast. Sha3_256 (before): 96 Mb/s Sha3_256 (after): 267 Mb/s Sha3_512 (before): 53 Mb/s Sha3_512 (after): 142 Mb/s No real gains from unrolling other initialization loops in crypto functions so have been left as is.

3 files changed, 10 insertions(+), 14 deletions(-)

std/crypto/md5.zig-1
......@@ -108,7 +108,6 @@ pub const Md5 = struct {
108108
109109 var s: [16]u32 = undefined;
110110
111 // ERROR: cannot unroll this at comptime
112111 var i: usize = 0;
113112 while (i < 16) : (i += 1) {
114113 // NOTE: Performing or's separately improves perf by ~10%
std/crypto/sha2.zig-2
......@@ -156,7 +156,6 @@ fn Sha2_32(comptime params: Sha2Params32) type { return struct {
156156
157157 var s: [64]u32 = undefined;
158158
159 // ERROR: Cannot unroll at compile-time.
160159 var i: usize = 0;
161160 while (i < 16) : (i += 1) {
162161 s[i] = 0;
......@@ -472,7 +471,6 @@ fn Sha2_64(comptime params: Sha2Params64) type { return struct {
472471
473472 var s: [80]u64 = undefined;
474473
475 // ERROR: Cannot unroll at compile-time.
476474 var i: usize = 0;
477475 while (i < 16) : (i += 1) {
478476 s[i] = 0;
std/crypto/sha3.zig+10-11
......@@ -123,35 +123,34 @@ fn keccak_f(comptime F: usize, d: []u8) void {
123123 *r = mem.readIntLE(u64, d[8*i .. 8*i + 8]);
124124 }
125125
126 var x: usize = 0;
127 var y: usize = 0;
128 // TODO: Cannot unroll all loops here due to comptime differences.
129 inline for (RC[0..no_rounds]) |round| {
126 comptime var x: usize = 0;
127 comptime var y: usize = 0;
128 for (RC[0..no_rounds]) |round| {
130129 // theta
131 x = 0; while (x < 5) : (x += 1) {
130 x = 0; inline while (x < 5) : (x += 1) {
132131 c[x] = s[x] ^ s[x+5] ^ s[x+10] ^ s[x+15] ^ s[x+20];
133132 }
134 x = 0; while (x < 5) : (x += 1) {
133 x = 0; inline while (x < 5) : (x += 1) {
135134 t[0] = c[M5[x+4]] ^ math.rotl(u64, c[M5[x+1]], usize(1));
136 y = 0; while (y < 5) : (y += 1) {
135 y = 0; inline while (y < 5) : (y += 1) {
137136 s[x + y*5] ^= t[0];
138137 }
139138 }
140139
141140 // rho+pi
142141 t[0] = s[1];
143 x = 0; while (x < 24) : (x += 1) {
142 x = 0; inline while (x < 24) : (x += 1) {
144143 c[0] = s[PIL[x]];
145144 s[PIL[x]] = math.rotl(u64, t[0], ROTC[x]);
146145 t[0] = c[0];
147146 }
148147
149148 // chi
150 y = 0; while (y < 5) : (y += 1) {
151 x = 0; while (x < 5) : (x += 1) {
149 y = 0; inline while (y < 5) : (y += 1) {
150 x = 0; inline while (x < 5) : (x += 1) {
152151 c[x] = s[x + y*5];
153152 }
154 x = 0; while (x < 5) : (x += 1) {
153 x = 0; inline while (x < 5) : (x += 1) {
155154 s[x + y*5] = c[x] ^ (~c[M5[x+1]] & c[M5[x+2]]);
156155 }
157156 }