vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
//! Certificate verifier subcommand.
//!
//! Reads a JSON certificate produced by `certify::to_json()`, recomputes the
//! registry hash from the compiled spec set, and compares it against the
//! certificate's recorded `registry_hash`.
//!
use std::fs;
use std::path::PathBuf;

use clap::Parser;

/// Arguments for certificate verification.
#[derive(Debug, Parser)]
pub struct Args {
    /// Path to the JSON certificate to verify.
    pub cert_path: PathBuf,
}

/// Verify a certificate against the compiled registry hash.
pub fn run(args: Args) -> Result<(), Box<dyn std::error::Error>> {
    let path = args.cert_path;
    let contents = fs::read_to_string(&path)
        .map_err(|err| format!("Fix: cannot read {}: {err}", path.display()))?;

    let doc: serde_json::Value = serde_json::from_str(&contents)
        .map_err(|err| format!("Fix: invalid JSON in {}: {err}", path.display()))?;

    let cert_hash = match doc.get("registry_hash").and_then(|v| v.as_array()) {
        Some(arr) if arr.len() == 32 => {
            let mut bytes = [0u8; 32];
            for (i, val) in arr.iter().enumerate() {
                let n = val.as_u64().ok_or_else(|| {
                    format!(
                        "Fix: registry_hash[{i}] in {} is not an integer.",
                        path.display()
                    )
                })?;
                bytes[i] = u8::try_from(n).map_err(|_| {
                    format!("Fix: registry_hash[{i}] in {} exceeds u8.", path.display())
                })?;
            }
            bytes
        }
        _ => return Err("Fix: certificate missing or malformed 'registry_hash' field.".into()),
    };

    let backend_name = doc
        .get("backend_name")
        .and_then(|v| v.as_str())
        .unwrap_or("<unknown>");
    let backend_version = doc
        .get("backend_version")
        .and_then(|v| v.as_str())
        .unwrap_or("<unknown>");
    let timestamp = doc
        .get("timestamp")
        .and_then(|v| v.as_str())
        .unwrap_or("<unknown>");

    let specs = crate::op_registry::compiled_specs();
    let recomputed = crate::pipeline::certify::compute_registry_hash(&specs);

    println!("Certificate : {}", path.display());
    println!("Backend     : {backend_name} {backend_version}");
    println!("Timestamp   : {timestamp}");
    let cert_hash_hex = vyre_reference::hash::hex::bytes_to_hex(&cert_hash);
    let recomputed_hex = vyre_reference::hash::hex::bytes_to_hex(&recomputed);
    println!("Cert hash   : {cert_hash_hex}");
    println!("Local hash  : {recomputed_hex}");

    if cert_hash == recomputed {
        println!("Result      : PASS - registry hash matches.");
    } else {
        println!("Result      : FAIL - registry hash mismatch.");
        return Err(
            "Fix: certificate was produced against a different compiled spec registry.".into(),
        );
    }
    Ok(())
}