From 06d159083d332063f4bee12e1bf5d77deb73cc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20=C5=A0pinka?= Date: Tue, 28 Jan 2025 00:22:36 +0100 Subject: [PATCH] Prepare SHA interfaces. --- src/primitive/digest/sha.zig | 195 +++++++++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 6 deletions(-) diff --git a/src/primitive/digest/sha.zig b/src/primitive/digest/sha.zig index 16f0aad..6d3cfcd 100644 --- a/src/primitive/digest/sha.zig +++ b/src/primitive/digest/sha.zig @@ -7,7 +7,15 @@ pub const MessageLengthLimitExceeded = error.MessageLengthLimitExceeded; // ----------------------------------- SHA CONSTANTS ----------------------------------- // -pub const ShaAlgorithm = enum { Sha1, Sha224, Sha256, Sha384, Sha512, Sha512_224, Sha512_256 }; +//pub const ShaAlgorithm = enum { Sha1, Sha224, Sha256, Sha384, Sha512, Sha512_224, Sha512_256 }; + +const SHA_1_DIGEST_LENGTH = 160 / 8; +const SHA_224_DIGEST_LENGTH = 224 / 8; +const SHA_256_DIGEST_LENGTH = 256 / 8; +const SHA_384_DIGEST_LENGTH = 384 / 8; +const SHA_512_DIGEST_LENGTH = 512 / 8; +const SHA_512_224_DIGEST_LENGTH = 224 / 8; +const SHA_512_256_DIGEST_LENGTH = 256 / 8; const SHA_1_IV = [_]u32{ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, @@ -49,7 +57,7 @@ const Sha1Ctx = struct { e: u32, message_buffer: [BLOCK_SIZE]u8, - buffer_index: u6, + message_length: u64, }; const Sha2Ctx = struct { @@ -67,7 +75,7 @@ const Sha2Ctx = struct { h: u32, message_buffer: [BLOCK_SIZE]u8, - buffer_index: u6, + message_length: u64, t_is_224: bool, }; @@ -75,7 +83,7 @@ const Sha2Ctx = struct { const Sha3Ctx = struct { const BLOCK_SIZE = 1024 / 8; - message_schedule: [16]u32, + message_schedule: [16]u64, hash: [8]u64, a: u64, b: u64, @@ -87,10 +95,185 @@ const Sha3Ctx = struct { h: u64, message_buffer: [BLOCK_SIZE]u8, - buffer_index: u7, + message_length: u128, - // could be generalized in the future, like decribed in the standard + // I could generalize this in the future, like decribed in the standard. t_is_224: bool, t_is_256: bool, t_is_384: bool, }; + +pub fn sha1_new() Sha1Ctx { + var ctx = Sha1Ctx{ + .message_schedule = undefined, + .hash = undefined, + .a = undefined, + .b = undefined, + .c = undefined, + .d = undefined, + .e = undefined, + .message_buffer = undefined, + .message_length = 0, + }; + + @memcpy(&ctx.hash, &SHA_1_IV); + ctx.a = ctx.hash[0]; + ctx.b = ctx.hash[1]; + ctx.c = ctx.hash[2]; + ctx.d = ctx.hash[3]; + ctx.e = ctx.hash[4]; + + return ctx; +} + +pub fn sha1_update(ctx: *Sha1Ctx, message: []const u8) !void { + // TODO + _ = .{ ctx, message }; +} + +pub fn sha1_final(ctx: *Sha1Ctx, out: [SHA_1_DIGEST_LENGTH]u8) void { + // TODO + _ = .{ ctx, out }; +} + +pub fn sha2_new(t: comptime_int) Sha2Ctx { + if (comptime t != 224 and t != 256) + @compileError("SHA-2 context can only be initialized in 224-bit and 256-bit mode."); + + var ctx = Sha2Ctx{ + .message_schedule = undefined, + .hash = undefined, + .a = if (t == 224) SHA_224_IV[0] else SHA_256_IV[0], + .b = if (t == 224) SHA_224_IV[1] else SHA_256_IV[1], + .c = if (t == 224) SHA_224_IV[2] else SHA_256_IV[2], + .d = if (t == 224) SHA_224_IV[3] else SHA_256_IV[3], + .e = if (t == 224) SHA_224_IV[4] else SHA_256_IV[4], + .f = if (t == 224) SHA_224_IV[5] else SHA_256_IV[5], + .g = if (t == 224) SHA_224_IV[6] else SHA_256_IV[6], + .h = if (t == 224) SHA_224_IV[7] else SHA_256_IV[7], + .message_buffer = undefined, + .message_length = 0, + .t_is_224 = (t == 224), + }; + @memcpy(&ctx.hash, if (t == 224) &SHA_224_IV else &SHA_256_IV); + + return ctx; +} + +pub fn sha224_new() Sha2Ctx { + return sha2_new(224); +} + +pub fn sha224_update(ctx: *Sha2Ctx, message: []const u8) !void { + // TODO + _ = .{ ctx, message }; +} + +pub fn sha224_final(ctx: *Sha1Ctx, out: [SHA_224_DIGEST_LENGTH]u8) void { + // TODO + _ = .{ ctx, out }; +} + +pub fn sha256_new() Sha2Ctx { + return sha2_new(256); +} + +pub fn sha256_update(ctx: *Sha2Ctx, message: []const u8) !void { + // TODO + _ = .{ ctx, message }; +} + +pub fn sha256_final(ctx: *Sha2Ctx, out: [SHA_256_DIGEST_LENGTH]u8) void { + // TODO + _ = .{ ctx, out }; +} + +pub fn sha3_new(t: comptime_int) Sha3Ctx { + if (comptime t != 224 and t != 256 and t != 384 and t != 512) + @compileError("SHA-3 context can only be initialized in 224, 256, 384 and 512-bit mode."); + + const iv: *const [Sha3Ctx.BLOCK_SIZE]u64 = switch (t) { + 224 => &SHA_512_224_IV, + 256 => &SHA_512_256_IV, + 384 => &SHA_384_IV, + 512 => &SHA_512_IV, + _ => unreachable, + }; + + var ctx = Sha3Ctx{ + .message_schedule = undefined, + .hash = undefined, + .a = iv[0], + .b = iv[1], + .c = iv[2], + .d = iv[3], + .e = iv[4], + .f = iv[5], + .g = iv[6], + .h = iv[7], + .message_buffer = undefined, + .message_length = 0, + .t_is_224 = (t == 224), + .t_is_256 = (t == 256), + .t_is_384 = (t == 384), + }; + @memcpy(&ctx.hash, iv); + + return ctx; +} + +pub fn sha384_new() Sha3Ctx { + return sha3_new(384); +} + +pub fn sha384_update(ctx: *Sha3Ctx, message: []const u8) !void { + // TODO + _ = .{ ctx, message }; +} + +pub fn sha384_final(ctx: *Sha3Ctx, out: [SHA_384_DIGEST_LENGTH]u8) void { + // TODO + _ = .{ ctx, out }; +} + +pub fn sha512_new() Sha3Ctx { + return sha3_new(512); +} + +pub fn sha512_update(ctx: *Sha3Ctx, message: []const u8) !void { + // TODO + _ = .{ ctx, message }; +} + +pub fn sha512_final(ctx: *Sha3Ctx, out: [SHA_512_DIGEST_LENGTH]u8) void { + // TODO + _ = .{ ctx, out }; +} + +pub fn sha512_224_new() Sha3Ctx { + return sha3_new(224); +} + +pub fn sha512_224_update(ctx: *Sha3Ctx, message: []const u8) !void { + // TODO + _ = .{ ctx, message }; +} + +pub fn sha512_224_final(ctx: *Sha3Ctx, out: [SHA_512_224_DIGEST_LENGTH]u8) void { + // TODO + _ = .{ ctx, out }; +} + +pub fn sha512_256_new() Sha3Ctx { + return sha3_new(256); +} + +pub fn sha512_256_update(ctx: *Sha3Ctx, message: []const u8) !void { + // TODO + _ = .{ ctx, message }; +} + +pub fn sha512_256_final(ctx: *Sha3Ctx, out: [SHA_512_256_DIGEST_LENGTH]u8) void { + // TODO + _ = .{ ctx, out }; +}