open-standards/wai/wai-web/src/quantum_ops.rs
Transaction Science d009db9087
Some checks failed
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m48s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m17s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m16s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m7s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 2m29s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 22s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 2m7s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 22s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 42s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 39s
wai formal verification (integer core) / kani (pull_request) Successful in 4m59s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 52s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Failing after 1m7s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 6m49s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 24s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 2m28s
standards workspaces build + test / aac-rs (pull_request) Successful in 3m25s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 3m46s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m22s
standards workspaces build + test / map-rs (pull_request) Successful in 2m16s
standards workspaces build + test / mesh-rs (pull_request) Successful in 2m3s
standards workspaces build + test / openpay (pull_request) Successful in 18m29s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 1m58s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Failing after 7s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Failing after 7s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Failing after 8s
standards workspaces build + test / arl-rs (pull_request) Successful in 3m49s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 3m19s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 3m45s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 3m17s
standards workspaces build + test / sense-rs (pull_request) Successful in 4m0s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 3m42s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 27s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 2m43s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 28s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 1m14s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · windows (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · windows (pull_request) Has been cancelled
wai: on-chip counters and calibrated instruments are separate energy classes, and every joule-carrying receipt can say which
The single `HwShunt` acquisition class covered both an on-chip vendor
counter (RAPL, NVML, SMC, IOReport) and an external calibrated shunt. They
are different evidence: a calibrated instrument's uncertainty is traceable to
a calibration, while a counter is a vendor's reading whose error the vendor
states (RAPL readings are deliberately noised when SGX or TDX is enabled,
per security advisory INTEL-SA-00389).

- extensions/energy-measurement.md §2 splits hardware evidence into
  `OnChipCounter` and `CalibratedInstrument`, each with a required declared
  uncertainty (relative error and integration window). IOReport is an
  on-chip counter, like RAPL and NVML. `HwShunt` stays readable as the legacy
  class, ranked below both, and is not sealed into a new WAI receipt.
- Every receipt family that carries joules — video, world, film, reel,
  haptic, score, splat4d, audio scene, ternary, provenance and the wai-quantum
  receipts — can carry its class. The label is additive: every committed
  signed vector still verifies, and the signed bytes of unlabelled and
  legacy-labelled receipts are pinned by tests. A sealed figure declares its
  1 µJ resolution, and the floor is stated as the rule verified (0.5/√3 µJ).
- The acquisition rules are scoped to the receipt profiles WAI defines, and
  the text says what enforces each one.
- Meters open their window from rest, report an all-zero power reader as
  unusable rather than clean, and state the running-window count model as
  conservative.
- oer-receipts.md maps OER's evidential grade onto the refined classes. The
  rule that a producer must not grade `measured` a figure whose class is
  `Estimator` is kept as settled on main.
- wai-quantum verifies a receipt in either form on every in-tree verify
  path, including wai-quantum-serve's POST /verify.
- CI: wai-energy-receipts.yml runs the energy-class, label and legacy-pin
  tests for wai-rs, wai-quantum and wai-quantum-serve, which no workflow
  enabled before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 01:27:37 -04:00

178 lines
5.6 KiB
Rust

//! Quantum-operations ATTESTATION in the browser (`wai.quantum.calibration` /
//! `wai.quantum.job`). The SAME `wai::quantum_ops` receipts native tools produce,
//! compiled to wasm32 — so the page can seal a signed, joule-metered, grant-
//! authorized receipt, then demonstrate gate ⊗ meter ⊗ receipt live:
//! tamper a field → `verify()` fails; blow the joule budget → `verify()` fails;
//! bind a job to (or mismatch it against) a calibration state. No hardware; WAI
//! owns the receipt.
use ed25519_dalek::SigningKey;
use wai::quantum_energy::MaybeLabelled;
use wai::quantum_ops::{content_hash, CalibrationReceipt, Evidence, GrantRef, JobReceipt};
use wasm_bindgen::prelude::*;
fn hex(b: &[u8]) -> String {
b.iter().map(|x| format!("{x:02x}")).collect()
}
fn from_hex32(s: &str) -> Option<[u8; 32]> {
if s.len() != 64 || !s.bytes().all(|b| b.is_ascii_hexdigit()) {
return None;
}
let mut out = [0u8; 32];
for (i, c) in s.as_bytes().chunks(2).enumerate() {
out[i] = u8::from_str_radix(std::str::from_utf8(c).ok()?, 16).ok()?;
}
Some(out)
}
/// A deterministic demo signing key (the sink would use its own identity key).
fn key(seed: u8) -> SigningKey {
SigningKey::from_bytes(&[seed; 32])
}
fn grant(capability: &str, joule_ceiling: u64) -> GrantRef {
GrantRef {
grant_hash: content_hash(capability.as_bytes()),
capability: capability.to_string(),
joule_ceiling_micro: joule_ceiling,
funds_ceiling: None,
}
}
#[wasm_bindgen]
pub struct QuantumCal {
inner: CalibrationReceipt,
}
#[wasm_bindgen]
impl QuantumCal {
/// Seal a calibration receipt. `config_bytes` and `evidence_bytes` are the raw
/// artifacts (content-addressed inside); `joule_ceiling` is the grant's budget.
#[allow(clippy::too_many_arguments)]
#[wasm_bindgen(constructor)]
pub fn new(
seed: u8,
device: &str,
target: &str,
config_bytes: &[u8],
evidence_kind: &str,
evidence_bytes: &[u8],
evidence_summary: &str,
joules_micro: u64,
capability: &str,
joule_ceiling: u64,
) -> QuantumCal {
let ev = vec![Evidence {
kind: evidence_kind.to_string(),
blob_hash: content_hash(evidence_bytes),
summary: evidence_summary.to_string(),
}];
let inner = CalibrationReceipt::seal(
&key(seed),
"did:key:demo-lab",
device,
target,
content_hash(config_bytes),
ev,
joules_micro,
grant(capability, joule_ceiling),
None,
);
QuantumCal { inner }
}
pub fn json(&self) -> String {
self.inner.to_json()
}
/// Cryptographically valid AND within the grant's joule budget.
pub fn verify(&self) -> bool {
self.inner.verify()
}
pub fn honors_budget(&self) -> bool {
self.inner.honors_budget()
}
pub fn joules_micro(&self) -> u64 {
self.inner.joules_micro
}
pub fn joule_ceiling(&self) -> u64 {
self.inner.grant.joule_ceiling_micro
}
pub fn receipt_hash_hex(&self) -> String {
hex(&self.inner.receipt_hash())
}
/// Tamper: overwrite the signed `joules_micro`. `verify()` now fails — the
/// signature no longer covers the mutated field.
pub fn tamper_joules(&mut self, j: u64) {
self.inner.joules_micro = j;
}
/// A fidelity claim binds to the exact dataset bytes that produced it.
pub fn evidence_matches(&self, bytes: &[u8]) -> bool {
self.inner.evidence_matches(0, bytes)
}
}
#[wasm_bindgen]
pub struct QuantumJob {
inner: JobReceipt,
}
#[wasm_bindgen]
impl QuantumJob {
/// Seal a job receipt. `cal_ref_hex` is the calibration receipt's hash (the
/// device state it ran under); pass `null`/undefined for a simulator run.
#[allow(clippy::too_many_arguments)]
#[wasm_bindgen(constructor)]
pub fn new(
seed: u8,
backend: &str,
circuit_bytes: &[u8],
result_bytes: &[u8],
cal_ref_hex: Option<String>,
shots: u64,
joules_micro: u64,
capability: &str,
joule_ceiling: u64,
) -> Result<QuantumJob, JsError> {
let cal_ref = match cal_ref_hex {
Some(h) if !h.is_empty() => {
Some(from_hex32(&h).ok_or_else(|| JsError::new("bad calibration_ref hex"))?)
}
_ => None,
};
let inner = JobReceipt::seal(
&key(seed),
"did:key:demo-lab",
backend,
content_hash(circuit_bytes),
content_hash(result_bytes),
cal_ref,
shots,
joules_micro,
grant(capability, joule_ceiling),
None,
);
Ok(QuantumJob { inner })
}
pub fn json(&self) -> String {
self.inner.to_json()
}
pub fn verify(&self) -> bool {
self.inner.verify()
}
pub fn receipt_hash_hex(&self) -> String {
hex(&self.inner.receipt_hash())
}
/// The cross-link: does this job bind to the given calibration state? Confirms
/// the job names that calibration's hash and both receipts verify. The
/// calibration may be in either form — as sealed, or with its joule figure's
/// acquisition class inside the signature — and is named by the identity of the
/// form it is in.
pub fn verify_against_calibration(&self, cal_json: &str) -> bool {
match MaybeLabelled::<CalibrationReceipt>::from_json(cal_json) {
Some(cal) => MaybeLabelled::Unlabelled(self.inner.clone()).verify_against_calibration(&cal),
None => false,
}
}
}