authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-10-11 13:05:59+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-10-16 18:41:11-04:00
log0b4a5254fa7ab43315d99790d0256b8527164faa
tree593fe7c0b1c66b9537704bada036099c5dccd8fb
parentf78380b936de862476ea6b3cc3e8d4ba4562c7fa

Vectorize Gimli


1 files changed, 53 insertions(+), 2 deletions(-)

lib/std/crypto/gimli.zig+53-2
......@@ -19,12 +19,13 @@ const debug = std.debug;
1919const assert = std.debug.assert;
2020const testing = std.testing;
2121const htest = @import("test.zig");
22const Vector = std.meta.Vector;
2223
2324pub const State = struct {
2425 pub const BLOCKBYTES = 48;
2526 pub const RATE = 16;
2627
27 data: [BLOCKBYTES / 4]u32,
28 data: [BLOCKBYTES / 4]u32 align(16),
2829
2930 const Self = @This();
3031
......@@ -103,7 +104,57 @@ pub const State = struct {
103104 }
104105 }
105106
106 pub const permute = if (std.builtin.mode == .ReleaseSmall) permute_small else permute_unrolled;
107 const Lane = Vector(4, u32);
108
109 inline fn shift(x: Lane, comptime n: comptime_int) Lane {
110 return x << @splat(4, @as(u5, n));
111 }
112
113 inline fn rot(x: Lane, comptime n: comptime_int) Lane {
114 return (x << @splat(4, @as(u5, n))) | (x >> @splat(4, @as(u5, 32 - n)));
115 }
116
117 fn permute_vectorized(self: *Self) void {
118 const state = &self.data;
119 var x = Lane{ state[0], state[1], state[2], state[3] };
120 var y = Lane{ state[4], state[5], state[6], state[7] };
121 var z = Lane{ state[8], state[9], state[10], state[11] };
122 var round = @as(u32, 24);
123 while (round > 0) : (round -= 1) {
124 x = rot(x, 24);
125 y = rot(y, 9);
126 const newz = x ^ shift(z, 1) ^ shift(y & z, 2);
127 const newy = y ^ x ^ shift(x | z, 1);
128 const newx = z ^ y ^ shift(x & y, 3);
129 x = newx;
130 y = newy;
131 z = newz;
132 switch (round & 3) {
133 0 => {
134 x = @shuffle(u32, x, undefined, [_]i32{ 1, 0, 3, 2 });
135 x[0] ^= round | 0x9e377900;
136 },
137 2 => {
138 x = @shuffle(u32, x, undefined, [_]i32{ 2, 3, 0, 1 });
139 },
140 else => {},
141 }
142 }
143 comptime var i: usize = 0;
144 inline while (i < 4) : (i += 1) {
145 state[0 + i] = x[i];
146 state[4 + i] = y[i];
147 state[8 + i] = z[i];
148 }
149 }
150
151 pub const permute = if (std.Target.current.cpu.arch == .x86_64) impl: {
152 break :impl permute_vectorized;
153 } else if (std.builtin.mode == .ReleaseSmall) impl: {
154 break :impl permute_small;
155 } else impl: {
156 break :impl permute_unrolled;
157 };
107158
108159 pub fn squeeze(self: *Self, out: []u8) void {
109160 var i = @as(usize, 0);