tiny.machine.profile.wire
Defined in profile.
API (12)
Actions
Public operations.
Types and contracts
Public types and contracts.
ContractFingerprint: The identity of the shared execution rules.ProfileFingerprint: The identity of one full profile.Wire
Values and defaults
Public values and defaults.
Source
Source: lib/machine/src/profile/root.zig:49
zig
pub const wire = @import("wire.zig");Source: lib/machine/src/profile/wire.zig
zig
const std = @import("std");const os_abi = @import("os").abi;const profile = @import("root.zig");const Sha256 = std.crypto.hash.sha2.Sha256;pub const bytes: u16 = 256;pub const magic = [8]u8{ 'M', 'C', 'H', 'P', 'R', 'F', '1', 0 };pub const flags: u16 = 0;pub const contract_fingerprint_schema = "tiny.machine-contract-fingerprint/v1";pub const profile_fingerprint_schema = "tiny.machine-profile-fingerprint/v1";pub const Wire = [bytes]u8;/// The identity of the shared execution rules. A caller compares this fingerprint/// to know whether two profiles obey the same execution rules. The fingerprint is/// computed over the profile's encoded form with the backend field and the four/// claim fields zeroed, so the backend and the claims contribute nothing. A KVM/// profile and its portable counterpart therefore hold the same value, so a test/// can run both and compare what comes out. Restoring an instance from a checkpoint/// requires this fingerprint to equal the one recorded in the checkpoint's receipt/// basis. `hex` renders the digest as lowercase hexadecimal.pub const ContractFingerprint = struct { digest: [Sha256.digest_length]u8, pub fn hex(self: ContractFingerprint) [Sha256.digest_length * 2]u8 { return std.fmt.bytesToHex(self.digest, .lower); }};/// The identity of one full profile. A caller compares this fingerprint to know/// whether two runs used the very same profile, backend and claims included. The/// contract, the backend, and the claims all feed it, so every pairing of a canonical/// kind with a backend gets a distinct value. A restore proceeds only when the profile/// in hand carries the value recorded with the checkpoint. `hex` renders the digest/// as lowercase hexadecimal.pub const ProfileFingerprint = struct { digest: [Sha256.digest_length]u8, pub fn hex(self: ProfileFingerprint) [Sha256.digest_length * 2]u8 { return std.fmt.bytesToHex(self.digest, .lower); }};pub fn encode(value: profile.Profile, output: *Wire) profile.Error!void { try profile.validate(value); const contract = value.contract; var encoded: Wire = @splat(0); @memcpy(encoded[0..8], &magic); os_abi.wire.write16(encoded[8..10], contract.schema_major); os_abi.wire.write16(encoded[10..12], contract.schema_minor); os_abi.wire.write16(encoded[12..14], bytes); os_abi.wire.write16(encoded[14..16], flags); encoded[16] = @backingInt(contract.kind); encoded[17] = @backingInt(contract.architecture); os_abi.wire.write16(encoded[18..20], @backingInt(contract.cpu)); os_abi.wire.write16(encoded[20..22], @backingInt(contract.boot)); encoded[22] = @backingInt(contract.root_semantics); encoded[23] = @backingInt(contract.missing_root); os_abi.wire.write16(encoded[24..26], @backingInt(contract.device)); os_abi.wire.write16(encoded[26..28], @backingInt(contract.scheduling)); os_abi.wire.write16(encoded[28..30], @backingInt(contract.time)); os_abi.wire.write16(encoded[30..32], @backingInt(contract.entropy)); os_abi.wire.write16(encoded[32..34], @backingInt(contract.transport.dialect)); os_abi.wire.write16(encoded[34..36], @backingInt(contract.checkpoint)); os_abi.wire.write16(encoded[36..38], @backingInt(value.backend)); os_abi.wire.write16(encoded[38..40], @backingInt(contract.effects)); os_abi.wire.write16(encoded[40..42], contract.geometry.vcpu_count); os_abi.wire.write16(encoded[42..44], contract.instance_limit); os_abi.wire.write32(encoded[44..48], contract.geometry.page_bytes); os_abi.wire.write64(encoded[48..56], contract.geometry.ram_base); os_abi.wire.write64(encoded[56..64], contract.geometry.ram_bytes); os_abi.wire.write16(encoded[64..66], contract.transport.abi_major); os_abi.wire.write16(encoded[66..68], contract.transport.abi_minor); os_abi.wire.write16(encoded[68..70], contract.transport.boot_frame_bytes); os_abi.wire.write16(encoded[70..72], contract.transport.message_frame_bytes); os_abi.wire.write16(encoded[72..74], contract.transport.ring_header_bytes); os_abi.wire.write16(encoded[74..76], contract.transport.request_records); os_abi.wire.write16(encoded[76..78], contract.transport.event_records); os_abi.wire.write16(encoded[78..80], contract.transport.terminal_bytes); os_abi.wire.write16(encoded[80..82], contract.transport.entropy_bytes); os_abi.wire.write16(encoded[82..84], contract.transport.semantic_bytes); os_abi.wire.write16(encoded[84..86], contract.transport.effect_request_bytes); os_abi.wire.write16(encoded[86..88], contract.transport.effect_result_bytes); os_abi.wire.write16(encoded[88..90], contract.checkpoint_candidate_limit); os_abi.wire.write16(encoded[90..92], @backingInt(contract.instruction_admission)); os_abi.wire.write32(encoded[92..96], contract.admission_limit); os_abi.wire.write16(encoded[96..98], @backingInt(contract.determinism.schema)); os_abi.wire.write16(encoded[98..100], contract.determinism.entry_count); @memcpy(encoded[100..132], &contract.determinism.digest); encodeClaim(value.claims.semantic, encoded[132..135]); encodeClaim(value.claims.same_backend_whole_system, encoded[135..138]); encodeClaim(value.claims.cross_host, encoded[138..141]); encodeClaim(value.claims.instruction_exact, encoded[141..144]); output.* = encoded;}pub fn decode(input: *const Wire) profile.Error!profile.Profile { if (!std.mem.eql(u8, input[0..8], &magic)) return error.BadMagic; if (os_abi.wire.read16(input[8..10]) != profile.schema_major or os_abi.wire.read16(input[10..12]) != profile.schema_minor) { return error.UnsupportedVersion; } if (os_abi.wire.read16(input[12..14]) != bytes) { return error.WireBytesMismatch; } if (os_abi.wire.read16(input[14..16]) != flags) { return error.UnsupportedFlags; } if (!os_abi.wire.allZero(input[144..])) { return error.ReservedNonzero; } const value: profile.Profile = .{ .contract = .{ .schema_major = os_abi.wire.read16(input[8..10]), .schema_minor = os_abi.wire.read16(input[10..12]), .kind = try enumValue(profile.ProfileKind, input[16]), .architecture = try enumValue(profile.Architecture, input[17]), .cpu = try enumValue(profile.CpuContract, os_abi.wire.read16(input[18..20])), .instruction_admission = try enumValue( profile.InstructionAdmission, os_abi.wire.read16(input[90..92]), ), .boot = try enumValue(profile.BootDialect, os_abi.wire.read16(input[20..22])), .root_semantics = try enumValue(profile.RootSemantics, input[22]), .missing_root = try enumValue(profile.MissingRoot, input[23]), .device = try enumValue(profile.DeviceDialect, os_abi.wire.read16(input[24..26])), .scheduling = try enumValue(profile.Scheduling, os_abi.wire.read16(input[26..28])), .time = try enumValue(profile.TimeSemantics, os_abi.wire.read16(input[28..30])), .entropy = try enumValue(profile.EntropySemantics, os_abi.wire.read16(input[30..32])), .geometry = .{ .vcpu_count = os_abi.wire.read16(input[40..42]), .page_bytes = os_abi.wire.read32(input[44..48]), .ram_base = os_abi.wire.read64(input[48..56]), .ram_bytes = os_abi.wire.read64(input[56..64]), }, .transport = .{ .dialect = try enumValue(profile.TransportDialect, os_abi.wire.read16(input[32..34])), .abi_major = os_abi.wire.read16(input[64..66]), .abi_minor = os_abi.wire.read16(input[66..68]), .boot_frame_bytes = os_abi.wire.read16(input[68..70]), .message_frame_bytes = os_abi.wire.read16(input[70..72]), .ring_header_bytes = os_abi.wire.read16(input[72..74]), .request_records = os_abi.wire.read16(input[74..76]), .event_records = os_abi.wire.read16(input[76..78]), .terminal_bytes = os_abi.wire.read16(input[78..80]), .entropy_bytes = os_abi.wire.read16(input[80..82]), .semantic_bytes = os_abi.wire.read16(input[82..84]), .effect_request_bytes = os_abi.wire.read16(input[84..86]), .effect_result_bytes = os_abi.wire.read16(input[86..88]), }, .checkpoint = try enumValue(profile.CheckpointFormat, os_abi.wire.read16(input[34..36])), .effects = try enumValue(profile.EffectSemantics, os_abi.wire.read16(input[38..40])), .determinism = .{ .schema = try enumValue( profile.DeterminismSchema, os_abi.wire.read16(input[96..98]), ), .entry_count = os_abi.wire.read16(input[98..100]), .digest = input[100..132].*, }, .instance_limit = os_abi.wire.read16(input[42..44]), .checkpoint_candidate_limit = os_abi.wire.read16(input[88..90]), .admission_limit = os_abi.wire.read32(input[92..96]), }, .backend = try enumValue(profile.BackendSemantics, os_abi.wire.read16(input[36..38])), .claims = .{ .semantic = try decodeClaim(input[132..135]), .same_backend_whole_system = try decodeClaim(input[135..138]), .cross_host = try decodeClaim(input[138..141]), .instruction_exact = try decodeClaim(input[141..144]), }, }; try profile.validate(value); return value;}pub fn contractFingerprint(value: profile.Profile) profile.Error!ContractFingerprint { var encoded: Wire = undefined; try encode(value, &encoded); os_abi.wire.write16(encoded[36..38], 0); @memset(encoded[132..144], 0); return .{ .digest = digest(contract_fingerprint_schema, &encoded) };}pub fn profileFingerprint(value: profile.Profile) profile.Error!ProfileFingerprint { var encoded: Wire = undefined; try encode(value, &encoded); return .{ .digest = digest(profile_fingerprint_schema, &encoded) };}fn digest(schema: []const u8, encoded: *const Wire) [Sha256.digest_length]u8 { var hasher = Sha256.init(.{}); hasher.update(schema); hasher.update(&.{0}); hasher.update(encoded); var output: [Sha256.digest_length]u8 = undefined; hasher.final(&output); return output;}fn enumValue(comptime T: type, value: anytype) profile.Error!T { inline for (std.meta.tags(T)) |candidate| { if (@backingInt(candidate) == value) return candidate; } return error.UnknownProfileField;}fn encodeClaim(claim: profile.DeterminismClaim, output: *[3]u8) void { const kind = std.meta.activeTag(claim); output[0] = @backingInt(kind); const evidence = switch (claim) { .enforced => |value| @backingInt(value), .assumed => |value| @backingInt(value), }; os_abi.wire.write16(output[1..3], evidence);}fn decodeClaim(input: *const [3]u8) profile.Error!profile.DeterminismClaim { const kind = try enumValue(profile.DeterminismClaimKind, input[0]); const evidence = os_abi.wire.read16(input[1..3]); return switch (kind) { .enforced => .{ .enforced = try enumValue( profile.DeterminismClaimWitness, evidence, ) }, .assumed => .{ .assumed = try enumValue( profile.DeterminismClaimAssumption, evidence, ) }, };}Audit
| Definitions | 11 |
|---|---|
| Public names | 16 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |