lib/machine/src/explore/distributed/seed.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const explore = @import("../root.zig");
 2 const profile = @import("../../profile/root.zig");
 3 const std = @import("std");
 4 const types = @import("types.zig");
 5 
 6 const Sha256 = std.crypto.hash.sha2.Sha256;
 7 const domain = "tiny.machine.explore.distributed.seed/v1";
 8 
 9 pub const Provenance = types.Provenance;
10 
11 pub fn selected() profile.Profile {
12     return profile.interpretedContinuationTestV1();
13 }
14 
15 pub fn provenance(value: profile.Profile) profile.Error!Provenance {
16     try profile.validate(value);
17     const full = try profile.profileFingerprint(value);
18     const contract = try profile.contractFingerprint(value);
19     const determinism = value.contract.determinism;
20     var hasher = Sha256.init(.{});
21     hasher.update(domain);
22     hasher.update(&full.digest);
23     hasher.update(&contract.digest);
24     hasher.update(&determinism.digest);
25     var encoded: [6]u8 = undefined;
26     std.mem.writeInt(u16, encoded[0..2], @backingInt(determinism.schema), .little);
27     std.mem.writeInt(u16, encoded[2..4], determinism.entry_count, .little);
28     std.mem.writeInt(u16, encoded[4..6], types.dialect_version, .little);
29     hasher.update(&encoded);
30     var bytes: [Sha256.digest_length]u8 = undefined;
31     hasher.final(&bytes);
32     std.debug.assert(!allZero(&bytes));
33     return .{
34         .profile = full,
35         .contract = contract,
36         .determinism = determinism,
37         .dialect = types.dialect_version,
38         .seed = .{ .bytes = bytes },
39     };
40 }
41 
42 fn allZero(bytes: []const u8) bool {
43     for (bytes) |byte| if (byte != 0) return false;
44     return true;
45 }
46 
47 test "distributed seed derives only from the frozen profile identity" {
48     const value = selected();
49     const first = try provenance(value);
50     const second = try provenance(value);
51     try std.testing.expectEqualDeep(first, second);
52     try std.testing.expectEqual(explore.SeedDialect.sha256_v1, first.seed.dialect);
53     try std.testing.expect(!allZero(&first.seed.bytes));
54     try std.testing.expectEqualDeep(
55         profile.determinism.inventory_identity,
56         first.determinism,
57     );
58     const other = try provenance(profile.interpretedReconstructV1());
59     try std.testing.expect(!std.mem.eql(u8, &first.seed.bytes, &other.seed.bytes));
60 }