authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2022-12-30 23:15:25+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-12-30 22:15:25+00:00
logd86685ac9612c08e33f1d94f7f617d9c0da1b7bd
treeebfd508ec57baa6df1f9ead511bf0c277728bcc8
parente2d7b2bf339dac811b9ae77638f1d29b2ab32a23
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

sha3: define block_length as the rate, not as the state size (#14132)

In sponge-based constructions, the block size is not the same as the state size. For practical purposes, it's the same as the rate. Size this is a constant for a given type, we don't need to keep a copy of that value in the state itself. Just use the constant directly. This saves some bytes and may even be slightly faster. More importantly: Fixes #14128

1 files changed, 12 insertions(+), 10 deletions(-)

lib/std/crypto/sha3.zig+12-10
......@@ -14,17 +14,19 @@ pub const Keccak_512 = Keccak(512, 0x01);
1414fn Keccak(comptime bits: usize, comptime delim: u8) type {
1515 return struct {
1616 const Self = @This();
17 pub const block_length = 200;
17 /// The output length, in bytes.
1818 pub const digest_length = bits / 8;
19 /// The block length, or rate, in bytes.
20 pub const block_length = 200 - bits / 4;
21 /// Keccak does not have any options.
1922 pub const Options = struct {};
2023
2124 s: [200]u8,
2225 offset: usize,
23 rate: usize,
2426
2527 pub fn init(options: Options) Self {
2628 _ = options;
27 return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) };
29 return Self{ .s = [_]u8{0} ** 200, .offset = 0 };
2830 }
2931
3032 pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void {
......@@ -36,7 +38,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
3638 pub fn update(d: *Self, b: []const u8) void {
3739 var ip: usize = 0;
3840 var len = b.len;
39 var rate = d.rate - d.offset;
41 var rate = block_length - d.offset;
4042 var offset = d.offset;
4143
4244 // absorb
......@@ -48,7 +50,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
4850
4951 ip += rate;
5052 len -= rate;
51 rate = d.rate;
53 rate = block_length;
5254 offset = 0;
5355 }
5456
......@@ -61,7 +63,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
6163 pub fn final(d: *Self, out: *[digest_length]u8) void {
6264 // padding
6365 d.s[d.offset] ^= delim;
64 d.s[d.rate - 1] ^= 0x80;
66 d.s[block_length - 1] ^= 0x80;
6567
6668 keccakF(1600, &d.s);
6769
......@@ -69,11 +71,11 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
6971 var op: usize = 0;
7072 var len: usize = bits / 8;
7173
72 while (len >= d.rate) {
73 mem.copy(u8, out[op..], d.s[0..d.rate]);
74 while (len >= block_length) {
75 mem.copy(u8, out[op..], d.s[0..block_length]);
7476 keccakF(1600, &d.s);
75 op += d.rate;
76 len -= d.rate;
77 op += block_length;
78 len -= block_length;
7779 }
7880
7981 mem.copy(u8, out[op..], d.s[0..len]);