#[derive(Debug, Clone, Copy)]
#[repr(C, align(64))]
pub struct WitnessRecord {
pub sequence: u64,
pub timestamp_ns: u64,
pub action_kind: u8,
pub proof_tier: u8,
pub flags: u8,
reserved: u8,
pub actor_partition_id: u32,
pub target_object_id: u64,
pub capability_hash: u32,
pub payload: [u8; 8],
pub prev_hash: u32,
pub record_hash: u32,
pub aux: [u8; 8],
pad: [u8; 4],
}
const _: () = {
assert!(core::mem::size_of::<WitnessRecord>() == 64);
};
impl WitnessRecord {
#[must_use]
pub const fn zeroed() -> Self {
Self {
sequence: 0,
timestamp_ns: 0,
action_kind: 0,
proof_tier: 0,
flags: 0,
reserved: 0,
actor_partition_id: 0,
target_object_id: 0,
capability_hash: 0,
payload: [0; 8],
prev_hash: 0,
record_hash: 0,
aux: [0; 8],
pad: [0; 4],
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct WitnessHash {
bytes: [u8; 32],
}
impl WitnessHash {
pub const ZERO: Self = Self { bytes: [0u8; 32] };
#[must_use]
pub const fn from_bytes(bytes: [u8; 32]) -> Self {
Self { bytes }
}
#[must_use]
pub const fn as_bytes(&self) -> &[u8; 32] {
&self.bytes
}
#[must_use]
pub const fn is_zero(&self) -> bool {
let mut i = 0;
while i < 32 {
if self.bytes[i] != 0 {
return false;
}
i += 1;
}
true
}
}
impl core::fmt::Debug for WitnessHash {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "WitnessHash(")?;
for byte in &self.bytes[..4] {
write!(f, "{byte:02x}")?;
}
write!(f, "..)")
}
}
impl core::fmt::Display for WitnessHash {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
for byte in &self.bytes {
write!(f, "{byte:02x}")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum ActionKind {
PartitionCreate = 0x01,
PartitionDestroy = 0x02,
PartitionSuspend = 0x03,
PartitionResume = 0x04,
PartitionSplit = 0x05,
PartitionMerge = 0x06,
PartitionHibernate = 0x07,
PartitionReconstruct = 0x08,
PartitionMigrate = 0x09,
CapabilityGrant = 0x10,
CapabilityRevoke = 0x11,
CapabilityDelegate = 0x12,
CapabilityEscalate = 0x13,
CapabilityAttenuated = 0x14,
RegionCreate = 0x20,
RegionDestroy = 0x21,
RegionTransfer = 0x22,
RegionShare = 0x23,
RegionUnshare = 0x24,
RegionPromote = 0x25,
RegionDemote = 0x26,
RegionMap = 0x27,
RegionUnmap = 0x28,
CommEdgeCreate = 0x30,
CommEdgeDestroy = 0x31,
IpcSend = 0x32,
IpcReceive = 0x33,
ZeroCopyShare = 0x34,
NotificationSignal = 0x35,
DeviceLeaseGrant = 0x40,
DeviceLeaseRevoke = 0x41,
DeviceLeaseExpire = 0x42,
DeviceLeaseRenew = 0x43,
ProofVerifiedP1 = 0x50,
ProofVerifiedP2 = 0x51,
ProofVerifiedP3 = 0x52,
ProofRejected = 0x53,
ProofEscalated = 0x54,
SchedulerEpoch = 0x60,
SchedulerModeSwitch = 0x61,
TaskSpawn = 0x62,
TaskTerminate = 0x63,
StructuralSplit = 0x64,
StructuralMerge = 0x65,
RecoveryEnter = 0x70,
RecoveryExit = 0x71,
CheckpointCreated = 0x72,
CheckpointRestored = 0x73,
MinCutBudgetExceeded = 0x74,
DegradedModeEntered = 0x75,
DegradedModeExited = 0x76,
BootAttestation = 0x80,
BootComplete = 0x81,
TeeAttestation = 0x82,
VectorPut = 0x90,
VectorDelete = 0x91,
GraphMutation = 0x92,
CoherenceRecomputed = 0x93,
VmidReclaim = 0xA0,
MigrationTimeout = 0xA1,
AnchorExternalReceipt = 0xB0,
ContextResolve = 0xC0,
ContextRead = 0xC1,
ContextSearch = 0xC2,
ContextPut = 0xC3,
ContextAliasUpdate = 0xC4,
ContextForget = 0xC5,
ContextExecute = 0xC6,
ContextEpochSeal = 0xC7,
}
impl ActionKind {
#[must_use]
pub const fn subsystem(self) -> u8 {
(self as u8) >> 4
}
}
#[inline]
#[must_use]
pub fn fnv1a_64(data: &[u8]) -> u64 {
const FNV_OFFSET: u64 = 0xcbf2_9ce4_8422_2325;
const FNV_PRIME: u64 = 0x0000_0100_0000_01B3;
let mut hash: u64 = FNV_OFFSET;
let len = data.len();
let mut i = 0;
while i + 8 <= len {
hash ^= u64::from(data[i]);
hash = hash.wrapping_mul(FNV_PRIME);
hash ^= u64::from(data[i + 1]);
hash = hash.wrapping_mul(FNV_PRIME);
hash ^= u64::from(data[i + 2]);
hash = hash.wrapping_mul(FNV_PRIME);
hash ^= u64::from(data[i + 3]);
hash = hash.wrapping_mul(FNV_PRIME);
hash ^= u64::from(data[i + 4]);
hash = hash.wrapping_mul(FNV_PRIME);
hash ^= u64::from(data[i + 5]);
hash = hash.wrapping_mul(FNV_PRIME);
hash ^= u64::from(data[i + 6]);
hash = hash.wrapping_mul(FNV_PRIME);
hash ^= u64::from(data[i + 7]);
hash = hash.wrapping_mul(FNV_PRIME);
i += 8;
}
while i < len {
hash ^= u64::from(data[i]);
hash = hash.wrapping_mul(FNV_PRIME);
i += 1;
}
hash
}
#[inline]
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub fn fnv1a_32(data: &[u8]) -> u32 {
fnv1a_64(data) as u32
}
pub const WITNESS_RING_CAPACITY: usize = 262_144;
pub const WITNESS_RECORD_SIZE: usize = 64;