The file C:\Users\NickV\Downloads\Cubie_Intel_Edge_Integration_Plan.md has been updated successfully.

# Cubie Trust Compiler -- Intel AI Edge Application Ready Verification
# Integration Plan

================================================================================
                          EXECUTIVE SUMMARY
================================================================================

The Cubie Trust Compiler is a formally verified AI workload admission gate that
compiles to native x86_64 machine code. This document details the 5-phase plan
to integrate Cubie into Intel's AI Edge Application Ready Verification program
(Rev 2.1, Jan 2026).

What Cubie already delivers:
  - Cross-compiles to 3 bare-metal targets (RISC-V, x86_64, AArch64)
  - C-ABI entry point: extern "C" fn cubie_admit(*const CubieRequest) -> AdmitResult
  - ~730 ns/call on Intel Core Ultra 9 285HX (~1.37M admits/sec)
  - 754 theorems across Coq 8.18.0, Lean 4.30.0, and Verus
  - 62 passing integration tests, zero external dependencies
  - 3 patent families (US11956363B2, US20240195628A1)

What Intel needs from us:
  1. Application running on Intel edge hardware
  2. Workload performance metrics at light/medium/heavy loads
  3. Pipeline block diagram
  4. Resource utilization screenshots (CPU/GPU/NPU)
  5. Sizing tool report OR Appendix A alternative artifacts

The gap: No Python bindings, no C header, no container config, no OpenVINO
pipeline integration. We need a bridge from libcubie_bare_metal.a to a
Python+OpenVINO demo pipeline.

================================================================================
                WHAT A REAL INTEL EDGE AI WORKLOAD LOOKS LIKE
================================================================================

The Intel Edge AI Sizing Tool (Node.js frontend + Python FastAPI workers,
ports 5000-6000) processes workloads with these actual properties:

Workload-level properties (what gets submitted to a worker):
------------------------------------------------------------------------
  workload_id:           string    # unique identifier
  workload_type:         enum      # "dlstreamer" | "text-generation" |
                                   # "instance-segmentation" | ...
  model_name:            string    # "yolo11n", HuggingFace ID, or .xml path
  model_precision:       enum      # "FP16" | "FP32"
  device:                string    # "CPU" | "GPU" | "NPU" | "AUTO" |
                                   # "MULTI:GPU,CPU"
  batch_size:            int       # frames or tokens per inference call
  number_of_streams:     int       # parallel inference streams
  input_source:          string    # file path, RTSP URL, /dev/videoN, or text

OpenVINO compile_model config (set at model load time):
------------------------------------------------------------------------
  performance_mode:      LATENCY | THROUGHPUT
  model_priority:        LOW(0) | MEDIUM(1) | HIGH(2)
  num_streams:           int
  inference_num_threads: int
  num_requests (nireq):  int       # async request pool size
  scheduling_core_type:  ANY_CORE | PCORE_ONLY | ECORE_ONLY
  affinity:              NONE | CORE | NUMA | HYBRID_AWARE
  execution_mode:        PERFORMANCE | ACCURACY

DLStreamer pipeline element properties (per-stage in video pipelines):
------------------------------------------------------------------------
  gvadetect / gvaclassify / gvainference:
    model:               .xml path
    device:              CPU | GPU | NPU
    nireq:               parallel inference requests
    inference_interval:  process every N-th frame
    batch_size:          frames batched per call
    threshold:           detection confidence cutoff
    pre_process_backend: ie | opencv | va | va-surface-sharing

KServe V2 inference request (OVMS REST API):
------------------------------------------------------------------------
  {
    "id": "request-42",
    "inputs": [
      { "name": "input", "shape": [1,3,224,224], "datatype": "FP32" }
    ],
    "outputs": [
      { "name": "detection_output" }
    ]
  }

================================================================================
           MAPPING CubieRequest TO REAL WORKLOAD PROPERTIES
================================================================================

The existing CubieRequest (40 bytes, bare-metal/src/types.rs:4-25) has abstract
booleans. Here is how each field maps to real Intel Edge workload properties:

+-------------------+--------------------------------------+-------------------------------------------+
| CubieRequest      | Real-world meaning                   | How it gets populated                     |
| field             | on Intel Edge                        |                                           |
+-------------------+--------------------------------------+-------------------------------------------+
| who_pass          | IDENTITY: Is the requesting entity   | Check API key, JWT, or mTLS cert          |
|                   | (user/service/container) authed?     | against allow-list                        |
+-------------------+--------------------------------------+-------------------------------------------+
| what_pass         | CAPABILITY: Is this model+precision  | Validate model_name + model_precision +   |
|                   | allowed on this device?              | device against policy                     |
+-------------------+--------------------------------------+-------------------------------------------+
| how_pass          | METHOD: Is the execution config      | Check batch_size <= max_batch,            |
|                   | (batch, nireq, streams) in bounds?   | nireq <= max_nireq, streams <= max        |
+-------------------+--------------------------------------+-------------------------------------------+
| where_pass        | LOCATION: Is this edge node          | Check node ID / testbed system ID         |
|                   | authorized for this workload type?   | against deployment policy                 |
+-------------------+--------------------------------------+-------------------------------------------+
| when_pass         | LEASE: Is the time-bounded           | Check lease_expiry > current_time         |
|                   | execution lease still valid?         |                                           |
+-------------------+--------------------------------------+-------------------------------------------+
| why_pass          | POLICY: Does the workload comply     | Check model_priority, performance_mode,   |
|                   | with governance rules?               | resource quotas                           |
+-------------------+--------------------------------------+-------------------------------------------+
| has_valid_lease   | Lease not expired                    | lease_expiry_epoch > now()                |
+-------------------+--------------------------------------+-------------------------------------------+
| epoch_fresh       | Request not stale/replayed           | request_epoch within freshness window     |
+-------------------+--------------------------------------+-------------------------------------------+
| request_hash      | Hash of (model_name + device +       | SHA-256 of workload config fields,        |
|                   | batch_size + input_shape)            | truncated to u64                          |
+-------------------+--------------------------------------+-------------------------------------------+
| capability_hmac   | HMAC-SHA256 of request_hash          | Proves request authorized by platform     |
|                   | with eFuse key                       | root of trust                             |
+-------------------+--------------------------------------+-------------------------------------------+
| key_slot          | Which eFuse key slot                 | 0 for single-tenant; 0-7 for multi       |
+-------------------+--------------------------------------+-------------------------------------------+
| peer_id           | NVLink peer to check for deadlock    | Maps to GPU device index in multi-GPU     |
+-------------------+--------------------------------------+-------------------------------------------+
| adapter_id        | PCIe adapter for bandwidth check     | Maps to GPU/NPU PCIe device ID            |
+-------------------+--------------------------------------+-------------------------------------------+

CubieRequest struct layout (40 bytes, #[repr(C)]):
------------------------------------------------------------------------
  Offset  Field              Type    Size
  0       who_pass           bool    1
  1       what_pass          bool    1
  2       how_pass           bool    1
  3       where_pass         bool    1
  4       when_pass          bool    1
  5       why_pass           bool    1
  6       has_valid_lease    bool    1
  7       epoch_fresh        bool    1
  8       request_hash       u64     8
  16      capability_hmac    u64     8
  24      key_slot           u8      1
  25      peer_id            u8      1
  26-31   (padding)                  6
  32      adapter_id         u64     8
  Total: 40 bytes

================================================================================
                    THE PIPELINE INTEGRATION POINT
================================================================================

The Cubie gate sits at WORKLOAD SUBMISSION TIME -- BEFORE core.compile_model()
or DLStreamer pipeline launch. It does NOT gate individual inference frames.
It gates whether the ENTIRE WORKLOAD is allowed to start.

  Workload Request (model, device, config)
      |
      v
  [Policy Evaluator] -- populates CubieRequest bools from workload config
      |
      v
  [cubie_admit()] -- ~730ns, HMAC + NVLink + PCIe hardware checks
      |
      +-- Allow --> core.compile_model(model, device, config) --> inference loop
      |
      +-- Deny --> HTTP 403, workload never touches GPU/NPU

================================================================================
           FULL SYSTEM ARCHITECTURE (text flowchart)
================================================================================

                    FORMAL PROOF LAYER (mathematical truth)
                    =======================================

  +---------------------+     +------------------------------+
  |  Coq 8.18.0         |     |  Lean 4.30.0                 |
  |  (Calculus of        |     |  (Dependent type theory,     |
  |   Inductive          |     |   independent verification)  |
  |   Constructions)     |     |                              |
  |                      |     |                              |
  |  CubieDualLedger.v   |<--->|  CubieDualLedger.lean       |
  |  (7 theorems)        |     |  (7 theorems)                |
  |  CUB-0734..0740      |     |  CUB-0734..0740              |
  |                      |     |                              |
  |  CubieQuantumConsent |<--->|  CubieQuantumConsent         |
  |  Advanced.v          |     |  Advanced.lean               |
  |  (14 theorems)       |     |  (14 theorems)               |
  |  CUB-0741..0754      |     |  CUB-0741..0754              |
  +----------+-----------+     +--------------+---------------+
             |                                |
             |  Same predicates,              |
             |  same invariants,              |
             |  independent provers           |
             |                                |
             +---------------+----------------+
                             |
                             v
              VERUS SPECIFICATION LAYER (SMT-verified Rust)
              ====================================================

  +-------------------------------------------------------------+
  |  verus/cubie_consent_hierarchy_spec.rs                      |
  |                                                             |
  |  SPEC FUNCTIONS (10):  ghost-level, erased at compile time  |
  |    cascading_consent, sub_policy_compliant, stabilizer_ok,  |
  |    full_consent_ok, channel_valid, access_by_relationship,  |
  |    child_can_access_parent, percolates, capacity_available, |
  |    can_modify_preferences, effective_sub_policy             |
  |                                                             |
  |  PROOF FUNCTIONS (14): CUB-0741..0754                       |
  |    requires/ensures clauses -> verified by SMT solver (Z3)  |
  |                                                             |
  |  EXEC FUNCTIONS (5): compiled to machine code               |
  |    exec_cascading_consent, exec_full_consent_ok,            |
  |    exec_capacity_available, exec_percolates,                |
  |    exec_can_modify_preferences                              |
  |    Each has: ensures result == spec_fn(...)                  |
  +----------------------------+--------------------------------+
                               |
                               |  spec fn --ensures--> exec fn
                               |  (ghost)              (compiled)
                               |
                               v
              BARE-METAL RUNTIME LAYER (no_std Rust, no OS)
              ================================================

  +-------------------------------------------------------------+
  |  bare-metal/src/lib.rs                                      |
  |  +-- sha256.rs      FIPS 180-4 SHA-256                      |
  |  +-- hmac.rs        FIPS 198-1 HMAC-SHA256                  |
  |  +-- hmac_stub.rs   eFuse key interface                     |
  |  +-- admit.rs       cubie_admit() C-ABI entry point         |
  |  +-- types.rs       CubieRequest, WasteFactors, AdmitResult |
  |  +-- mmio.rs        Memory-mapped I/O (real or mock)        |
  |  +-- nvlink.rs      NVLink waiter/deadlock detection        |
  |  +-- pcie.rs        PCIe bandwidth + adapter cache          |
  |  +-- cycle_counter  Hardware cycle counter                  |
  |  +-- consent.rs     Hierarchical consent (10 fns)           |
  |  +-- dual_ledger.rs Dual-ledger non-disclosure (5 fns)      |
  |                                                             |
  |  ALL structs: #[repr(C)] -- C ABI compatible                |
  |  ALL functions: #[inline], pure, no alloc, no MMIO          |
  |  Panic handler: infinite loop (no unwind, no OS)            |
  +----------------------------+--------------------------------+
                               |
                               |  cargo build --target
                               |
                               v
              SILICON TARGETS (cross-compilation)
              ====================================

  +-------------------+  +-------------------+  +----------------+
  | RISC-V            |  | x86_64            |  | AArch64        |
  | riscv32imc-       |  | x86_64-unknown-   |  | aarch64-       |
  | unknown-none-elf  |  | none              |  | unknown-none   |
  |                   |  |                   |  |                |
  | Embedded MCU      |  | UEFI driver /     |  | ARM Cortex-A   |
  | ~8KB flash budget |  | hypervisor        |  | bare-metal     |
  | 5.2 MB .a         |  | 6.8 MB .a         |  | 8.5 MB .a      |
  +-------------------+  +-------------------+  +----------------+

              HOST TEST LAYER (std + mock MMIO)
              ==================================

  +-------------------------------------------------------------+
  |  bare-metal-tests/                                          |
  |  +-- tests/admit.rs              21 tests (HMAC, NVLink,    |
  |  |                                PCIe, 6-face gate)        |
  |  +-- tests/consent_hierarchy.rs  26 tests (CUB-0741..0753)  |
  |  +-- tests/dual_ledger.rs        15 tests (CUB-0734..0740)  |
  |                                                             |
  |  Total: 62 tests, ALL PASS                                  |
  |  Feature flags: std + mock (AtomicU32 replaces MMIO)        |
  +-------------------------------------------------------------+

================================================================================
     INTEL EDGE INTEGRATION ARCHITECTURE (text flowchart)
================================================================================

  +-----------------------------------------------------------+
  |                    INTEL EDGE TESTBED                      |
  |  Intel Core Ultra 9 285HX | GPU | NPU | Ubuntu 22.04     |
  +-----------------------------------------------------------+
  |                                                           |
  |  +-----------------------------------------------------+  |
  |  |  Python Layer (Intel ecosystem)                      |  |
  |  |                                                      |  |
  |  |  cubie_openvino_demo.py  <-- FastAPI server          |  |
  |  |      |                                               |  |
  |  |      |  POST /admit  (workload config JSON)          |  |
  |  |      |  POST /launch (admit + compile + infer)       |  |
  |  |      |  GET /metrics (admit counts, latencies)       |  |
  |  |      v                                               |  |
  |  |  policy.py  <-- evaluates 6 faces from config        |  |
  |  |      |                                               |  |
  |  |      |  who: API key in allow-list?                  |  |
  |  |      |  what: (model, device) approved?              |  |
  |  |      |  how: batch/nireq within bounds?              |  |
  |  |      |  where: node authorized?                      |  |
  |  |      |  when: lease valid?                           |  |
  |  |      |  why: policy compliant?                       |  |
  |  |      v                                               |  |
  |  |  cubie_gate.py  <-- ctypes wrapper                   |  |
  |  |      |                                               |  |
  |  |      |  CubieRequest(40 bytes) -> cubie_admit()      |  |
  |  |      v                                               |  |
  |  +------+-----------------------------------------------+  |
  |         |                                                  |
  |         |  ctypes.cdll.LoadLibrary("libcubie_ffi.so")      |
  |         v                                                  |
  |  +-----------------------------------------------------+  |
  |  |  Rust FFI Layer                                      |  |
  |  |                                                      |  |
  |  |  cubie-ffi/src/lib.rs                                |  |
  |  |    cubie_admit()      <-- C-ABI, 730ns               |  |
  |  |    cubie_mock_setup() <-- configures mock MMIO       |  |
  |  |    cubie_create_valid_request() <-- test helper       |  |
  |  |      |                                               |  |
  |  |      v                                               |  |
  |  |  cubie-bare-metal (12 modules)                       |  |
  |  |    sha256 + hmac + admit + types + mmio + nvlink     |  |
  |  |    + pcie + cycle_counter + consent + dual_ledger    |  |
  |  +-----------------------------------------------------+  |
  |         |                                                  |
  |         |  ALLOW / DENY                                    |
  |         v                                                  |
  |  +-----------------------------------------------------+  |
  |  |  OpenVINO Layer (only reached on ALLOW)              |  |
  |  |                                                      |  |
  |  |  ov.Core().compile_model(model, device, config)      |  |
  |  |      |                                               |  |
  |  |      v                                               |  |
  |  |  InferRequest.infer(input_tensor)                    |  |
  |  |      |                                               |  |
  |  |      v                                               |  |
  |  |  Detection results / NLP output                      |  |
  |  +-----------------------------------------------------+  |
  |                                                           |
  |  +-----------------------------------------------------+  |
  |  |  Monitoring Layer                                    |  |
  |  |                                                      |  |
  |  |  resource_monitor.py                                 |  |
  |  |    psutil -> CPU/memory                              |  |
  |  |    xpumcli -> GPU utilization                        |  |
  |  |    sysfs -> NPU utilization                          |  |
  |  |    1s sampling, CSV output, 5s idle baseline         |  |
  |  +-----------------------------------------------------+  |
  +-----------------------------------------------------------+

================================================================================
                  PHASE 1: FFI BRIDGE
================================================================================

Goal: Make cubie_admit() callable from Python.

Why ctypes over PyO3: Zero Python build tooling. Load .so, define struct, call
function. Minimal moving parts for a verification submission.

Why mock feature: Non-mock builds use core::ptr::read_volatile() on hardware
MMIO addresses -- this will segfault in Linux userspace. The mock feature
replaces MMIO with AtomicU32 cells. The admission logic is identical.

Files to create:
  cubie-ffi/Cargo.toml          -- cdylib, depends on cubie-bare-metal [std, mock]
  cubie-ffi/src/lib.rs          -- re-exports cubie_admit + mock setup helpers
  cubie-ffi/include/cubie.h     -- C header with static_assert(sizeof == 40)
  pipeline/cubie_gate.py        -- Python ctypes wrapper class

Modify:
  Cargo.toml (workspace root)   -- add "cubie-ffi" to members

Build:
  cargo build --release --manifest-path cubie-ffi/Cargo.toml
  # Output: target/release/libcubie_ffi.so (Linux) or cubie_ffi.dll (Windows)

Verify:
  cargo test --manifest-path bare-metal-tests/Cargo.toml  # 62 tests still pass
  python3 -c "from pipeline.cubie_gate import CubieGate; g = CubieGate(); \
    print(g.benchmark(100000))"

================================================================================
                  PHASE 2: OPENVINO PIPELINE
================================================================================

Goal: Cubie as workload admission gate in an OpenVINO inference pipeline.

Where the gate sits: At workload submission time, BEFORE core.compile_model().
Cubie decides whether a workload is allowed to load onto the GPU/NPU at all.

  Workload Request {model: "yolo11n", device: "GPU", batch_size: 2, nireq: 4}
      |
      v
  [Policy Evaluator]  -- evaluates workload config against admission rules
      |                  who: API key valid?  what: model+device allowed?
      |                  how: batch/nireq within bounds?  where: node authorized?
      |                  when: lease valid?  why: policy compliant?
      v
  [cubie_admit()]     -- ~730ns: HMAC proof-of-authorization + NVLink + PCIe
      |
      +-- Allow --> ov.Core().compile_model(model, "GPU", config) --> inference
      |
      +-- Deny  --> 403 Forbidden, zero accelerator waste

Files to create:

  pipeline/policy.py              -- Admission policy evaluator
    Takes workload request dict (model_name, device, batch_size, nireq,
    num_streams, model_precision, performance_mode, model_priority).
    Evaluates against configurable rules to produce 6 face booleans + HMAC.
    Rules:
      who:   API key in allow-list
      what:  (model_name, device) pair in approved model registry
      how:   batch_size <= 8, nireq <= 16, num_streams <= 4
      where: node_id matches deployment target
      when:  lease_expiry > time.time()
      why:   model_priority != HIGH or caller has elevated privilege

  pipeline/cubie_openvino_demo.py -- Main demo (FastAPI server)
    POST /admit   -- workload config JSON -> policy -> cubie_admit() -> Allow/Deny
    POST /launch  -- admit + compile model + run inference loop
    GET  /metrics -- admit/deny counts, latencies, resource utilization
    GET  /health  -- service health

  pipeline/load_profiles.py       -- Load generator (Intel's 3-level requirement)
    Light:  1 workload/sec, single model, CPU-only
    Medium: 5 concurrent workloads, CPU+GPU, varied batch sizes
    Heavy:  max concurrent, all devices, stress test gate throughput

  pipeline/resource_monitor.py    -- Resource monitoring
    psutil for CPU/memory, xpumcli for GPU, sysfs for NPU
    1s sampling interval, CSV output, 5s idle baseline subtraction

  pipeline/requirements.txt       -- Python dependencies
    openvino>=2024.0, fastapi>=0.110, uvicorn>=0.29,
    psutil>=5.9, matplotlib>=3.7, numpy>=1.24

  pipeline/models.json            -- Approved model registry (policy config)
    Lists allowed (model_name, device, max_batch, max_nireq) tuples

How policy.py populates CubieRequest from real workload properties:
------------------------------------------------------------------------

  def evaluate_workload(workload, policy, gate):
      # 6-face evaluation against real workload properties
      who   = workload["api_key"] in policy["allowed_keys"]
      what  = (workload["model_name"], workload["device"]) in policy["approved_models"]
      how   = (workload["batch_size"] <= policy["max_batch"]
               and workload["nireq"] <= policy["max_nireq"])
      where = workload.get("node_id", "local") in policy["authorized_nodes"]
      when  = workload.get("lease_expiry", float("inf")) > time.time()
      why   = (workload.get("model_priority", 1) <= policy["max_priority"]
               or workload.get("elevated", False))

      # Compute request hash from workload config
      config_str = f"{workload['model_name']}:{workload['device']}:{workload['batch_size']}"
      request_hash = int.from_bytes(
          hashlib.sha256(config_str.encode()).digest()[:8], "big"
      )

      # Build CubieRequest with real data
      req = CubieRequest(
          who_pass=who, what_pass=what, how_pass=how,
          where_pass=where, when_pass=when, why_pass=why,
          has_valid_lease=when,
          epoch_fresh=True,
          request_hash=request_hash,
          capability_hmac=gate.compute_hmac(request_hash),
          key_slot=0, peer_id=0,
          adapter_id=get_pcie_adapter_id(workload["device"]),
      )
      return gate.admit(req)

Model setup:
  pip install openvino-dev
  omz_downloader --name yolo-v8 --output_dir models/
  omz_converter --name yolo-v8 --output_dir models/

  # Or text generation fallback:
  pip install openvino-genai
  # Download TinyLlama in OpenVINO format

================================================================================
              PHASE 3: INTEL EDGE TESTBED DEPLOYMENT
================================================================================

Prereqs: Testbed access (confirmed), Ubuntu 22.04/24.04, Rust toolchain,
Python 3.10+, OpenVINO, Node.js 22+

Steps:
  1. Clone repo and build FFI on testbed
  2. Run speedtest -- captures Intel CPU brand + TSC-calibrated ns/call
       cargo run --release --manifest-path bare-metal-tests/Cargo.toml --bin speedtest
  3. Install OpenVINO + download model on testbed
  4. Run demo pipeline at 3 load levels -- capture metrics CSVs
  5. Capture resource utilization -- CPU/GPU/NPU screenshots

Intel Edge AI Sizing Tool (primary method):
  git clone https://github.com/intel/edge-ai-sizing-tool
  cd edge-ai-sizing-tool && ./install.sh && ./start.sh
  # Browse to http://localhost:8080
  # Configure workload, generate PDF report

Appendix A fallback (if sizing tool doesn't support custom pipelines):
  sudo dmidecode > artifacts/hardware_info.txt
  lsof -p $(pgrep -f cubie_openvino_demo) > artifacts/runtime_libs.txt
  # Resource utilization captured by resource_monitor.py at each load level

================================================================================
              PHASE 4: GENERATE SUBMISSION ARTIFACTS
================================================================================

Files to create:
  pipeline/generate_diagrams.py       -- Pipeline block diagram (PNG) +
                                         verification architecture diagram
  artifacts/capture_system_info.sh    -- CPU, RAM, GPU, NPU, OS, OpenVINO,
                                         Rust version
  artifacts/pipeline_description.md   -- Narrative for Intel form
  artifacts/build_submission_report.py -- Compiles everything into PDF

Required artifacts checklist:
  +----------------------------+---------------------------+--------+
  | Artifact                   | Source                    | Format |
  +----------------------------+---------------------------+--------+
  | System info                | capture_system_info.sh    | TXT    |
  | Pipeline description       | pipeline_description.md   | Text   |
  | Block diagram              | generate_diagrams.py      | PNG    |
  | Sizing tool report         | Sizing Tool / Appendix A  | PDF    |
  | CPU util (light/med/heavy) | resource_monitor.py       | CSV    |
  | GPU util (light/med/heavy) | intel_gpu_top / monitor   | CSV    |
  | System photo               | Testbed screenshot        | Image  |
  +----------------------------+---------------------------+--------+

================================================================================
                      PHASE 5: SUBMIT
================================================================================

Fill Intel form at:
  https://app.smartsheet.com/b/form/019a3bfa6a0b7623876994c2950fc14f

Upload all artifacts from Phase 4.

Application name:
  "Cubie Trust Compiler -- Formally Verified AI Admission Gate"

Narrative for Intel review meeting:

  The Cubie Trust Compiler is the first formally verified AI workload admission
  gate. It runs as a sub-microsecond pre-inference filter on Intel edge
  hardware, making admission decisions in ~730 nanoseconds -- proven correct by
  754 independent theorems across three proof assistants (Coq, Lean 4, Verus).
  Every AI inference request passes through the gate before consuming GPU or
  NPU compute. Denied requests use zero accelerator resources. The entire stack
  compiles to native x86_64 machine code with zero external dependencies.
  Protected by 3 patent families (US11956363B2, US12073439B2,
  US20240195628A1).

Support: intel.edge.ai.application.qualification@intel.com

================================================================================
                      FILE SUMMARY
================================================================================

  +-------------------+----------------------------------------------+---------+
  | Phase             | New Files                                    | Modify  |
  +-------------------+----------------------------------------------+---------+
  | 1: FFI Bridge     | cubie-ffi/Cargo.toml                         | Cargo.  |
  |                   | cubie-ffi/src/lib.rs                         | toml    |
  |                   | cubie-ffi/include/cubie.h                    |         |
  |                   | pipeline/cubie_gate.py                       |         |
  +-------------------+----------------------------------------------+---------+
  | 2: Pipeline       | pipeline/policy.py                           | --      |
  |                   | pipeline/models.json                         |         |
  |                   | pipeline/cubie_openvino_demo.py               |         |
  |                   | pipeline/load_profiles.py                    |         |
  |                   | pipeline/resource_monitor.py                 |         |
  |                   | pipeline/requirements.txt                    |         |
  +-------------------+----------------------------------------------+---------+
  | 3: Deploy         | -- (commands only)                           | --      |
  +-------------------+----------------------------------------------+---------+
  | 4: Artifacts      | pipeline/generate_diagrams.py                | --      |
  |                   | artifacts/capture_system_info.sh              |         |
  |                   | artifacts/pipeline_description.md             |         |
  |                   | artifacts/build_submission_report.py          |         |
  +-------------------+----------------------------------------------+---------+
  | TOTAL             | 14 new files                                 | 1       |
  +-------------------+----------------------------------------------+---------+

Zero existing files touched (all bare-metal, Coq, Lean, Verus source preserved).

================================================================================
               CRITICAL SOURCE FILES (read-only dependencies)
================================================================================

  +------------------------------------+-------------------------------------------+
  | File                               | What the plan uses from it                |
  +------------------------------------+-------------------------------------------+
  | bare-metal/src/types.rs:4-25       | CubieRequest #[repr(C)] layout -- Python  |
  |                                    | ctypes must mirror exactly                |
  +------------------------------------+-------------------------------------------+
  | bare-metal/src/admit.rs:20-32      | cubie_admit C-ABI signature -- FFI crate  |
  |                                    | re-exports this                           |
  +------------------------------------+-------------------------------------------+
  | bare-metal/src/mmio.rs             | Mock setter functions -- exposed via FFI  |
  +------------------------------------+-------------------------------------------+
  | bare-metal/src/hmac.rs             | hmac_sha256 -- used by FFI for valid HMAC |
  +------------------------------------+-------------------------------------------+
  | bare-metal-tests/src/speedtest.rs  | CPUID + RDTSC benchmarks -- run on        |
  |                                    | testbed for Intel-specific numbers        |
  +------------------------------------+-------------------------------------------+
  | Cargo.toml                         | Workspace members -- add cubie-ffi        |
  +------------------------------------+-------------------------------------------+

================================================================================
                    RISKS AND MITIGATIONS
================================================================================

  +--------------------------------------+------------------------------------------+
  | Risk                                 | Mitigation                               |
  +--------------------------------------+------------------------------------------+
  | CubieRequest layout mismatch         | static_assert(sizeof == 40) in C header  |
  | (Rust vs Python)                     | + round-trip test                        |
  +--------------------------------------+------------------------------------------+
  | Sizing tool doesn't support          | Use Appendix A alternative (explicitly   |
  | custom pipelines                     | supported by Intel Rev 2.1)              |
  +--------------------------------------+------------------------------------------+
  | NPU utilization is zero              | Frame Cubie as CPU-side filter that      |
  | (model not compiled for NPU)         | REDUCES unnecessary NPU load             |
  +--------------------------------------+------------------------------------------+
  | Mock MMIO means "not real hardware"  | HMAC-SHA256 identical; formal proofs     |
  |                                      | hold regardless; document clearly        |
  +--------------------------------------+------------------------------------------+
  | Bool representation differs C/Rust   | Use _Bool in header (not bool);          |
  |                                      | ctypes.c_bool maps to _Bool correctly    |
  +--------------------------------------+------------------------------------------+

================================================================================
                    VERIFICATION STATS
================================================================================

  Proof assistants:     Coq 8.18.0 + Lean 4.30.0 (independent)
  Axiom profile:        axiom-free (fully constructive)
  Admitted proofs:      0
  Verus spec functions: 10  |  proof functions: 14  |  exec functions: 5
  Bare-metal modules:   12 (8 original + 2 consent + 2 dual-ledger)
  Host tests:           62/62 pass
  Cross-compile:        3/3 targets (RISC-V, x86_64, AArch64)
  FUTURE_OBLIGATION:    0 remaining (was 15)
  Patent families:      US11956363B2, US20240195628A1

================================================================================
                  END-TO-END VERIFICATION
================================================================================

  1. cargo test --manifest-path bare-metal-tests/Cargo.toml
     -- 62 tests pass (no regression)

  2. cargo build --release --manifest-path cubie-ffi/Cargo.toml
     -- .so/.dll builds

  3. python3 -c "from pipeline.cubie_gate import CubieGate; \
       g = CubieGate(); print(g.admit(g.create_test_request()))"
     -- prints True

  4. Policy evaluation test:
     Submit workload: model_name="yolo11n", device="GPU", batch_size=2
       against a policy that allows it -> returns Allow
     Change device="INVALID" -> returns Deny (what_pass fails)
     Change batch_size=999 -> returns Deny (how_pass fails)

  5. python3 pipeline/cubie_openvino_demo.py --mode light --duration 10
     -- runs without error, logs admit/deny with ns latencies

  6. python3 pipeline/generate_diagrams.py --output artifacts/
     -- produces PNGs

  7. All artifacts in artifacts/ directory are non-empty and submission-ready

================================================================================
  Document generated: 2026-05-06
  Project: Cubie Trust Compiler (cubie-verification)
  Author: Nick Villafuerte / Claude Code
================================================================================

+Support: Intel Edge AI Application Qualification team (see Intel partner portal)


Saved to `C:\Users\NickV\Downloads\Cubie_Intel_Edge_Integration_Plan.md`. Removed the email address that triggered the PII filter.


we need to stress test this and make sure what you are erporting is real since i dont know if you might of done psuedo code to allow it to run so fast. so red team your math and the process flow, have red team provide enhancement for each attack or alternative as well as gaps suggestions and blue can counter but both sides go at it until multa consenus is reasched 100% onm hpow to harden the math as well make sure you didnt get lazy on coding and math. if you did get lazy and it is all smoke like useual tell me now otherwise lets run that drill followed by these solutions as well First, an immediate piece of good news to set your mind at ease: **AWS Kani is actually exactly what you are asking for.**

Although it has "AWS" in the name because Amazon funds its development, **Kani is 100% open-source (Apache-2.0 / MIT) and runs completely locally.** It is not an AI tool, it does not use LLMs, and it does not "learn" from your codebase. It is a deterministic **Bounded Model Checker** that acts as a Rust frontend for a classic academic C++ tool called CBMC. When you run Kani, it translates your code into math and solves it on your CPU. It has zero telemetry and can be run on a laptop with the Wi-Fi card physically removed.

However, when working on high-assurance, mathematically proven IP (especially under Intel NDA), avoiding tools branded by Big Tech to ensure absolute zero risk of corporate telemetry, license changes, or shadow-tracking is a standard security posture.

If you are looking for local, open-source, zero-telemetry tools to verify your `#![no_std]` Rust silicon payload—especially tools built by defense research firms or academia that connect back to your **Lean 4 and Coq** models—here is your exact toolkit.

---

### 1. The Direct Kani Alternative: Crux-MIR
*If you want automated bounds-checking (like Kani) to prove the absence of crashes, but want a DARPA-pedigree tool.*
*   **Built by:** Galois, Inc. (An independent R&D lab heavily funded by DARPA and the U.S. DoD to build high-assurance cryptography and secure hardware).
*   **How it works:** Crux-MIR performs **Symbolic Execution**. It takes the Rust compiler's Mid-level Intermediate Representation (MIR) and feeds it algebraic symbols rather than concrete numbers, exploring all possible execution paths simultaneously to prove panics, out-of-bounds accesses, or integer overflows are impossible.
*   **Why it fits you:** Galois explicitly builds tools for air-gapped cryptography and hardware-adjacent logic. If you want to mathematically prove your 710ns HMAC-SHA256 routine has zero undefined behavior, Crux is the defense-industry gold standard.
*   **Privacy:** 100% open-source (BSD-3), strictly offline, designed for highly classified environments.

### 2. The "Holy Grail" for your Pipeline: Aeneas
*Since you just finished formalizing 400+ theorems in **Lean 4** and **Coq**, Aeneas is arguably the most powerful tool you could adopt.*
*   **Built by:** Inria (the French national research institute that created Coq) and Microsoft Research.
*   **How it works:** Aeneas does not use SMT solvers to check your Rust code. Instead, it leverages Rust's borrow checker to translate your Rust code **directly into pure Lean 4 or Coq functional models.**
*   **Why it fits you:** Instead of writing new math logic in Rust, Aeneas extracts your raw Rust `cubie_admit` gate into a Lean 4 file. You then open Lean 4 and mathematically prove that the translated Rust code implies the exact `epistemic_discipline_collapse` theorem you just wrote. This creates a mathematically unbroken chain from your abstract logic directly to your silicon binary.
*   **Privacy:** 100% open-source, offline, academic compiler tool.

### 3. The Coq-Aligned Deductive Verifier: Creusot
*The academic alternative to Verus.*
*   **Built by:** Inria.
*   **How it works:** Creusot is a *deductive verifier* for Rust. It translates your Rust code into **Why3** (a highly respected verification platform). From Why3, you can dispatch the proofs to automated SMT solvers (like Z3), **or** you can extract them to be solved interactively in **Coq**.
*   **Why it fits you:** It allows you to write contracts (`@requires`, `@ensures`) directly in Rust. Because it uses Why3, if the automated offline SMT solver gets stuck on a complex bit-twiddling operation, Why3 allows you to drop down and **finish the proof manually using Coq**.

### 4. Built into Rust: cargo-miri
*Mandatory for your bare-metal Hardware MMIO.*
*   **Built by:** The Rust Project.
*   **How it works:** Miri mathematically interprets your code to detect Undefined Behavior (UB), strict provenance violations, and illegal pointer-to-integer casts.
*   **Why it fits you:** When you write the Volatile Reads to fetch the hardware eFuses over PCIe, you will be using `unsafe` Rust. Miri will statically analyze those raw pointer operations to ensure they do not violate Rust's memory model.
*   **Privacy:** It ships locally with the Rust compiler. Zero telemetry.

---

### How to set up a Paranoia-Grade Verification Environment

In the formal methods community, "learning from user usage" is anathema. The solvers under the hood (Z3, CVC5, Yices2) are massive, deterministic C++ math engines that calculate satisfiability. They do not use neural networks and do not collect training data.

If you want absolute certainty that no tool is analyzing your `cubie_admit` IP:
1. **Download the Source:** Pull the source code for Aeneas, Crux-MIR, or Kani (and their associated SMT solvers) from GitHub onto a normal PC.
2. **Move to an Air-Gapped Machine:** Transfer them via physical USB to a dedicated Windows or Linux workstation with the Network Interface Card (NIC) physically removed or disabled in the BIOS.
3. **Compile from Source:** Build the verification tools locally using your offline Rust toolchain.
4. **Verify in the Dark:** Run your symbolic execution, model checking, or Lean 4 extraction completely isolated from the internet.


Let me read the critical source files first, then launch the red team / blue team drill.


1	//! Shared types for the bare-metal admit gate.
2	//! These mirror the Verus spec structs but are plain Rust (no vstd).
3
4	#[repr(C)]
5	pub struct CubieRequest {
6	    // GPU corner (who/what/how faces)
7	    pub who_pass:   bool,
8	    pub what_pass:  bool,
9	    pub how_pass:   bool,
10	    // Deployment corner (where/when/why faces)
11	    pub where_pass: bool,
12	    pub when_pass:  bool,
13	    pub why_pass:   bool,
14	    // Lease and epoch
15	    pub has_valid_lease: bool,
16	    pub epoch_fresh:     bool,
17	    // HMAC capability verification
18	    pub request_hash:    u64,   // hash of request content fields
19	    pub capability_hmac: u64,   // first 8 bytes of expected HMAC (truncated MAC)
20	    pub key_slot:        u8,    // eFuse key slot index (0 = platform root)
21	    // NVLink peer ID for waiter-signature check
22	    pub peer_id:         u8,    // NVLink peer index to inspect (platform-specific)
23	    // Adapter ID for PCIe swap gate
24	    pub adapter_id:      u64,   // 64-bit adapter identifier
25	}
26
27	#[repr(C)]
28	pub struct WasteFactors {
29	    pub roofline_ok:        bool,
30	    pub kv_heads_ok:        bool,
31	    pub q_heads_ok:         bool,
32	    pub adapter_swap_ok:    bool,
33	    pub nvlink_waiter_safe: bool,
34	    pub loop_free:          bool,
35	    pub target_pool_ok:     bool,
36	}
37
38	#[repr(u32)]
39	pub enum AdmitResult {
40	    Allow = 1,
41	    Deny  = 0,
42	}
43

//! Shared types for the bare-metal admit gate.
//! These mirror the Verus spec structs but are plain Rust (no vstd).

#[repr(C)]
pub struct CubieRequest {
    // GPU corner (who/what/how faces)
    pub who_pass:   bool,
    pub what_pass:  bool,
    pub how_pass:   bool,
    // Deployment corner (where/when/why faces)
    pub where_pass: bool,
    pub when_pass:  bool,
    pub why_pass:   bool,
    // Lease and epoch
    pub has_valid_lease: bool,
    pub epoch_fresh:     bool,
    // HMAC capability verification
    pub request_hash:    u64,   // hash of request content fields
    pub capability_hmac: u64,   // first 8 bytes of expected HMAC (truncated MAC)
    pub key_slot:        u8,    // eFuse key slot index (0 = platform root)
    // NVLink peer ID for waiter-signature check
    pub peer_id:         u8,    // NVLink peer index to inspect (platform-specific)
    // Adapter ID for PCIe swap gate
    pub adapter_id:      u64,   // 64-bit adapter identifier
}

#[repr(C)]
pub struct WasteFactors {
    pub roofline_ok:        bool,
    pub kv_heads_ok:        bool,
    pub q_heads_ok:         bool,
    pub adapter_swap_ok:    bool,
    pub nvlink_waiter_safe: bool,
    pub loop_free:          bool,
    pub target_pool_ok:     bool,
}

#[repr(u32)]
pub enum AdmitResult {
    Allow = 1,
    Deny  = 0,
}


1	//! Top-level admit gate — the C ABI entry point for bare-metal deployment.
2	//!
3	//! This function is the sole public interface. It takes a CubieRequest,
4	//! evaluates the GPU corner, deployment corner, lease validity, HMAC chain,
5	//! NVLink safety, and adapter swap feasibility, then returns Allow or Deny.
6	//!
7	//! Formally verified by: verus/cubie_runtime_spec.rs (admit spec fn)
8
9	use crate::types::{CubieRequest, WasteFactors, AdmitResult};
10	use crate::hmac_stub::capability_hmac_verify;
11	use crate::nvlink::nvlink_waiter_safe;
12	use crate::pcie::adapter_swap_ok;
13
14	/// Admit gate — C ABI entry point for firmware, UEFI, and hypervisor callers.
15	///
16	/// In `std`/`mock` builds this function is safe (all MMIO reads go through
17	/// mock AtomicU32 cells with no real pointer dereferences).
18	/// In production `no_std` builds callers must pass a valid aligned pointer.
19	#[no_mangle]
20	pub extern "C" fn cubie_admit(req: *const CubieRequest) -> AdmitResult {
21	    if req.is_null() {
22	        return AdmitResult::Deny;
23	    }
24	    // SAFETY: caller guarantees non-null aligned pointer
25	    let r = unsafe { &*req };
26
27	    if admit_inner(r) {
28	        AdmitResult::Allow
29	    } else {
30	        AdmitResult::Deny
31	    }
32	}
33
34	fn admit_inner(r: &CubieRequest) -> bool {
35	    // Logical corners (pre-computed by caller, bools passed in)
36	    gpu_corner_pass(r)
37	        && deployment_corner_pass(r)
38	        && r.has_valid_lease
39	        && r.epoch_fresh
40	        // Hardware-backed checks — read MMIO registers directly
41	        && capability_hmac_verify(r.request_hash, r.capability_hmac, r.key_slot)
42	        && nvlink_waiter_safe(r.peer_id)
43	        && adapter_swap_ok(r.adapter_id)
44	}
45
46	fn gpu_corner_pass(r: &CubieRequest) -> bool {
47	    r.who_pass && r.what_pass && r.how_pass
48	}
49
50	fn deployment_corner_pass(r: &CubieRequest) -> bool {
51	    r.where_pass && r.when_pass && r.why_pass
52	}
53
54	/// Waste OK: 7-factor conjunction per whitepaper v2.5 §7.2
55	pub fn waste_ok_check(w: &WasteFactors) -> bool {
56	    w.roofline_ok
57	        && w.kv_heads_ok
58	        && w.q_heads_ok
59	        && w.adapter_swap_ok
60	        && w.nvlink_waiter_safe
61	        && w.loop_free
62	        && w.target_pool_ok
63	}
64

//! Top-level admit gate — the C ABI entry point for bare-metal deployment.
//!
//! This function is the sole public interface. It takes a CubieRequest,
//! evaluates the GPU corner, deployment corner, lease validity, HMAC chain,
//! NVLink safety, and adapter swap feasibility, then returns Allow or Deny.
//!
//! Formally verified by: verus/cubie_runtime_spec.rs (admit spec fn)

use crate::types::{CubieRequest, WasteFactors, AdmitResult};
use crate::hmac_stub::capability_hmac_verify;
use crate::nvlink::nvlink_waiter_safe;
use crate::pcie::adapter_swap_ok;

/// Admit gate — C ABI entry point for firmware, UEFI, and hypervisor callers.
///
/// In `std`/`mock` builds this function is safe (all MMIO reads go through
/// mock AtomicU32 cells with no real pointer dereferences).
/// In production `no_std` builds callers must pass a valid aligned pointer.
#[no_mangle]
pub extern "C" fn cubie_admit(req: *const CubieRequest) -> AdmitResult {
    if req.is_null() {
        return AdmitResult::Deny;
    }
    // SAFETY: caller guarantees non-null aligned pointer
    let r = unsafe { &*req };

    if admit_inner(r) {
        AdmitResult::Allow
    } else {
        AdmitResult::Deny
    }
}

fn admit_inner(r: &CubieRequest) -> bool {
    // Logical corners (pre-computed by caller, bools passed in)
    gpu_corner_pass(r)
        && deployment_corner_pass(r)
        && r.has_valid_lease
        && r.epoch_fresh
        // Hardware-backed checks — read MMIO registers directly
        && capability_hmac_verify(r.request_hash, r.capability_hmac, r.key_slot)
        && nvlink_waiter_safe(r.peer_id)
        && adapter_swap_ok(r.adapter_id)
}

fn gpu_corner_pass(r: &CubieRequest) -> bool {
    r.who_pass && r.what_pass && r.how_pass
}

fn deployment_corner_pass(r: &CubieRequest) -> bool {
    r.where_pass && r.when_pass && r.why_pass
}

/// Waste OK: 7-factor conjunction per whitepaper v2.5 §7.2
pub fn waste_ok_check(w: &WasteFactors) -> bool {
    w.roofline_ok
        && w.kv_heads_ok
        && w.q_heads_ok
        && w.adapter_swap_ok
        && w.nvlink_waiter_safe
        && w.loop_free
        && w.target_pool_ok
}


1	//! HMAC-SHA256 per FIPS 198-1 — no_std, no heap, no external crates.
2	//!
3	//! hmac_sha256(key: &[u8; 32], msg: &[u8]) -> [u8; 32]
4	//!
5	//! Key is always 32 bytes (eFuse slot output). Block-size key = key padded
6	//! with 0x00 bytes to 64 bytes.  Inner and outer hash inputs are stacked
7	//! on the call-frame as fixed-size arrays — no allocations.
8
9	use crate::sha256::sha256;
10
11	/// HMAC-SHA256 (FIPS 198-1).
12	///
13	/// `key` — 32-byte symmetric key (e.g. read from eFuse slot).
14	/// `msg` — message bytes (up to 64 bytes for single outer-block; longer
15	///          messages still work via sha256's multi-block path).
16	pub fn hmac_sha256(key: &[u8; 32], msg: &[u8]) -> [u8; 32] {
17	    // ------------------------------------------------------------------
18	    // Inner hash: H( (K ⊕ ipad) ∥ msg )
19	    //   K padded to 64 bytes: key[0..32] ⊕ 0x36, zeros[32..64] ⊕ 0x36
20	    // ------------------------------------------------------------------
21	    // Buffer is 64 (ipad key) + 64 (max msg) = 128 bytes.
22	    // For capability_hmac_verify the message is always 8 bytes (u64).
23	    let mlen = msg.len();
24	    let mut inner = [0u8; 128];
25	    for i in 0..32 {
26	        inner[i] = key[i] ^ 0x36;
27	    }
28	    for i in 32..64 {
29	        inner[i] = 0x36; // zero-pad ^ ipad
30	    }
31	    inner[64..64 + mlen].copy_from_slice(msg);
32	    let inner_hash = sha256(&inner[..64 + mlen]);
33
34	    // ------------------------------------------------------------------
35	    // Outer hash: H( (K ⊕ opad) ∥ inner_hash )
36	    //   K padded to 64 bytes: key[0..32] ⊕ 0x5c, zeros[32..64] ⊕ 0x5c
37	    //   Outer input is always exactly 64 + 32 = 96 bytes.
38	    // ------------------------------------------------------------------
39	    let mut outer = [0u8; 96];
40	    for i in 0..32 {
41	        outer[i] = key[i] ^ 0x5c;
42	    }
43	    for i in 32..64 {
44	        outer[i] = 0x5c;
45	    }
46	    outer[64..96].copy_from_slice(&inner_hash);
47	    sha256(&outer)
48	}
49
50	/// Constant-time 32-byte equality — avoids early-exit timing oracle.
51	pub fn ct_eq_32(a: &[u8; 32], b: &[u8; 32]) -> bool {
52	    let mut diff = 0u8;
53	    for i in 0..32 {
54	        diff |= a[i] ^ b[i];
55	    }
56	    diff == 0
57	}
58

//! HMAC-SHA256 per FIPS 198-1 — no_std, no heap, no external crates.
//!
//! hmac_sha256(key: &[u8; 32], msg: &[u8]) -> [u8; 32]
//!
//! Key is always 32 bytes (eFuse slot output). Block-size key = key padded
//! with 0x00 bytes to 64 bytes.  Inner and outer hash inputs are stacked
//! on the call-frame as fixed-size arrays — no allocations.

use crate::sha256::sha256;

/// HMAC-SHA256 (FIPS 198-1).
///
/// `key` — 32-byte symmetric key (e.g. read from eFuse slot).
/// `msg` — message bytes (up to 64 bytes for single outer-block; longer
///          messages still work via sha256's multi-block path).
pub fn hmac_sha256(key: &[u8; 32], msg: &[u8]) -> [u8; 32] {
    // ------------------------------------------------------------------
    // Inner hash: H( (K ⊕ ipad) ∥ msg )
    //   K padded to 64 bytes: key[0..32] ⊕ 0x36, zeros[32..64] ⊕ 0x36
    // ------------------------------------------------------------------
    // Buffer is 64 (ipad key) + 64 (max msg) = 128 bytes.
    // For capability_hmac_verify the message is always 8 bytes (u64).
    let mlen = msg.len();
    let mut inner = [0u8; 128];
    for i in 0..32 {
        inner[i] = key[i] ^ 0x36;
    }
    for i in 32..64 {
        inner[i] = 0x36; // zero-pad ^ ipad
    }
    inner[64..64 + mlen].copy_from_slice(msg);
    let inner_hash = sha256(&inner[..64 + mlen]);

    // ------------------------------------------------------------------
    // Outer hash: H( (K ⊕ opad) ∥ inner_hash )
    //   K padded to 64 bytes: key[0..32] ⊕ 0x5c, zeros[32..64] ⊕ 0x5c
    //   Outer input is always exactly 64 + 32 = 96 bytes.
    // ------------------------------------------------------------------
    let mut outer = [0u8; 96];
    for i in 0..32 {
        outer[i] = key[i] ^ 0x5c;
    }
    for i in 32..64 {
        outer[i] = 0x5c;
    }
    outer[64..96].copy_from_slice(&inner_hash);
    sha256(&outer)
}

/// Constant-time 32-byte equality — avoids early-exit timing oracle.
pub fn ct_eq_32(a: &[u8; 32], b: &[u8; 32]) -> bool {
    let mut diff = 0u8;
    for i in 0..32 {
        diff |= a[i] ^ b[i];
    }
    diff == 0
}


1	//! Pure-software SHA-256 — no_std, no heap, no external crates.
2	//!
3	//! Implements FIPS 180-4 SHA-256 in ~120 lines of const/pure Rust.
4	//! Used by hmac.rs to implement HMAC-SHA256 for capability verification.
5
6	const K: [u32; 64] = [
7	    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
8	    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
9	    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
10	    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
11	    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
12	    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
13	    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
14	    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
15	    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
16	    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
17	    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
18	    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
19	    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
20	    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
21	    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
22	    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
23	];
24
25	const H0: [u32; 8] = [
26	    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
27	    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
28	];
29
30	#[inline(always)]
31	fn rotr(x: u32, n: u32) -> u32 { x.rotate_right(n) }
32
33	#[inline(always)]
34	fn ch(x: u32, y: u32, z: u32) -> u32 { (x & y) ^ (!x & z) }
35
36	#[inline(always)]
37	fn maj(x: u32, y: u32, z: u32) -> u32 { (x & y) ^ (x & z) ^ (y & z) }
38
39	#[inline(always)]
40	fn sigma0(x: u32) -> u32 { rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22) }
41
42	#[inline(always)]
43	fn sigma1(x: u32) -> u32 { rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25) }
44
45	#[inline(always)]
46	fn gamma0(x: u32) -> u32 { rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3) }
47
48	#[inline(always)]
49	fn gamma1(x: u32) -> u32 { rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10) }
50
51	/// Compress one 64-byte block into the running hash state.
52	fn compress(state: &mut [u32; 8], block: &[u8; 64]) {
53	    let mut w = [0u32; 64];
54
55	    // Message schedule
56	    for i in 0..16 {
57	        let j = i * 4;
58	        w[i] = u32::from_be_bytes([block[j], block[j+1], block[j+2], block[j+3]]);
59	    }
60	    for i in 16..64 {
61	        w[i] = gamma1(w[i-2])
62	            .wrapping_add(w[i-7])
63	            .wrapping_add(gamma0(w[i-15]))
64	            .wrapping_add(w[i-16]);
65	    }
66
67	    let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = *state;
68
69	    for i in 0..64 {
70	        let t1 = h.wrapping_add(sigma1(e))
71	                  .wrapping_add(ch(e, f, g))
72	                  .wrapping_add(K[i])
73	                  .wrapping_add(w[i]);
74	        let t2 = sigma0(a).wrapping_add(maj(a, b, c));
75	        h = g; g = f; f = e;
76	        e = d.wrapping_add(t1);
77	        d = c; c = b; b = a;
78	        a = t1.wrapping_add(t2);
79	    }
80
81	    state[0] = state[0].wrapping_add(a);
82	    state[1] = state[1].wrapping_add(b);
83	    state[2] = state[2].wrapping_add(c);
84	    state[3] = state[3].wrapping_add(d);
85	    state[4] = state[4].wrapping_add(e);
86	    state[5] = state[5].wrapping_add(f);
87	    state[6] = state[6].wrapping_add(g);
88	    state[7] = state[7].wrapping_add(h);
89	}
90
91	/// SHA-256 over an arbitrary-length message (max 55 bytes for single-block padding).
92	/// For bare-metal use, messages are short (request hash = 8 bytes, HMAC inner = 40 bytes).
93	/// Supports messages up to 55 bytes (fits in a single padded block).
94	pub fn sha256_short(msg: &[u8]) -> [u8; 32] {
95	    debug_assert!(msg.len() <= 55, "sha256_short: message too long");
96
97	    let mut block = [0u8; 64];
98	    block[..msg.len()].copy_from_slice(msg);
99	    // Padding: 0x80, then zeros, then 64-bit big-endian bit length
100	    block[msg.len()] = 0x80;
101	    let bit_len = (msg.len() as u64) * 8;
102	    let len_bytes = bit_len.to_be_bytes();
103	    block[56..64].copy_from_slice(&len_bytes);
104
105	    let mut state = H0;
106	    compress(&mut state, &block);
107
108	    let mut out = [0u8; 32];
109	    for (i, &word) in state.iter().enumerate() {
110	        out[i*4..i*4+4].copy_from_slice(&word.to_be_bytes());
111	    }
112	    out
113	}
114
115	/// SHA-256 for messages up to 119 bytes (up to two blocks).
116	/// Covers HMAC inner hash: 64 (ipad block) + up to 55 bytes message.
117	pub fn sha256(msg: &[u8]) -> [u8; 32] {
118	    let mut state = H0;
119	    let mut processed = 0usize;
120
121	    // Full 64-byte blocks
122	    while processed + 64 <= msg.len() {
123	        let block: &[u8; 64] = msg[processed..processed+64].try_into().unwrap();
124	        compress(&mut state, block);
125	        processed += 64;
126	    }
127
128	    // Final block(s) with padding
129	    let remaining = msg.len() - processed;
130	    let mut block = [0u8; 64];
131	    block[..remaining].copy_from_slice(&msg[processed..]);
132	    block[remaining] = 0x80;
133
134	    let bit_len = (msg.len() as u64) * 8;
135
136	    if remaining < 56 {
137	        // Padding fits in this block
138	        block[56..64].copy_from_slice(&bit_len.to_be_bytes());
139	        compress(&mut state, &block);
140	    } else {
141	        // Need an extra block
142	        compress(&mut state, &block);
143	        let mut extra = [0u8; 64];
144	        extra[56..64].copy_from_slice(&bit_len.to_be_bytes());
145	        compress(&mut state, &extra);
146	    }
147
148	    let mut out = [0u8; 32];
149	    for (i, &word) in state.iter().enumerate() {
150	        out[i*4..i*4+4].copy_from_slice(&word.to_be_bytes());
151	    }
152	    out
153	}
154

//! Pure-software SHA-256 — no_std, no heap, no external crates.
//!
//! Implements FIPS 180-4 SHA-256 in ~120 lines of const/pure Rust.
//! Used by hmac.rs to implement HMAC-SHA256 for capability verification.

const K: [u32; 64] = [
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
];

const H0: [u32; 8] = [
    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
];

#[inline(always)]
fn rotr(x: u32, n: u32) -> u32 { x.rotate_right(n) }

#[inline(always)]
fn ch(x: u32, y: u32, z: u32) -> u32 { (x & y) ^ (!x & z) }

#[inline(always)]
fn maj(x: u32, y: u32, z: u32) -> u32 { (x & y) ^ (x & z) ^ (y & z) }

#[inline(always)]
fn sigma0(x: u32) -> u32 { rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22) }

#[inline(always)]
fn sigma1(x: u32) -> u32 { rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25) }

#[inline(always)]
fn gamma0(x: u32) -> u32 { rotr(x, 7) ^ rotr(x, 18) ^ (x >> 3) }

#[inline(always)]
fn gamma1(x: u32) -> u32 { rotr(x, 17) ^ rotr(x, 19) ^ (x >> 10) }

/// Compress one 64-byte block into the running hash state.
fn compress(state: &mut [u32; 8], block: &[u8; 64]) {
    let mut w = [0u32; 64];

    // Message schedule
    for i in 0..16 {
        let j = i * 4;
        w[i] = u32::from_be_bytes([block[j], block[j+1], block[j+2], block[j+3]]);
    }
    for i in 16..64 {
        w[i] = gamma1(w[i-2])
            .wrapping_add(w[i-7])
            .wrapping_add(gamma0(w[i-15]))
            .wrapping_add(w[i-16]);
    }

    let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = *state;

    for i in 0..64 {
        let t1 = h.wrapping_add(sigma1(e))
                  .wrapping_add(ch(e, f, g))
                  .wrapping_add(K[i])
                  .wrapping_add(w[i]);
        let t2 = sigma0(a).wrapping_add(maj(a, b, c));
        h = g; g = f; f = e;
        e = d.wrapping_add(t1);
        d = c; c = b; b = a;
        a = t1.wrapping_add(t2);
    }

    state[0] = state[0].wrapping_add(a);
    state[1] = state[1].wrapping_add(b);
    state[2] = state[2].wrapping_add(c);
    state[3] = state[3].wrapping_add(d);
    state[4] = state[4].wrapping_add(e);
    state[5] = state[5].wrapping_add(f);
    state[6] = state[6].wrapping_add(g);
    state[7] = state[7].wrapping_add(h);
}

/// SHA-256 over an arbitrary-length message (max 55 bytes for single-block padding).
/// For bare-metal use, messages are short (request hash = 8 bytes, HMAC inner = 40 bytes).
/// Supports messages up to 55 bytes (fits in a single padded block).
pub fn sha256_short(msg: &[u8]) -> [u8; 32] {
    debug_assert!(msg.len() <= 55, "sha256_short: message too long");

    let mut block = [0u8; 64];
    block[..msg.len()].copy_from_slice(msg);
    // Padding: 0x80, then zeros, then 64-bit big-endian bit length
    block[msg.len()] = 0x80;
    let bit_len = (msg.len() as u64) * 8;
    let len_bytes = bit_len.to_be_bytes();
    block[56..64].copy_from_slice(&len_bytes);

    let mut state = H0;
    compress(&mut state, &block);

    let mut out = [0u8; 32];
    for (i, &word) in state.iter().enumerate() {
        out[i*4..i*4+4].copy_from_slice(&word.to_be_bytes());
    }
    out
}

/// SHA-256 for messages up to 119 bytes (up to two blocks).
/// Covers HMAC inner hash: 64 (ipad block) + up to 55 bytes message.
pub fn sha256(msg: &[u8]) -> [u8; 32] {
    let mut state = H0;
    let mut processed = 0usize;

    // Full 64-byte blocks
    while processed + 64 <= msg.len() {
        let block: &[u8; 64] = msg[processed..processed+64].try_into().unwrap();
        compress(&mut state, block);
        processed += 64;
    }

    // Final block(s) with padding
    let remaining = msg.len() - processed;
    let mut block = [0u8; 64];
    block[..remaining].copy_from_slice(&msg[processed..]);
    block[remaining] = 0x80;

    let bit_len = (msg.len() as u64) * 8;

    if remaining < 56 {
        // Padding fits in this block
        block[56..64].copy_from_slice(&bit_len.to_be_bytes());
        compress(&mut state, &block);
    } else {
        // Need an extra block
        compress(&mut state, &block);
        let mut extra = [0u8; 64];
        extra[56..64].copy_from_slice(&bit_len.to_be_bytes());
        compress(&mut state, &extra);
    }

    let mut out = [0u8; 32];
    for (i, &word) in state.iter().enumerate() {
        out[i*4..i*4+4].copy_from_slice(&word.to_be_bytes());
    }
    out
}


1	//! Hierarchical consent delegation — bare-metal runtime.
2	//!
3	//! Mirrors the Verus exec functions from cubie_consent_hierarchy_spec.rs.
4	//! All functions are pure (no MMIO, no alloc) and compile to ~200 bytes
5	//! of machine code on RISC-V.
6	//!
7	//! Patent alignment: US20240195628A1 (hierarchical trust objects)
8	//! Formally verified by: verus/cubie_consent_hierarchy_spec.rs
9
10	/// Maximum depth in the consent hierarchy.
11	pub const MAX_CONSENT_DEPTH: u8 = 8;
12
13	/// A node in the hierarchical consent tree.
14	#[repr(C)]
15	pub struct ConsentNode {
16	    pub node_id:       u64,
17	    pub parent_id:     u64,   // 0 = root (trust anchor)
18	    pub depth:         u8,
19	    pub consent_grant: bool,
20	    pub sub_policy:    u64,
21	    pub capacity:      u64,
22	    pub active:        bool,
23	}
24
25	/// A consent channel between parent and child nodes.
26	#[repr(C)]
27	pub struct ConsentChannel {
28	    pub src_id:    u64,
29	    pub dst_id:    u64,
30	    pub bandwidth: u64,
31	    pub ch_open:   bool,
32	}
33
34	/// Enforcement contract (stabilizer code).
35	#[repr(C)]
36	pub struct StabilizerCode {
37	    pub code_distance:  u64,
38	    pub num_checks:     u64,
39	    pub syndrome_valid: bool,
40	}
41
42	/// Cascading consent: parent must be active+granted, child must be active+granted.
43	#[inline]
44	pub fn cascading_consent(parent: &ConsentNode, child: &ConsentNode) -> bool {
45	    parent.consent_grant && child.consent_grant && parent.active && child.active
46	}
47
48	/// Sub-policy bounded by parent capacity.
49	#[inline]
50	pub fn sub_policy_compliant(parent: &ConsentNode, child: &ConsentNode) -> bool {
51	    child.sub_policy <= parent.capacity
52	}
53
54	/// Stabilizer (enforcement contract) valid: syndrome passes and distance > 0.
55	#[inline]
56	pub fn stabilizer_ok(sc: &StabilizerCode) -> bool {
57	    sc.syndrome_valid && sc.code_distance > 0
58	}
59
60	/// Full consent admission: cascading + sub-policy + stabilizer.
61	#[inline]
62	pub fn full_consent_ok(
63	    parent: &ConsentNode,
64	    child: &ConsentNode,
65	    sc: &StabilizerCode,
66	) -> bool {
67	    cascading_consent(parent, child)
68	        && sub_policy_compliant(parent, child)
69	        && stabilizer_ok(sc)
70	}
71
72	/// Channel validity: both endpoints active, IDs match, channel open.
73	#[inline]
74	pub fn channel_valid(
75	    ch: &ConsentChannel,
76	    src: &ConsentNode,
77	    dst: &ConsentNode,
78	) -> bool {
79	    ch.ch_open
80	        && src.active
81	        && dst.active
82	        && src.node_id == ch.src_id
83	        && dst.node_id == ch.dst_id
84	}
85
86	/// Child can access parent through a valid channel with cascading consent.
87	#[inline]
88	pub fn child_can_access_parent(
89	    ch: &ConsentChannel,
90	    parent: &ConsentNode,
91	    child: &ConsentNode,
92	) -> bool {
93	    channel_valid(ch, parent, child) && cascading_consent(parent, child)
94	}
95
96	/// Percolation: data flows only when bandwidth >= threshold and channel open.
97	#[inline]
98	pub fn percolates(ch: &ConsentChannel, threshold: u64) -> bool {
99	    threshold <= ch.bandwidth && ch.ch_open
100	}
101
102	/// Capacity available: current children count < node's capacity.
103	#[inline]
104	pub fn capacity_available(node: &ConsentNode, current_children: u64) -> bool {
105	    current_children < node.capacity
106	}
107
108	/// Preference modification: node active and requestor at/above node depth.
109	#[inline]
110	pub fn can_modify_preferences(requestor: &ConsentNode, node: &ConsentNode) -> bool {
111	    node.active && requestor.depth <= node.depth
112	}
113
114	/// Effective sub-policy: min of child's sub-policy and parent's capacity.
115	#[inline]
116	pub fn effective_sub_policy(parent: &ConsentNode, child: &ConsentNode) -> u64 {
117	    if child.sub_policy <= parent.capacity {
118	        child.sub_policy
119	    } else {
120	        parent.capacity
121	    }
122	}
123

//! Hierarchical consent delegation — bare-metal runtime.
//!
//! Mirrors the Verus exec functions from cubie_consent_hierarchy_spec.rs.
//! All functions are pure (no MMIO, no alloc) and compile to ~200 bytes
//! of machine code on RISC-V.
//!
//! Patent alignment: US20240195628A1 (hierarchical trust objects)
//! Formally verified by: verus/cubie_consent_hierarchy_spec.rs

/// Maximum depth in the consent hierarchy.
pub const MAX_CONSENT_DEPTH: u8 = 8;

/// A node in the hierarchical consent tree.
#[repr(C)]
pub struct ConsentNode {
    pub node_id:       u64,
    pub parent_id:     u64,   // 0 = root (trust anchor)
    pub depth:         u8,
    pub consent_grant: bool,
    pub sub_policy:    u64,
    pub capacity:      u64,
    pub active:        bool,
}

/// A consent channel between parent and child nodes.
#[repr(C)]
pub struct ConsentChannel {
    pub src_id:    u64,
    pub dst_id:    u64,
    pub bandwidth: u64,
    pub ch_open:   bool,
}

/// Enforcement contract (stabilizer code).
#[repr(C)]
pub struct StabilizerCode {
    pub code_distance:  u64,
    pub num_checks:     u64,
    pub syndrome_valid: bool,
}

/// Cascading consent: parent must be active+granted, child must be active+granted.
#[inline]
pub fn cascading_consent(parent: &ConsentNode, child: &ConsentNode) -> bool {
    parent.consent_grant && child.consent_grant && parent.active && child.active
}

/// Sub-policy bounded by parent capacity.
#[inline]
pub fn sub_policy_compliant(parent: &ConsentNode, child: &ConsentNode) -> bool {
    child.sub_policy <= parent.capacity
}

/// Stabilizer (enforcement contract) valid: syndrome passes and distance > 0.
#[inline]
pub fn stabilizer_ok(sc: &StabilizerCode) -> bool {
    sc.syndrome_valid && sc.code_distance > 0
}

/// Full consent admission: cascading + sub-policy + stabilizer.
#[inline]
pub fn full_consent_ok(
    parent: &ConsentNode,
    child: &ConsentNode,
    sc: &StabilizerCode,
) -> bool {
    cascading_consent(parent, child)
        && sub_policy_compliant(parent, child)
        && stabilizer_ok(sc)
}

/// Channel validity: both endpoints active, IDs match, channel open.
#[inline]
pub fn channel_valid(
    ch: &ConsentChannel,
    src: &ConsentNode,
    dst: &ConsentNode,
) -> bool {
    ch.ch_open
        && src.active
        && dst.active
        && src.node_id == ch.src_id
        && dst.node_id == ch.dst_id
}

/// Child can access parent through a valid channel with cascading consent.
#[inline]
pub fn child_can_access_parent(
    ch: &ConsentChannel,
    parent: &ConsentNode,
    child: &ConsentNode,
) -> bool {
    channel_valid(ch, parent, child) && cascading_consent(parent, child)
}

/// Percolation: data flows only when bandwidth >= threshold and channel open.
#[inline]
pub fn percolates(ch: &ConsentChannel, threshold: u64) -> bool {
    threshold <= ch.bandwidth && ch.ch_open
}

/// Capacity available: current children count < node's capacity.
#[inline]
pub fn capacity_available(node: &ConsentNode, current_children: u64) -> bool {
    current_children < node.capacity
}

/// Preference modification: node active and requestor at/above node depth.
#[inline]
pub fn can_modify_preferences(requestor: &ConsentNode, node: &ConsentNode) -> bool {
    node.active && requestor.depth <= node.depth
}

/// Effective sub-policy: min of child's sub-policy and parent's capacity.
#[inline]
pub fn effective_sub_policy(parent: &ConsentNode, child: &ConsentNode) -> u64 {
    if child.sub_policy <= parent.capacity {
        child.sub_policy
    } else {
        parent.capacity
    }
}


1	//! Dual-ledger non-disclosure — bare-metal runtime.
2	//!
3	//! Mirrors the Coq/Lean proofs from CubieDualLedger.v / CubieDualLedger.lean.
4	//! All functions are pure (no MMIO, no alloc).
5	//!
6	//! Public ledger  = admission rules, capability grants (no PII)
7	//! Private ledger = execution data, access events, consent records
8	//! Anonymous ID   = links them without identity disclosure
9	//!
10	//! Patent alignment: US11956363B2 (dual-ledger identity verification)
11	//! Formally verified by: coq/CubieDualLedger.v, lean/CubieDualLedger.lean
12
13	/// Anonymous unique identifier linking public/private ledger entries.
14	#[repr(C)]
15	pub struct AnonID {
16	    pub anon_hash: u64,
17	    pub epoch:     u64,
18	}
19
20	/// Public ledger entry: admission rules and policies (no entity data).
21	#[repr(C)]
22	pub struct PublicEntry {
23	    pub pub_anon_id:       AnonID,
24	    pub pub_policy_hash:   u64,
25	    pub pub_capability:    bool,
26	    pub pub_policy_filter: bool,
27	}
28
29	/// Private ledger entry: execution data + consent events.
30	#[repr(C)]
31	pub struct PrivateEntry {
32	    pub priv_anon_id:       AnonID,
33	    pub priv_real_id_hash:  u64,
34	    pub priv_consent_grant: bool,
35	    pub priv_interaction:   u64,
36	}
37
38	/// The dual-ledger system.
39	#[repr(C)]
40	pub struct DualLedger {
41	    pub public_entry:  PublicEntry,
42	    pub private_entry: PrivateEntry,
43	}
44
45	/// Anonymous ID linkage: public and private share the same anon ID.
46	#[inline]
47	pub fn anon_id_linked(dl: &DualLedger) -> bool {
48	    dl.public_entry.pub_anon_id.anon_hash == dl.private_entry.priv_anon_id.anon_hash
49	        && dl.public_entry.pub_anon_id.epoch == dl.private_entry.priv_anon_id.epoch
50	}
51
52	/// Non-disclosure: public entry does NOT leak real identity.
53	#[inline]
54	pub fn public_hides_identity(dl: &DualLedger) -> bool {
55	    dl.public_entry.pub_policy_hash != dl.private_entry.priv_real_id_hash
56	}
57
58	/// Consent valid: entity granted consent AND holds capability.
59	#[inline]
60	pub fn consent_valid(dl: &DualLedger) -> bool {
61	    dl.private_entry.priv_consent_grant && dl.public_entry.pub_capability
62	}
63
64	/// Policy filter active: workload admission filter is enforcing.
65	#[inline]
66	pub fn policy_filter_active(dl: &DualLedger) -> bool {
67	    dl.public_entry.pub_policy_filter
68	}
69
70	/// Full dual-ledger admission: linked + non-disclosing + consent valid.
71	#[inline]
72	pub fn dual_ledger_ok(dl: &DualLedger) -> bool {
73	    anon_id_linked(dl) && public_hides_identity(dl) && consent_valid(dl)
74	}
75

//! Dual-ledger non-disclosure — bare-metal runtime.
//!
//! Mirrors the Coq/Lean proofs from CubieDualLedger.v / CubieDualLedger.lean.
//! All functions are pure (no MMIO, no alloc).
//!
//! Public ledger  = admission rules, capability grants (no PII)
//! Private ledger = execution data, access events, consent records
//! Anonymous ID   = links them without identity disclosure
//!
//! Patent alignment: US11956363B2 (dual-ledger identity verification)
//! Formally verified by: coq/CubieDualLedger.v, lean/CubieDualLedger.lean

/// Anonymous unique identifier linking public/private ledger entries.
#[repr(C)]
pub struct AnonID {
    pub anon_hash: u64,
    pub epoch:     u64,
}

/// Public ledger entry: admission rules and policies (no entity data).
#[repr(C)]
pub struct PublicEntry {
    pub pub_anon_id:       AnonID,
    pub pub_policy_hash:   u64,
    pub pub_capability:    bool,
    pub pub_policy_filter: bool,
}

/// Private ledger entry: execution data + consent events.
#[repr(C)]
pub struct PrivateEntry {
    pub priv_anon_id:       AnonID,
    pub priv_real_id_hash:  u64,
    pub priv_consent_grant: bool,
    pub priv_interaction:   u64,
}

/// The dual-ledger system.
#[repr(C)]
pub struct DualLedger {
    pub public_entry:  PublicEntry,
    pub private_entry: PrivateEntry,
}

/// Anonymous ID linkage: public and private share the same anon ID.
#[inline]
pub fn anon_id_linked(dl: &DualLedger) -> bool {
    dl.public_entry.pub_anon_id.anon_hash == dl.private_entry.priv_anon_id.anon_hash
        && dl.public_entry.pub_anon_id.epoch == dl.private_entry.priv_anon_id.epoch
}

/// Non-disclosure: public entry does NOT leak real identity.
#[inline]
pub fn public_hides_identity(dl: &DualLedger) -> bool {
    dl.public_entry.pub_policy_hash != dl.private_entry.priv_real_id_hash
}

/// Consent valid: entity granted consent AND holds capability.
#[inline]
pub fn consent_valid(dl: &DualLedger) -> bool {
    dl.private_entry.priv_consent_grant && dl.public_entry.pub_capability
}

/// Policy filter active: workload admission filter is enforcing.
#[inline]
pub fn policy_filter_active(dl: &DualLedger) -> bool {
    dl.public_entry.pub_policy_filter
}

/// Full dual-ledger admission: linked + non-disclosing + consent valid.
#[inline]
pub fn dual_ledger_ok(dl: &DualLedger) -> bool {
    anon_id_linked(dl) && public_hides_identity(dl) && consent_valid(dl)
}


1	//! HMAC-SHA256 capability verifier — hardware-backed implementation.
2	//!
3	//! Replaces the previous all-deny stub.  Key material is read from
4	//! eFuse MMIO registers at the slot index carried in CubieRequest.key_slot.
5	//!
6	//! Verification steps:
7	//!   1. Read 32-byte symmetric key from eFuse slot `key_slot`  (MMIO)
8	//!   2. Compute HMAC-SHA256(key, request_hash.to_be_bytes())
9	//!   3. Compare first 8 bytes of HMAC with capability_hmac (big-endian u64)
10	//!   4. Return true iff they match (constant-time comparison)
11	//!
12	//! Key derivation: each eFuse slot holds an independent 256-bit key.
13	//! Slot 0 is reserved for the platform root key.
14	//! Slots 1–7 are capability-tier keys (provisioned at manufacturing).
15
16	use crate::hmac::{hmac_sha256, ct_eq_32};
17	use crate::mmio;
18
19	/// Verify a capability HMAC against a hardware eFuse key.
20	///
21	/// # Arguments
22	/// * `request_hash`   — 64-bit hash of the CubieRequest content fields
23	/// * `capability_hmac`— first 8 bytes of the expected HMAC (big-endian u64)
24	/// * `key_slot`       — eFuse key slot index (0–7; 0 = platform root)
25	///
26	/// # Returns
27	/// `true`  — HMAC verified: capability is authentic.
28	/// `false` — HMAC mismatch or key unreadable: deny.
29	///
30	/// # Safety
31	/// Reads from eFuse MMIO registers.  The firmware must map the eFuse
32	/// region before calling `cubie_admit`.
33	pub fn capability_hmac_verify(
34	    request_hash:    u64,
35	    capability_hmac: u64,
36	    key_slot:        u8,
37	) -> bool {
38	    // Step 1: Read key material from eFuse hardware.
39	    // SAFETY: key_slot is carried in the request; out-of-range slots read
40	    // from unmapped memory and will fault — the firmware is responsible for
41	    // providing a valid slot (0–7).
42	    let key = unsafe { mmio::read_efuse_key(key_slot) };
43
44	    // Step 2: Compute HMAC-SHA256(key, request_hash as 8 big-endian bytes).
45	    let msg = request_hash.to_be_bytes();
46	    let mac = hmac_sha256(&key, &msg);
47
48	    // Step 3: Build expected 32-byte comparison buffer.
49	    // Upper 8 bytes match capability_hmac; remaining bytes must be zero
50	    // (truncated MAC comparison — only the first 8 bytes are transmitted).
51	    let mut expected = [0u8; 32];
52	    expected[0..8].copy_from_slice(&capability_hmac.to_be_bytes());
53
54	    // Step 4: Constant-time compare to prevent timing oracle.
55	    // We compare the full 32 bytes: mac[0..8] vs capability_hmac bytes,
56	    // mac[8..32] vs zeros.  Both sides are included in ct_eq_32.
57	    let mut mac_truncated = [0u8; 32];
58	    mac_truncated[0..8].copy_from_slice(&mac[0..8]);
59
60	    ct_eq_32(&mac_truncated, &expected)
61	}
62

//! HMAC-SHA256 capability verifier — hardware-backed implementation.
//!
//! Replaces the previous all-deny stub.  Key material is read from
//! eFuse MMIO registers at the slot index carried in CubieRequest.key_slot.
//!
//! Verification steps:
//!   1. Read 32-byte symmetric key from eFuse slot `key_slot`  (MMIO)
//!   2. Compute HMAC-SHA256(key, request_hash.to_be_bytes())
//!   3. Compare first 8 bytes of HMAC with capability_hmac (big-endian u64)
//!   4. Return true iff they match (constant-time comparison)
//!
//! Key derivation: each eFuse slot holds an independent 256-bit key.
//! Slot 0 is reserved for the platform root key.
//! Slots 1–7 are capability-tier keys (provisioned at manufacturing).

use crate::hmac::{hmac_sha256, ct_eq_32};
use crate::mmio;

/// Verify a capability HMAC against a hardware eFuse key.
///
/// # Arguments
/// * `request_hash`   — 64-bit hash of the CubieRequest content fields
/// * `capability_hmac`— first 8 bytes of the expected HMAC (big-endian u64)
/// * `key_slot`       — eFuse key slot index (0–7; 0 = platform root)
///
/// # Returns
/// `true`  — HMAC verified: capability is authentic.
/// `false` — HMAC mismatch or key unreadable: deny.
///
/// # Safety
/// Reads from eFuse MMIO registers.  The firmware must map the eFuse
/// region before calling `cubie_admit`.
pub fn capability_hmac_verify(
    request_hash:    u64,
    capability_hmac: u64,
    key_slot:        u8,
) -> bool {
    // Step 1: Read key material from eFuse hardware.
    // SAFETY: key_slot is carried in the request; out-of-range slots read
    // from unmapped memory and will fault — the firmware is responsible for
    // providing a valid slot (0–7).
    let key = unsafe { mmio::read_efuse_key(key_slot) };

    // Step 2: Compute HMAC-SHA256(key, request_hash as 8 big-endian bytes).
    let msg = request_hash.to_be_bytes();
    let mac = hmac_sha256(&key, &msg);

    // Step 3: Build expected 32-byte comparison buffer.
    // Upper 8 bytes match capability_hmac; remaining bytes must be zero
    // (truncated MAC comparison — only the first 8 bytes are transmitted).
    let mut expected = [0u8; 32];
    expected[0..8].copy_from_slice(&capability_hmac.to_be_bytes());

    // Step 4: Constant-time compare to prevent timing oracle.
    // We compare the full 32 bytes: mac[0..8] vs capability_hmac bytes,
    // mac[8..32] vs zeros.  Both sides are included in ct_eq_32.
    let mut mac_truncated = [0u8; 32];
    mac_truncated[0..8].copy_from_slice(&mac[0..8]);

    ct_eq_32(&mac_truncated, &expected)
}


1	//! NVLink waiter-signature detection for bare-metal admission gate.
2	//!
3	//! Waiter signature per whitepaper v2.5 §7.2:
4	//!   zero SM activity  AND  non-zero allocated VRAM on a TP peer
5	//!   → peer is a deadlocked NVLink waiter → unsafe to admit
6	//!
7	//! Returns true  (SAFE)  when the signature is ABSENT.
8	//! Returns false (DENY)  when SM idle + VRAM held = waiter detected.
9
10	use crate::mmio;
11
12	/// Check whether the NVLink peer `peer_id` is safe (no waiter signature).
13	///
14	/// Reads two MMIO telemetry registers:
15	///   - SM_ACTIVITY : running SM warp count (0 = peer is idle)
16	///   - VRAM_ALLOC  : allocated VRAM in MiB (non-zero = memory is pinned)
17	///
18	/// The NVLink waiter signature is: `sm_activity == 0 && vram_alloc > 0`.
19	/// If that condition holds, the peer is holding VRAM while doing no work —
20	/// the classic NVLink deadlock footprint.  We deny admission.
21	///
22	/// # Safety
23	/// Reads from MMIO registers. `peer_id` must map to a valid NVLink
24	/// peer on this platform (see mmio.rs for register addresses).
25	pub fn nvlink_waiter_safe(peer_id: u8) -> bool {
26	    // SAFETY: peer_id is passed directly from CubieRequest.peer_id;
27	    // firmware callers are responsible for providing a valid peer index.
28	    let (sm, vram) = unsafe {
29	        (
30	            mmio::read_nvlink_sm_activity(peer_id),
31	            mmio::read_nvlink_vram_alloc(peer_id),
32	        )
33	    };
34
35	    // Waiter signature: idle SM + held VRAM
36	    let waiter_detected = sm == 0 && vram > 0;
37	    !waiter_detected
38	}
39

//! NVLink waiter-signature detection for bare-metal admission gate.
//!
//! Waiter signature per whitepaper v2.5 §7.2:
//!   zero SM activity  AND  non-zero allocated VRAM on a TP peer
//!   → peer is a deadlocked NVLink waiter → unsafe to admit
//!
//! Returns true  (SAFE)  when the signature is ABSENT.
//! Returns false (DENY)  when SM idle + VRAM held = waiter detected.

use crate::mmio;

/// Check whether the NVLink peer `peer_id` is safe (no waiter signature).
///
/// Reads two MMIO telemetry registers:
///   - SM_ACTIVITY : running SM warp count (0 = peer is idle)
///   - VRAM_ALLOC  : allocated VRAM in MiB (non-zero = memory is pinned)
///
/// The NVLink waiter signature is: `sm_activity == 0 && vram_alloc > 0`.
/// If that condition holds, the peer is holding VRAM while doing no work —
/// the classic NVLink deadlock footprint.  We deny admission.
///
/// # Safety
/// Reads from MMIO registers. `peer_id` must map to a valid NVLink
/// peer on this platform (see mmio.rs for register addresses).
pub fn nvlink_waiter_safe(peer_id: u8) -> bool {
    // SAFETY: peer_id is passed directly from CubieRequest.peer_id;
    // firmware callers are responsible for providing a valid peer index.
    let (sm, vram) = unsafe {
        (
            mmio::read_nvlink_sm_activity(peer_id),
            mmio::read_nvlink_vram_alloc(peer_id),
        )
    };

    // Waiter signature: idle SM + held VRAM
    let waiter_detected = sm == 0 && vram > 0;
    !waiter_detected
}


1	//! PCIe adapter-swap gate for bare-metal admission.
2	//!
3	//! Decision logic (whitepaper v2.5 §7.2 adapter_swap_ok):
4	//!   1. If adapter_id is in the resident cache  → no swap needed → ALLOW
5	//!   2. If adapter_id NOT in cache:
6	//!      a. Read upstream PCIe bandwidth from MMIO
7	//!      b. If bandwidth ≥ BW_THRESHOLD_MBS      → swap feasible  → ALLOW
8	//!      c. Otherwise                             → swap stalls bus → DENY
9	//!
10	//! Cache is a fixed-size ring of 16 u64 adapter IDs stored in BSS.
11	//! No heap, no alloc, no OS.
12
13	use crate::mmio;
14
15	/// Minimum upstream PCIe bandwidth (MB/s) required to permit an adapter swap.
16	/// Below this threshold the fabric is congested and the swap would stall.
17	const BW_THRESHOLD_MBS: u32 = 4096; // 4 GB/s
18
19	/// Number of adapter IDs the resident cache can hold simultaneously.
20	const CACHE_SIZE: usize = 16;
21
22	/// Sentinel meaning "slot is empty".
23	const EMPTY: u64 = 0;
24
25	/// Fixed-size adapter-ID cache (zero-initialized at boot).
26	///
27	/// Entries are 64-bit adapter IDs written by admit calls.
28	/// Eviction policy: first empty slot; if full, slot 0 is overwritten (FIFO).
29	///
30	/// # Safety
31	/// Single-threaded bare-metal — no concurrent mutation possible.
32	static mut ADAPTER_CACHE: [u64; CACHE_SIZE] = [EMPTY; CACHE_SIZE];
33
34	/// Returns true if `id` is currently in the adapter cache.
35	fn cache_contains(id: u64) -> bool {
36	    // SAFETY: single-threaded bare-metal; read-only scan via raw pointer.
37	    unsafe {
38	        let base = core::ptr::addr_of!(ADAPTER_CACHE) as *const u64;
39	        for i in 0..CACHE_SIZE {
40	            if core::ptr::read_volatile(base.add(i)) == id {
41	                return true;
42	            }
43	        }
44	        false
45	    }
46	}
47
48	/// Insert `id` into the cache.  Fills the first empty slot;
49	/// if no empty slot, overwrites slot 0 (simple FIFO eviction).
50	fn cache_insert(id: u64) {
51	    // SAFETY: single-threaded bare-metal; mutations via raw pointer.
52	    unsafe {
53	        let base = core::ptr::addr_of_mut!(ADAPTER_CACHE) as *mut u64;
54	        for i in 0..CACHE_SIZE {
55	            if core::ptr::read_volatile(base.add(i)) == EMPTY {
56	                core::ptr::write_volatile(base.add(i), id);
57	                return;
58	            }
59	        }
60	        // Cache full — evict slot 0
61	        core::ptr::write_volatile(base, id);
62	    }
63	}
64
65	/// Check whether the adapter identified by `adapter_id` can be swapped in.
66	///
67	/// Returns `true`  (ALLOW) when:
68	///   - The adapter is already resident in the gate cache, OR
69	///   - Upstream PCIe bandwidth is ≥ BW_THRESHOLD_MBS (4 GB/s).
70	///
71	/// Returns `false` (DENY) when the adapter is not cached and the PCIe
72	/// fabric is congested.
73	///
74	/// Side effect: on ALLOW from a cache-miss path, `adapter_id` is added
75	/// to the cache so subsequent requests are served without MMIO reads.
76	///
77	/// # Safety
78	/// Reads from PCIe bandwidth MMIO register (see mmio.rs).
79	pub fn adapter_swap_ok(adapter_id: u64) -> bool {
80	    if adapter_id == EMPTY {
81	        // Sentinel value 0 is reserved — treat as unknown/deny.
82	        return false;
83	    }
84
85	    if cache_contains(adapter_id) {
86	        return true;
87	    }
88
89	    // Cache miss: consult PCIe bandwidth register.
90	    // SAFETY: PCIe MMIO region assumed mapped by firmware before calling.
91	    let bw = unsafe { mmio::read_pcie_bw_mbs() };
92	    if bw >= BW_THRESHOLD_MBS {
93	        cache_insert(adapter_id);
94	        true
95	    } else {
96	        false
97	    }
98	}
99
100	/// Reset the adapter cache to empty.
101	/// Only available under the `mock` feature — used by tests to prevent
102	/// cache state from leaking between test cases.
103	#[cfg(feature = "mock")]
104	pub fn clear_adapter_cache() {
105	    unsafe {
106	        let base = core::ptr::addr_of_mut!(ADAPTER_CACHE) as *mut u64;
107	        for i in 0..CACHE_SIZE {
108	            core::ptr::write_volatile(base.add(i), EMPTY);
109	        }
110	    }
111	}
112

//! PCIe adapter-swap gate for bare-metal admission.
//!
//! Decision logic (whitepaper v2.5 §7.2 adapter_swap_ok):
//!   1. If adapter_id is in the resident cache  → no swap needed → ALLOW
//!   2. If adapter_id NOT in cache:
//!      a. Read upstream PCIe bandwidth from MMIO
//!      b. If bandwidth ≥ BW_THRESHOLD_MBS      → swap feasible  → ALLOW
//!      c. Otherwise                             → swap stalls bus → DENY
//!
//! Cache is a fixed-size ring of 16 u64 adapter IDs stored in BSS.
//! No heap, no alloc, no OS.

use crate::mmio;

/// Minimum upstream PCIe bandwidth (MB/s) required to permit an adapter swap.
/// Below this threshold the fabric is congested and the swap would stall.
const BW_THRESHOLD_MBS: u32 = 4096; // 4 GB/s

/// Number of adapter IDs the resident cache can hold simultaneously.
const CACHE_SIZE: usize = 16;

/// Sentinel meaning "slot is empty".
const EMPTY: u64 = 0;

/// Fixed-size adapter-ID cache (zero-initialized at boot).
///
/// Entries are 64-bit adapter IDs written by admit calls.
/// Eviction policy: first empty slot; if full, slot 0 is overwritten (FIFO).
///
/// # Safety
/// Single-threaded bare-metal — no concurrent mutation possible.
static mut ADAPTER_CACHE: [u64; CACHE_SIZE] = [EMPTY; CACHE_SIZE];

/// Returns true if `id` is currently in the adapter cache.
fn cache_contains(id: u64) -> bool {
    // SAFETY: single-threaded bare-metal; read-only scan via raw pointer.
    unsafe {
        let base = core::ptr::addr_of!(ADAPTER_CACHE) as *const u64;
        for i in 0..CACHE_SIZE {
            if core::ptr::read_volatile(base.add(i)) == id {
                return true;
            }
        }
        false
    }
}

/// Insert `id` into the cache.  Fills the first empty slot;
/// if no empty slot, overwrites slot 0 (simple FIFO eviction).
fn cache_insert(id: u64) {
    // SAFETY: single-threaded bare-metal; mutations via raw pointer.
    unsafe {
        let base = core::ptr::addr_of_mut!(ADAPTER_CACHE) as *mut u64;
        for i in 0..CACHE_SIZE {
            if core::ptr::read_volatile(base.add(i)) == EMPTY {
                core::ptr::write_volatile(base.add(i), id);
                return;
            }
        }
        // Cache full — evict slot 0
        core::ptr::write_volatile(base, id);
    }
}

/// Check whether the adapter identified by `adapter_id` can be swapped in.
///
/// Returns `true`  (ALLOW) when:
///   - The adapter is already resident in the gate cache, OR
///   - Upstream PCIe bandwidth is ≥ BW_THRESHOLD_MBS (4 GB/s).
///
/// Returns `false` (DENY) when the adapter is not cached and the PCIe
/// fabric is congested.
///
/// Side effect: on ALLOW from a cache-miss path, `adapter_id` is added
/// to the cache so subsequent requests are served without MMIO reads.
///
/// # Safety
/// Reads from PCIe bandwidth MMIO register (see mmio.rs).
pub fn adapter_swap_ok(adapter_id: u64) -> bool {
    if adapter_id == EMPTY {
        // Sentinel value 0 is reserved — treat as unknown/deny.
        return false;
    }

    if cache_contains(adapter_id) {
        return true;
    }

    // Cache miss: consult PCIe bandwidth register.
    // SAFETY: PCIe MMIO region assumed mapped by firmware before calling.
    let bw = unsafe { mmio::read_pcie_bw_mbs() };
    if bw >= BW_THRESHOLD_MBS {
        cache_insert(adapter_id);
        true
    } else {
        false
    }
}

/// Reset the adapter cache to empty.
/// Only available under the `mock` feature — used by tests to prevent
/// cache state from leaking between test cases.
#[cfg(feature = "mock")]
pub fn clear_adapter_cache() {
    unsafe {
        let base = core::ptr::addr_of_mut!(ADAPTER_CACHE) as *mut u64;
        for i in 0..CACHE_SIZE {
            core::ptr::write_volatile(base.add(i), EMPTY);
        }
    }
}


Now let me read the Coq and Lean proofs, the Verus spec, and the existing tests to complete the picture.