diff options
| author | Frank Denis <github@pureftpd.org> | 2020-10-11 13:05:59 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-10-16 18:41:11 -0400 |
| commit | 0b4a5254fa7ab43315d99790d0256b8527164faa (patch) | |
| tree | 593fe7c0b1c66b9537704bada036099c5dccd8fb /lib/std | |
| parent | f78380b936de862476ea6b3cc3e8d4ba4562c7fa (diff) | |
| download | zig-0b4a5254fa7ab43315d99790d0256b8527164faa.tar.gz zig-0b4a5254fa7ab43315d99790d0256b8527164faa.zip | |
Vectorize Gimli
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/crypto/gimli.zig | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/lib/std/crypto/gimli.zig b/lib/std/crypto/gimli.zig index 07cbb5d40b..c68bd0abb5 100644 --- a/lib/std/crypto/gimli.zig +++ b/lib/std/crypto/gimli.zig @@ -19,12 +19,13 @@ const debug = std.debug; const assert = std.debug.assert; const testing = std.testing; const htest = @import("test.zig"); +const Vector = std.meta.Vector; pub const State = struct { pub const BLOCKBYTES = 48; pub const RATE = 16; - data: [BLOCKBYTES / 4]u32, + data: [BLOCKBYTES / 4]u32 align(16), const Self = @This(); @@ -103,7 +104,57 @@ pub const State = struct { } } - pub const permute = if (std.builtin.mode == .ReleaseSmall) permute_small else permute_unrolled; + const Lane = Vector(4, u32); + + inline fn shift(x: Lane, comptime n: comptime_int) Lane { + return x << @splat(4, @as(u5, n)); + } + + inline fn rot(x: Lane, comptime n: comptime_int) Lane { + return (x << @splat(4, @as(u5, n))) | (x >> @splat(4, @as(u5, 32 - n))); + } + + fn permute_vectorized(self: *Self) void { + const state = &self.data; + var x = Lane{ state[0], state[1], state[2], state[3] }; + var y = Lane{ state[4], state[5], state[6], state[7] }; + var z = Lane{ state[8], state[9], state[10], state[11] }; + var round = @as(u32, 24); + while (round > 0) : (round -= 1) { + x = rot(x, 24); + y = rot(y, 9); + const newz = x ^ shift(z, 1) ^ shift(y & z, 2); + const newy = y ^ x ^ shift(x | z, 1); + const newx = z ^ y ^ shift(x & y, 3); + x = newx; + y = newy; + z = newz; + switch (round & 3) { + 0 => { + x = @shuffle(u32, x, undefined, [_]i32{ 1, 0, 3, 2 }); + x[0] ^= round | 0x9e377900; + }, + 2 => { + x = @shuffle(u32, x, undefined, [_]i32{ 2, 3, 0, 1 }); + }, + else => {}, + } + } + comptime var i: usize = 0; + inline while (i < 4) : (i += 1) { + state[0 + i] = x[i]; + state[4 + i] = y[i]; + state[8 + i] = z[i]; + } + } + + pub const permute = if (std.Target.current.cpu.arch == .x86_64) impl: { + break :impl permute_vectorized; + } else if (std.builtin.mode == .ReleaseSmall) impl: { + break :impl permute_small; + } else impl: { + break :impl permute_unrolled; + }; pub fn squeeze(self: *Self, out: []u8) void { var i = @as(usize, 0); |
