use vstd::prelude::*;
verus! {
pub open spec fn hex_digit(byte: u8) -> bool {
(0x30 <= byte <= 0x39) || (0x61 <= byte <= 0x66)
}
pub fn hex_digit_exec(byte: u8) -> (hex: bool)
ensures hex == hex_digit(byte),
{
matches!(byte, b'0'..=b'9' | b'a'..=b'f')
}
pub open spec fn is_hex_address(bytes: &[u8]) -> bool {
bytes.len() == 64
&& forall|i: int| 0 <= i < bytes.len() ==> #[trigger] hex_digit(bytes[i])
}
pub fn is_content_address(bytes: &[u8]) -> (address: bool)
ensures address == is_hex_address(bytes),
{
if bytes.len() != 64 {
return false;
}
let mut all_hex = true;
let mut i = 0;
while i < bytes.len()
invariant
0 <= i <= bytes.len(),
all_hex == (forall|j: int| 0 <= j < i ==> #[trigger] hex_digit(bytes[j])),
decreases bytes.len() - i,
{
all_hex = all_hex && hex_digit_exec(bytes[i]);
i += 1;
}
all_hex
}
pub open spec fn object_pinned(is_current: bool, live_leases: u64) -> bool {
is_current || live_leases > 0
}
pub fn keep_object(is_current: bool, live_leases: u64) -> (keep: bool)
ensures keep == object_pinned(is_current, live_leases),
{
is_current || live_leases > 0
}
proof fn live_lease_object_survives(is_current: bool, live_leases: u64)
requires live_leases > 0,
ensures object_pinned(is_current, live_leases),
{
}
pub open spec fn activation_permits(
published: bool,
digest_matches: bool,
receipted: bool,
) -> bool {
published && digest_matches && receipted
}
pub fn activation_admitted(
published: bool,
digest_matches: bool,
receipted: bool,
) -> (admitted: bool)
ensures admitted == activation_permits(published, digest_matches, receipted),
{
published && digest_matches && receipted
}
proof fn unverified_object_never_activates(
published: bool,
digest_matches: bool,
receipted: bool,
)
requires !published || !digest_matches,
ensures !activation_permits(published, digest_matches, receipted),
{
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CatalogVerdict {
Compatible,
ProtocolMismatch,
VersionMismatch,
NoArtifactForTarget,
}
pub fn catalog_verdict(
protocol_matches: bool,
version_matches: bool,
target_available: bool,
) -> (verdict: CatalogVerdict)
ensures
(verdict == CatalogVerdict::Compatible)
== (protocol_matches && version_matches && target_available),
(verdict == CatalogVerdict::ProtocolMismatch) == !protocol_matches,
(verdict == CatalogVerdict::VersionMismatch)
== (protocol_matches && !version_matches),
(verdict == CatalogVerdict::NoArtifactForTarget)
== (protocol_matches && version_matches && !target_available),
{
if !protocol_matches {
CatalogVerdict::ProtocolMismatch
} else if !version_matches {
CatalogVerdict::VersionMismatch
} else if target_available {
CatalogVerdict::Compatible
} else {
CatalogVerdict::NoArtifactForTarget
}
}
}