authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-09-28 23:23:32+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-09-29 00:29:20+02:00
log868a46eb43e68971634c046c8317c1b83cae21ae
tree26d2b972569d5ef088cc380f242d77b1c093c576
parent5c6cd5e2c9e8b2d0feb0026bad7c201035a175b4

std/crypto: make gimli slightly faster

Before: gimli-hash: 120 MiB/s gimli-aead: 130 MiB/s After: gimli-hash: 195 MiB/s gimli-aead: 208 MiB/s Also fixes in-place decryption by the way. If the input & output buffers were the same, decryption used to fail. Return on decryption error in the benchmark to detect similar issues in future AEADs even in non release-fast mode.

2 files changed, 22 insertions(+), 14 deletions(-)

lib/std/crypto/benchmark.zig+1-1
...@@ -168,7 +168,7 @@ pub fn benchmarkAead(comptime Aead: anytype, comptime bytes: comptime_int) !u64...@@ -168,7 +168,7 @@ pub fn benchmarkAead(comptime Aead: anytype, comptime bytes: comptime_int) !u64
168 const start = timer.lap();168 const start = timer.lap();
169 while (offset < bytes) : (offset += in.len) {169 while (offset < bytes) : (offset += in.len) {
170 Aead.encrypt(in[0..], tag[0..], in[0..], &[_]u8{}, nonce, key);170 Aead.encrypt(in[0..], tag[0..], in[0..], &[_]u8{}, nonce, key);
171 Aead.decrypt(in[0..], in[0..], tag, &[_]u8{}, nonce, key) catch unreachable;171 try Aead.decrypt(in[0..], in[0..], tag, &[_]u8{}, nonce, key);
172 }172 }
173 mem.doNotOptimizeAway(&in);173 mem.doNotOptimizeAway(&in);
174 const end = timer.read();174 const end = timer.read();
lib/std/crypto/gimli.zig+21-13
...@@ -40,8 +40,8 @@ pub const State = struct {...@@ -40,8 +40,8 @@ pub const State = struct {
4040
41 pub fn permute(self: *Self) void {41 pub fn permute(self: *Self) void {
42 const state = &self.data;42 const state = &self.data;
43 var round = @as(u32, 24);43 comptime var round = @as(u32, 24);
44 while (round > 0) : (round -= 1) {44 inline while (round > 0) : (round -= 1) {
45 var column = @as(usize, 0);45 var column = @as(usize, 0);
46 while (column < 4) : (column += 1) {46 while (column < 4) : (column += 1) {
47 const x = math.rotl(u32, state[column], 24);47 const x = math.rotl(u32, state[column], 24);
...@@ -249,15 +249,19 @@ pub const Aead = struct {...@@ -249,15 +249,19 @@ pub const Aead = struct {
249 in = in[State.RATE..];249 in = in[State.RATE..];
250 out = out[State.RATE..];250 out = out[State.RATE..];
251 }) {251 }) {
252 for (buf[0..State.RATE]) |*p, i| {252 const d = in[0..State.RATE];
253 p.* ^= in[i];253 for (d) |v, i| {
254 out[i] = p.*;254 buf[i] ^= v;
255 }
256 for (d) |_, i| {
257 out[i] = buf[i];
255 }258 }
256 state.permute();259 state.permute();
257 }260 }
258 for (buf[0..in.len]) |*p, i| {261 const d = in[0..];
259 p.* ^= in[i];262 for (d) |v, i| {
260 out[i] = p.*;263 buf[i] ^= v;
264 out[i] = buf[i];
261 }265 }
262266
263 // XOR 1 into the next byte of the state267 // XOR 1 into the next byte of the state
...@@ -291,15 +295,19 @@ pub const Aead = struct {...@@ -291,15 +295,19 @@ pub const Aead = struct {
291 in = in[State.RATE..];295 in = in[State.RATE..];
292 out = out[State.RATE..];296 out = out[State.RATE..];
293 }) {297 }) {
294 for (buf[0..State.RATE]) |*p, i| {298 const d = in[0..State.RATE].*;
295 out[i] = p.* ^ in[i];299 for (d) |v, i| {
296 p.* = in[i];300 out[i] = buf[i] ^ v;
301 }
302 for (d) |v, i| {
303 buf[i] = v;
297 }304 }
298 state.permute();305 state.permute();
299 }306 }
300 for (buf[0..in.len]) |*p, i| {307 for (buf[0..in.len]) |*p, i| {
301 out[i] = p.* ^ in[i];308 const d = in[i];
302 p.* = in[i];309 out[i] = p.* ^ d;
310 p.* = d;
303 }311 }
304312
305 // XOR 1 into the next byte of the state313 // XOR 1 into the next byte of the state