mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
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
This commit is contained in:
parent
e2d7b2bf33
commit
d86685ac96
@ -14,17 +14,19 @@ pub const Keccak_512 = Keccak(512, 0x01);
|
|||||||
fn Keccak(comptime bits: usize, comptime delim: u8) type {
|
fn Keccak(comptime bits: usize, comptime delim: u8) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const block_length = 200;
|
/// The output length, in bytes.
|
||||||
pub const digest_length = bits / 8;
|
pub const digest_length = bits / 8;
|
||||||
|
/// The block length, or rate, in bytes.
|
||||||
|
pub const block_length = 200 - bits / 4;
|
||||||
|
/// Keccak does not have any options.
|
||||||
pub const Options = struct {};
|
pub const Options = struct {};
|
||||||
|
|
||||||
s: [200]u8,
|
s: [200]u8,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
rate: usize,
|
|
||||||
|
|
||||||
pub fn init(options: Options) Self {
|
pub fn init(options: Options) Self {
|
||||||
_ = options;
|
_ = options;
|
||||||
return Self{ .s = [_]u8{0} ** 200, .offset = 0, .rate = 200 - (bits / 4) };
|
return Self{ .s = [_]u8{0} ** 200, .offset = 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void {
|
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 {
|
|||||||
pub fn update(d: *Self, b: []const u8) void {
|
pub fn update(d: *Self, b: []const u8) void {
|
||||||
var ip: usize = 0;
|
var ip: usize = 0;
|
||||||
var len = b.len;
|
var len = b.len;
|
||||||
var rate = d.rate - d.offset;
|
var rate = block_length - d.offset;
|
||||||
var offset = d.offset;
|
var offset = d.offset;
|
||||||
|
|
||||||
// absorb
|
// absorb
|
||||||
@ -48,7 +50,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
|
|||||||
|
|
||||||
ip += rate;
|
ip += rate;
|
||||||
len -= rate;
|
len -= rate;
|
||||||
rate = d.rate;
|
rate = block_length;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +63,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
|
|||||||
pub fn final(d: *Self, out: *[digest_length]u8) void {
|
pub fn final(d: *Self, out: *[digest_length]u8) void {
|
||||||
// padding
|
// padding
|
||||||
d.s[d.offset] ^= delim;
|
d.s[d.offset] ^= delim;
|
||||||
d.s[d.rate - 1] ^= 0x80;
|
d.s[block_length - 1] ^= 0x80;
|
||||||
|
|
||||||
keccakF(1600, &d.s);
|
keccakF(1600, &d.s);
|
||||||
|
|
||||||
@ -69,11 +71,11 @@ fn Keccak(comptime bits: usize, comptime delim: u8) type {
|
|||||||
var op: usize = 0;
|
var op: usize = 0;
|
||||||
var len: usize = bits / 8;
|
var len: usize = bits / 8;
|
||||||
|
|
||||||
while (len >= d.rate) {
|
while (len >= block_length) {
|
||||||
mem.copy(u8, out[op..], d.s[0..d.rate]);
|
mem.copy(u8, out[op..], d.s[0..block_length]);
|
||||||
keccakF(1600, &d.s);
|
keccakF(1600, &d.s);
|
||||||
op += d.rate;
|
op += block_length;
|
||||||
len -= d.rate;
|
len -= block_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem.copy(u8, out[op..], d.s[0..len]);
|
mem.copy(u8, out[op..], d.s[0..len]);
|
||||||
|
Loading…
Reference in New Issue
Block a user