authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-07 18:06:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-07 18:06:55-07:00
loge579c88f4ca6deaff53f0d1d226fdfc8715f85ac
treeef5d024a714d15e9c87f7cd82b714ad836a70230
parent87b223428a8953b6af9bea61ff4cc905821c0557

std.crypto.siphash: add finalResult() and peek()

Useful for avoiding mutable state when using this API.

1 files changed, 22 insertions(+), 0 deletions(-)

lib/std/crypto/siphash.zig+22
...@@ -87,6 +87,11 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round...@@ -87,6 +87,11 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
87 self.msg_len +%= @truncate(u8, b.len);87 self.msg_len +%= @truncate(u8, b.len);
88 }88 }
8989
90 pub fn peek(self: Self) [digest_length]u8 {
91 var copy = self;
92 return copy.finalResult();
93 }
94
90 pub fn final(self: *Self, b: []const u8) T {95 pub fn final(self: *Self, b: []const u8) T {
91 std.debug.assert(b.len < 8);96 std.debug.assert(b.len < 8);
9297
...@@ -124,6 +129,12 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round...@@ -124,6 +129,12 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
124 return (@as(u128, b2) << 64) | b1;129 return (@as(u128, b2) << 64) | b1;
125 }130 }
126131
132 pub fn finalResult(self: *Self) [digest_length]u8 {
133 var result: [digest_length]u8 = undefined;
134 self.final(&result);
135 return result;
136 }
137
127 fn round(self: *Self, b: [8]u8) void {138 fn round(self: *Self, b: [8]u8) void {
128 const m = mem.readIntLittle(u64, b[0..8]);139 const m = mem.readIntLittle(u64, b[0..8]);
129 self.v3 ^= m;140 self.v3 ^= m;
...@@ -205,12 +216,23 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)...@@ -205,12 +216,23 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
205 self.buf_len += @intCast(u8, b[off + aligned_len ..].len);216 self.buf_len += @intCast(u8, b[off + aligned_len ..].len);
206 }217 }
207218
219 pub fn peek(self: Self) [mac_length]u8 {
220 var copy = self;
221 return copy.finalResult();
222 }
223
208 /// Return an authentication tag for the current state224 /// Return an authentication tag for the current state
209 /// Assumes `out` is less than or equal to `mac_length`.225 /// Assumes `out` is less than or equal to `mac_length`.
210 pub fn final(self: *Self, out: *[mac_length]u8) void {226 pub fn final(self: *Self, out: *[mac_length]u8) void {
211 mem.writeIntLittle(T, out, self.state.final(self.buf[0..self.buf_len]));227 mem.writeIntLittle(T, out, self.state.final(self.buf[0..self.buf_len]));
212 }228 }
213229
230 pub fn finalResult(self: *Self) [mac_length]u8 {
231 var result: [mac_length]u8 = undefined;
232 self.final(&result);
233 return result;
234 }
235
214 /// Return an authentication tag for a message and a key236 /// Return an authentication tag for a message and a key
215 pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void {237 pub fn create(out: *[mac_length]u8, msg: []const u8, key: *const [key_length]u8) void {
216 var ctx = Self.init(key);238 var ctx = Self.init(key);