tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

io_v2_digest.zig (1988B)


      1 //! Scoped, incremental SHA-256 state. No chunk/history retention and no writer or
      2 //! publication policy. The host registry supplies ownership and exclusive leases.
      3 const std = @import("std");
      4 pub const Digest = struct {
      5     state: std.crypto.hash.sha2.Sha256 = std.crypto.hash.sha2.Sha256.init(.{}),
      6     finished: bool = false,
      7     pub fn update(self: *Digest, bytes: []const u8) error{ InvalidBound, InvalidState }!void {
      8         if (bytes.len == 0 or bytes.len > 4096) return error.InvalidBound;
      9         if (self.finished) return error.InvalidState;
     10         self.state.update(bytes);
     11     }
     12     pub fn finish(self: *Digest) error{InvalidState}![64]u8 {
     13         if (self.finished) return error.InvalidState;
     14         var bytes: [32]u8 = undefined;
     15         self.state.final(&bytes);
     16         self.finished = true;
     17         var hex: [64]u8 = undefined;
     18         for (bytes, 0..) |byte, i| {
     19             hex[2 * i] = "0123456789abcdef"[byte >> 4];
     20             hex[2 * i + 1] = "0123456789abcdef"[byte & 15];
     21         }
     22         return hex;
     23     }
     24 };
     25 test "independent SHA-256 vectors, partitioning and terminal state" {
     26     const t = std.testing;
     27     var empty: Digest = .{};
     28     try t.expectEqualStrings("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", &(try empty.finish()));
     29     try t.expectError(error.InvalidState, empty.finish());
     30     try t.expectError(error.InvalidState, empty.update("x"));
     31     var abc: Digest = .{};
     32     try t.expectError(error.InvalidBound, abc.update(""));
     33     try t.expectError(error.InvalidBound, abc.update(&([_]u8{'x'} ** 4097)));
     34     try abc.update("a");
     35     try abc.update("bc");
     36     try t.expectEqualStrings("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", &(try abc.finish()));
     37     var million: Digest = .{};
     38     const block = [_]u8{'a'} ** 1000;
     39     for (0..1000) |_| try million.update(&block);
     40     try t.expectEqualStrings("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", &(try million.finish()));
     41 }