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
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]>
178 lines
5.6 KiB
Rust
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,
|
|
}
|
|
}
|
|
}
|