open-standards/wai/wai-quantum/examples/receipt.rs
Transaction Science e546a87a2f wai-quantum circuit2: the crate's consumers follow the circuit's gateset
QuantumReceipt gains gateset_of, which names the gateset under which a
circuit's ops hash to the receipt's circuit_hash, and gateset_note, which
turns that into the text to show when a reconstruction fails for that
reason. verify_reconstruction stays strict. from_json refuses an n_qubits
that does not fit a u8 and an n_ops that does not fit a u32 instead of
truncating them.

The fabric names its gate kernel and random corpus once per gateset:
wai.quantum.circuit2/apply and wai.quantum.circuit2/random-v1 join the
circuit/1 names. certify_lanes and lanes::random_circuit take a gateset and
draw the same ops from a seed in both. detect_local offers the reference
kernel of each gateset. The lanes32 corpus digests for seed 7 and 200 cases
are pinned: d18454c6 for circuit/1, as 0.3.41 certified it, and 3dbde276
for circuit2.

noisy_expect_z and route_line build their circuits with empty_like, so a
derived circuit keeps its source's gateset. from_qasm refuses a gate that
names one qubit twice as an invalid circuit when it reads it, in every
gateset. quantum_spd's controlled_phase refuses a phase on 32 or more
qubits instead of shifting out of range. The QIR and QASM export docs say
that a circuit/1 circuit exports ideal angles, not its own numerics. The
bell and receipt examples print the capability and handle the fallible
calls.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 11:19:49 -04:00

47 lines
2 KiB
Rust

//! Sealing a computation into a signed, energy-accounted receipt — and watching
//! verification reject a doctored one.
//!
//! cargo run --example receipt
use wai_quantum::ed25519_dalek::SigningKey;
use wai_quantum::quantum::{Gateset, Measure};
use wai_quantum::quantum_receipt::QuantumReceipt;
use wai_quantum::quantum_toolchain as qt;
fn main() {
let circuit = qt::ghz(3);
let key = SigningKey::from_bytes(&[42u8; 32]); // demo key; use a real one
let receipt = QuantumReceipt::seal(
&key,
"did:key:example",
&circuit,
Some(Measure { seed: 7, shots: 4096 }),
0, // measured microjoules; 0 means unmetered
None,
)
.expect("seal");
println!("capability {}", circuit.gateset.capability());
println!("verifies {}", receipt.verify());
println!("re-simulates to claim {}", receipt.verify_reconstruction(&circuit));
// The receipt binds the circuit's gateset: the same ops in circuit/1 do not
// reconstruct it, and the receipt says which gateset they need.
let mut v1 = circuit.clone();
v1.gateset = Gateset::V1;
println!("same ops, circuit/1 {}", receipt.verify_reconstruction(&v1));
if let Some(note) = receipt.gateset_note(&v1) {
println!(" {note}");
}
println!("work {} amplitude updates", receipt.work_amp_updates);
println!("energy {} uJ (0 = unmetered)", receipt.joules_micro);
// The work is recomputable by anyone from (n_qubits, n_ops), so a sink cannot
// inflate it. The energy is only as good as the signature, and says so.
let json = receipt.to_json();
let tampered = json.replace("\"work_amp_updates\":24", "\"work_amp_updates\":2400");
assert_ne!(json, tampered, "expected the work field in the JSON");
let forged = QuantumReceipt::from_json(&tampered).expect("still parses");
println!("\nclaiming 100x the work: verifies = {}", forged.verify());
}