All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 29s
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 3m3s
standards workspaces build + test / jcp-rs (jcp-conformance, jcp/jcp-rs, -p jcp-energy --features nvml, jcp-rs, linux) (pull_request) Successful in 2m46s
standards workspaces build + test / joule-ui-rs (joule-ui/joule-ui-rs, joule-ui-rs, linux) (pull_request) Successful in 1m17s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 1m35s
standards workspaces build + test / proof-rs (proof-conformance, proof/proof-rs, proof-rs, linux, true) (pull_request) Successful in 1m39s
standards workspaces build + test / sandbox-rs (sandbox-conformance, sandbox/sandbox-rs, sandbox-rs, linux) (pull_request) Successful in 2m51s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 9m1s
standards workspaces build + test / jouleclaw-rs (-nodebug, jouleclaw/jouleclaw-rs, -p jouleclaw-energy --features rapl,nvml, jouleclaw-rs, linux-arm64, -C target-feature=+fp16) (pull_request) Successful in 6m29s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 2m39s
standards workspaces build + test / joulecontract-rs (joulecontract/joulecontract-rs, joulecontract-rs, linux-arm64, true) (pull_request) Successful in 1m33s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 2m3s
standards workspaces build + test / mesh-rs (mesh/mesh-rs, -p mesh-engine-gguf -p mesh-openai --features mesh-engine-gguf/gguf,mesh-openai/server, mesh-rs, linux-arm64) (pull_request) Successful in 1m26s
CI caught what the previous commit's verification could not: `jcp-efficiency`
is a **path dependency of three other workspaces**, and
`cargo test --workspace` inside `jcp/jcp-rs` never compiles them. The
jouledesk-rs, sandbox-rs and joulehook-rs legs all failed to build.
The consumers are:
jouledesk/.../jouledesk/Cargo.toml
jouledesk/.../jouledesk-livekit/Cargo.toml
jouledesk/.../jouledesk-github/Cargo.toml
sandbox/.../sandbox-tee/Cargo.toml
joulehook/.../joulehook-meter/Cargo.toml
Five call sites read a figure that is now an `Option`:
- `jouledesk/src/lib.rs` — the assertion that waste inflates
joules-per-completed-unit. Two units completed there, so the ratio is
defined; `.expect` now records that rather than hiding it.
- `jouledesk/examples/channel.rs`, `examples/room.rs` and
`sandbox-tee/examples/attested_efficiency.rs` — `println!` of the figure.
Each prints "—" when undefined, for the same reason `session.rs` does:
0 is the optimum of a cost-per-result figure, so printing it would name
the cheapest possible cost for work that delivered none.
- `joulehook-meter` — `assert_eq!` on a receipt field; 900 tokens were
accepted, so the figure is present and the assertion takes `Some`.
`Efficiency`'s own fields did not change, so the `Efficiency { .. }`
literals in all four consumers are untouched; only reads of
`EfficiencyReceipt::uj_per_accepted_token` and `Totals::uj_per_completed_unit`
needed work.
Verified by building and testing **each** of the four workspaces that
compile this crate — jcp-rs, jouledesk-rs, sandbox-rs, joulehook-rs — rather
than only the one holding the edit: `cargo check --workspace --all-targets`
and `cargo test --workspace` exit 0 in all four, with 0 failed suites.
Co-Authored-By: Claude Opus 5 <[email protected]>
220 lines
10 KiB
Rust
220 lines
10 KiB
Rust
//! End-to-end: a small task runs here, this host's meter reads its energy, the
|
|
//! figure is attested inside a TEE, committed into an `efficiency/1` receipt,
|
|
//! and then independently re-verified from scratch — deriving the trust level,
|
|
//! never asserting it. This is the whole frontier composed in one runnable flow.
|
|
//!
|
|
//! cargo run -p sandbox-tee --example attested_efficiency
|
|
//!
|
|
//! **What the figure is.** The task is a bounded SHA-512 chain on this thread,
|
|
//! metered by [`PowerMeter::detect_in_process`] (the work runs on this
|
|
//! process's own threads). The attested counter class and the receipt's grade
|
|
//! both follow how the figure was obtained:
|
|
//!
|
|
//! - where a vendor counter read this process's CPU work over the span (the
|
|
//! kernel's per-process count on macOS, a RAPL package on Linux, IOReport's
|
|
//! CPU rails on Apple Silicon where they are live), the statement names that
|
|
//! counter's class and the receipt seals the reading, `HwShunt`;
|
|
//! - where none did (no live counter, or one that did not advance over the
|
|
//! span), the figure is the meter's estimate: attested as
|
|
//! [`CounterClass::Estimator`] and sealed `Estimator`.
|
|
//!
|
|
//! Either way the derived trust level is `IntegrityAttested`: a software-grounded
|
|
//! report binds the figure, as it was obtained, to a measured environment. What
|
|
//! the figure itself is — a reading or an estimate — is the counter class the
|
|
//! report binds, printed beside it.
|
|
|
|
use ed25519_dalek::SigningKey;
|
|
use jcp_efficiency::{verify as verify_efficiency, Efficiency, EfficiencyReceipt};
|
|
use jcp_schema::{ContentId, Energy};
|
|
use sandbox_meter::{Measurement, PowerMeter, Provenance};
|
|
use sandbox_schema::DeviceClass;
|
|
use sandbox_tee::energy::{
|
|
attest_energy, verify_attested_energy, AttestTrust, AttestedEnergy, CounterClass, EnergyStatement,
|
|
};
|
|
use sandbox_tee::provider::LocalSnpProvider;
|
|
use sandbox_tee::Grounding;
|
|
use sha2::{Digest, Sha512};
|
|
|
|
/// Links in the task's SHA-512 chain: a fixed amount of real CPU work, some
|
|
/// hundreds of milliseconds in a debug build and a few in a release one. A
|
|
/// span too short for the counter to advance over it is not a reading, and
|
|
/// comes back as the meter's estimate.
|
|
pub const CHAIN_LINKS: u64 = 20_000;
|
|
|
|
/// The task: a SHA-512 chain of [`CHAIN_LINKS`] links from a fixed seed. Its
|
|
/// output is the last link, so the work cannot be optimised away.
|
|
pub fn task() -> [u8; 64] {
|
|
let mut link = [0x5au8; 64];
|
|
for _ in 0..CHAIN_LINKS {
|
|
let next = Sha512::digest(link);
|
|
link.copy_from_slice(&next);
|
|
}
|
|
link
|
|
}
|
|
|
|
/// The counter class of the probe among `sources` (a [`PowerMeter`]'s live
|
|
/// hardware probes) that reads CPU energy: only a known one is named. `None`
|
|
/// for a probe set with no CPU counter this example can name.
|
|
pub fn cpu_counter(sources: &[&str]) -> Option<CounterClass> {
|
|
sources.iter().find_map(|s| match *s {
|
|
"process-energy" => Some(CounterClass::ProcessEnergy),
|
|
"rapl-powercap" => Some(CounterClass::Rapl),
|
|
"ioreport-energy-model" => Some(CounterClass::IoReport),
|
|
_ => None,
|
|
})
|
|
}
|
|
|
|
/// The figure to attest for span `m` on `meter`, and the class that obtained
|
|
/// it. A hardware reading of the CPU work — the span's `HwShunt` CPU records,
|
|
/// from a counter this example can name — is attested under that counter's
|
|
/// class and sealed as a reading. Anything else is the meter's estimate of the
|
|
/// span ([`PowerMeter::estimate`]): attested as `Estimator`, sealed as one.
|
|
pub fn figure(meter: &PowerMeter, m: &Measurement) -> (CounterClass, Energy) {
|
|
if m.reads_cpu() {
|
|
if let Some(class) = cpu_counter(&meter.sources()) {
|
|
let cpu_uj: u64 = m
|
|
.devices
|
|
.iter()
|
|
.filter(|d| d.class == DeviceClass::Cpu && d.provenance == Provenance::HwShunt)
|
|
.filter_map(|d| d.measured_uj)
|
|
.sum();
|
|
return (class, Energy::measured(cpu_uj));
|
|
}
|
|
}
|
|
(CounterClass::Estimator, Energy::estimator(meter.estimate(m.wall).total_uj()))
|
|
}
|
|
|
|
/// One run of the composed flow.
|
|
pub struct Run {
|
|
/// The meter's live hardware probes (empty: the estimator alone).
|
|
pub sources: Vec<&'static str>,
|
|
/// The span over the task, as the meter recorded it.
|
|
pub measurement: Measurement,
|
|
/// The attested statement and its report.
|
|
pub attested: AttestedEnergy,
|
|
/// The `efficiency/1` receipt, as a relying party verified it.
|
|
pub receipt: EfficiencyReceipt,
|
|
/// The trust level derived from the attestation.
|
|
pub trust: AttestTrust,
|
|
/// The task's output.
|
|
pub output: [u8; 64],
|
|
/// Whether a tampered joule figure failed attestation verification.
|
|
pub tamper_rejected: bool,
|
|
}
|
|
|
|
/// Run the task, meter it, attest the figure, seal the receipt, and verify the
|
|
/// composition from scratch.
|
|
pub fn run() -> Run {
|
|
// ── 1. The task runs here, metered as it runs.
|
|
let mut meter = PowerMeter::detect_in_process();
|
|
let sources = meter.sources();
|
|
let (output, measurement) = meter.measure(task);
|
|
let (counter, energy) = figure(&meter, &measurement);
|
|
let window_ns = u64::try_from(measurement.wall.as_nanos()).unwrap_or(u64::MAX);
|
|
|
|
// ── 2. A verifier issues a fresh nonce; we attest the figure inside a TEE,
|
|
// under the class that obtained it. The LocalSnpProvider mints a real
|
|
// ECDSA-P384 report — software-grounded.
|
|
let nonce = [0x5au8; 32];
|
|
let measurement_digest = [0x11u8; 48];
|
|
let provider = LocalSnpProvider::new(measurement_digest, 7);
|
|
let statement = EnergyStatement { counter, energy_uj: energy.uj(), window_ns, nonce };
|
|
let attested = attest_energy(statement, &provider).expect("attest the figure");
|
|
|
|
// ── 3. Seal the efficiency/1 receipt at the figure's own grade, committing
|
|
// to the attestation by content id. Its output units are the chain's
|
|
// links; no value figure is stated (none is invented).
|
|
let sk = SigningKey::from_bytes(&[0xefu8; 32]);
|
|
let steward = "did:jcp:attested-efficiency-demo";
|
|
let eff = Efficiency {
|
|
task: "sha512-chain".into(),
|
|
completed: true,
|
|
verdict: "chain-computed".into(),
|
|
tokens_in: 1,
|
|
tokens_out: CHAIN_LINKS,
|
|
energy,
|
|
wall_ns: window_ns,
|
|
value_uusd: None,
|
|
energy_attestation: None,
|
|
}
|
|
.with_energy_attestation(&attested.report);
|
|
let envelope = eff.seal(0, &ContentId([0u8; 32]), &sk, steward);
|
|
|
|
// ── 4. A relying party runs the COMPOSED verification, from scratch:
|
|
// (a) the receipt verifies under the steward key.
|
|
let receipt =
|
|
verify_efficiency(&envelope, steward, &sk.verifying_key().to_bytes()).expect("efficiency/1 verifies");
|
|
// (b) its commitment resolves to the attestation we hold.
|
|
let commitment = receipt.energy_attestation.as_deref().expect("receipt carries an attestation commitment");
|
|
assert_eq!(commitment, ContentId::of_bytes(&attested.report).to_hex(), "commitment must match the attestation");
|
|
// (c) the attestation verifies — deriving the trust level from evidence.
|
|
let trust = verify_attested_energy(&attested, measurement_digest, &nonce, &provider.vcek(), Grounding::Software)
|
|
.expect("attestation verifies");
|
|
// (d) the attested joules equal the sealed joules.
|
|
assert_eq!(attested.statement.energy_uj, receipt.energy_uj, "attested energy must match the receipt");
|
|
|
|
// Tampering is caught: rewrite the attested energy figure downstream.
|
|
let mut forged = attested.clone();
|
|
forged.statement.energy_uj = forged.statement.energy_uj.wrapping_add(1);
|
|
let tamper_rejected =
|
|
verify_attested_energy(&forged, measurement_digest, &nonce, &provider.vcek(), Grounding::Software).is_err();
|
|
|
|
Run { sources, measurement, attested, receipt, trust, output, tamper_rejected }
|
|
}
|
|
|
|
fn main() {
|
|
let r = run();
|
|
let counter = r.attested.statement.counter;
|
|
let sources = if r.sources.is_empty() { "none — the estimator".to_string() } else { r.sources.join(", ") };
|
|
|
|
println!("task '{}' ran here: {} SHA-512 links in {:?}", r.receipt.task, CHAIN_LINKS, r.measurement.wall);
|
|
println!(" meter's live counters : {sources}");
|
|
println!(
|
|
" sealed efficiency/1 : {} µJ [{}] over {} links\n",
|
|
r.receipt.energy_uj, r.receipt.provenance, r.receipt.tokens_out
|
|
);
|
|
|
|
println!("composed verification ✓");
|
|
println!(" receipt : verified under the steward key");
|
|
println!(" commitment : matches the attestation");
|
|
println!(
|
|
" attested energy : {} µJ ({}) == receipt energy {} µJ [{}]",
|
|
r.attested.statement.energy_uj,
|
|
counter.tag(),
|
|
r.receipt.energy_uj,
|
|
r.receipt.provenance
|
|
);
|
|
println!(" nonce : fresh (matches the issued challenge)");
|
|
println!(
|
|
" efficiency : {} µJ / link",
|
|
r.receipt
|
|
.uj_per_accepted_token
|
|
.map_or_else(|| "—".to_string(), |uj| uj.to_string())
|
|
);
|
|
println!(" TRUST LEVEL : {:?}, over a `{}` figure", r.trust, counter.tag());
|
|
println!();
|
|
|
|
assert_eq!(r.trust, AttestTrust::IntegrityAttested);
|
|
if counter == CounterClass::Estimator {
|
|
println!(
|
|
"This is IntegrityAttested over an ESTIMATE: no counter on this host read the\n\
|
|
task's CPU work over the span, so the figure is the meter's estimate, attested\n\
|
|
under the `estimator` class and sealed `Estimator`. The report binds the figure\n\
|
|
to a measured environment; it does not make the figure a reading."
|
|
);
|
|
} else {
|
|
println!(
|
|
"This is IntegrityAttested, not PhysicallyRooted: a software-grounded report\n\
|
|
over a platform-self-reported counter (`{}`) attests an honest *relay* inside\n\
|
|
a measured environment — not a reading rooted independently of the platform.\n\
|
|
(Not a claim that the counter is inaccurate: it is a real sensor reading;\n\
|
|
nothing binds it to the sensor.) An independent root needs a dedicated sensor\n\
|
|
signed at the source (a shunt) on confidential hardware — derived, never asserted.",
|
|
counter.tag()
|
|
);
|
|
}
|
|
|
|
assert!(r.tamper_rejected, "a tampered energy figure must fail attestation verification");
|
|
println!("\n(a tampered joule figure fails attestation verification — checked.)");
|
|
std::hint::black_box(r.output);
|
|
}
|