wai-quantum 0.3.18

A deterministic quantum stack in pure Rust: byte-exact circuit simulation (statevector / stabilizer / tensor-network MPS / sparse-Pauli backends), error mitigation, qLDPC decoding, noise learning, circuit-equivalence proofs, a phasor interference-ML layer, information-theoretic limits, noisy channels and state tomography, and signed energy-accounted receipts. No QPU, no cloud, no system libraries — identical results native, in the browser, and as a WASI component at the edge.
Documentation
//! Quantum-circuit receipt — the energy-accounted seal for a
//! `wai.quantum.circuit` reconstruction (extensions/quantum-sim § Receipt).
//!
//! This is the artifact WAI's determinism uniquely enables here: a signed record
//! that cleanly **separates the two halves** of a classical quantum-simulation's
//! cost, so each half is trusted the way it can honestly be trusted.
//!
//! - The **work** is *portable-exact*: `n_ops · 2^n` amplitude updates — a number
//!   anyone recomputes from `(n_ops, n_qubits)` alone, and which grows
//!   **exponentially** in qubits. It is the honest, machine-independent measure of
//!   what a classical sink actually did to reconstruct the state. **Verified by
//!   recomputation, not attested.**
//! - The **energy** is *measured-attested*: `joules_micro`, the real marginal CPU
//!   energy the sink's meter recorded (`wai_quantum_meter`, IOReport via `macmon`).
//!   Only the signer can vouch for what its own silicon drew. **Attested by
//!   signature, not verifiable by a third party.**
//!
//! The **`statevector_hash`** binds both to a byte-exact reconstruction anyone can
//! independently re-simulate and check ([`QuantumReceipt::verify_reconstruction`]).
//! So the receipt states, checkably: *"this circuit reconstructs to THIS
//! statevector [re-checkable], costing THIS exact deterministic work
//! [re-checkable], which drew THIS measured energy on my machine \[signed\]."*
//!
//! It is a JWP profile like every other receipt in this crate — the
//! worlds/provenance Merkle (`crate::merkle::merkle_root`) + Ed25519,
//! reused, not reinvented — and chains across a derivation via
//! `parent_receipt_hash`. Because a quantum computation carries no speedup here,
//! the receipt's value is exactly this: it makes the *cost* of the reconstruction
//! auditable, and the *result* reproducible.

use crate::quantum::{circuit_hash, Circuit, Measure, QuantumError};
use crate::merkle::merkle_root;
use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};

const DOMAIN_RECEIPT: &[u8] = b"wai:quantum-receipt\x01";
const DOMAIN_RECEIPT_ID: &[u8] = b"wai:quantum-receipt-id\x01";

fn hx(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)
}

fn from_hex64(s: &str) -> Option<[u8; 64]> {
    if s.len() != 128 || !s.bytes().all(|b| b.is_ascii_hexdigit()) {
        return None;
    }
    let mut out = [0u8; 64];
    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)
}

/// The exact, portable, machine-independent reconstruction work in amplitude
/// updates: `n_ops · 2^n_qubits` (saturating). Every gate touches the whole
/// `2^n` state, so this is the count of complex fused-multiply-adds a faithful
/// statevector sink performs — the number that makes the *cost* auditable and
/// grows exponentially in qubits. Recomputable by anyone from the two inputs,
/// so a verifier never trusts the sink's claim of it.
pub fn work_amp_updates(n_qubits: u8, n_ops: u32) -> u64 {
    (n_ops as u64).saturating_mul(1u64 << n_qubits.min(63))
}

/// The measurement half of a receipt: a shot histogram at a pinned
/// `(seed, shots)` (sampled by the circuit's pinned `splitmix64`, so this hash
/// converges on every machine too — shot-histogram-equivalence).
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MeasureRecord {
    pub seed: u64,
    pub shots: u64,
    pub histogram_hash: [u8; 32],
}

/// A signed, energy-accounted seal over one `wai.quantum.circuit` reconstruction.
#[derive(Clone, Debug, PartialEq)]
pub struct QuantumReceipt {
    /// Identity: the WQC circuit hash (`crate::quantum::circuit_hash`).
    pub circuit_hash: [u8; 32],
    /// The reconstruction result: the `2^n`-amplitude statevector's portable hash.
    pub statevector_hash: [u8; 32],
    pub n_qubits: u8,
    pub n_ops: u32,
    /// Present iff the receipt also vouches for a shot histogram.
    pub measurement: Option<MeasureRecord>,
    /// Merkle root over the receipt's leaf hashes (circuit, statevector,
    /// \[histogram\]) — JWP's exact domains, reused.
    pub merkle_root: [u8; 32],
    /// Exact, portable reconstruction work = `n_ops · 2^n` (see
    /// [`work_amp_updates`]). Verified by recomputation.
    pub work_amp_updates: u64,
    /// Measured microjoules the sink spent reconstructing (`0` = unmetered).
    /// Attested by the signature, not independently verifiable.
    pub joules_micro: u64,
    pub parent_receipt_hash: Option<[u8; 32]>,
    pub signer_pubkey: [u8; 32],
    pub signer_id: String,
    pub sig: [u8; 64],
}

impl QuantumReceipt {
    /// Leaf hashes, in fixed order: circuit hash, statevector hash, and (if the
    /// receipt vouches for a measurement) the histogram hash.
    fn leaves(&self) -> Vec<[u8; 32]> {
        let mut v = vec![self.circuit_hash, self.statevector_hash];
        if let Some(m) = &self.measurement {
            v.push(m.histogram_hash);
        }
        v
    }

    fn signing_payload(&self) -> Vec<u8> {
        let mut o = DOMAIN_RECEIPT.to_vec();
        o.extend_from_slice(&self.circuit_hash);
        o.extend_from_slice(&self.statevector_hash);
        o.push(self.n_qubits);
        o.extend_from_slice(&self.n_ops.to_be_bytes());
        o.extend_from_slice(&self.merkle_root);
        o.extend_from_slice(&self.work_amp_updates.to_be_bytes());
        o.extend_from_slice(&self.joules_micro.to_be_bytes());
        match &self.measurement {
            Some(m) => {
                o.push(1);
                o.extend_from_slice(&m.seed.to_be_bytes());
                o.extend_from_slice(&m.shots.to_be_bytes());
                o.extend_from_slice(&m.histogram_hash);
            }
            None => o.push(0),
        }
        match self.parent_receipt_hash {
            Some(h) => {
                o.push(1);
                o.extend_from_slice(&h);
            }
            None => o.push(0),
        }
        o.extend_from_slice(&self.signer_pubkey);
        o.extend_from_slice(self.signer_id.as_bytes());
        o
    }

    /// Simulate `circuit`, then build and sign a receipt over the byte-exact
    /// reconstruction. Simulating *inside* seal is deliberate: the receipt's
    /// `statevector_hash` is always the true reconstruction, never a caller
    /// claim. `joules_micro` is the sink's measured energy (`0` if unmetered);
    /// pass `measure` to also vouch for a shot histogram.
    pub fn seal(
        signer: &SigningKey,
        signer_id: impl Into<String>,
        circuit: &Circuit,
        measure: Option<Measure>,
        joules_micro: u64,
        parent_receipt_hash: Option<[u8; 32]>,
    ) -> Result<QuantumReceipt, QuantumError> {
        let sv = circuit.simulate()?;
        let statevector_hash = sv.statevector_hash();
        let measurement = measure.map(|m| MeasureRecord {
            seed: m.seed,
            shots: m.shots,
            histogram_hash: sv.histogram_hash(m.seed, m.shots),
        });
        let mut r = QuantumReceipt {
            circuit_hash: circuit_hash(circuit),
            statevector_hash,
            n_qubits: circuit.n_qubits,
            n_ops: circuit.ops.len() as u32,
            measurement,
            merkle_root: [0u8; 32],
            work_amp_updates: work_amp_updates(circuit.n_qubits, circuit.ops.len() as u32),
            joules_micro,
            parent_receipt_hash,
            signer_pubkey: signer.verifying_key().to_bytes(),
            signer_id: signer_id.into(),
            sig: [0u8; 64],
        };
        r.merkle_root = merkle_root(&r.leaves());
        r.sig = signer.sign(&r.signing_payload()).to_bytes();
        Ok(r)
    }

    /// Verify the receipt is internally consistent and signed: the Merkle root
    /// recomputes over its leaves, the work equals `n_ops · 2^n` (a stated cost a
    /// sink cannot inflate), and the Ed25519 signature is valid. This does NOT
    /// re-run the simulation — see [`Self::verify_reconstruction`] for that.
    pub fn verify(&self) -> bool {
        if merkle_root(&self.leaves()) != self.merkle_root {
            return false;
        }
        if self.work_amp_updates != work_amp_updates(self.n_qubits, self.n_ops) {
            return false;
        }
        let Ok(k) = VerifyingKey::from_bytes(&self.signer_pubkey) else {
            return false;
        };
        k.verify(&self.signing_payload(), &Signature::from_bytes(&self.sig))
            .is_ok()
    }

    /// The strong, portable check: independently re-simulate `circuit` and
    /// confirm it reproduces this receipt's identity, reconstruction, shape, and
    /// (if present) histogram — then that the receipt itself verifies. Anyone
    /// holding the circuit can run this on any machine and reject a receipt whose
    /// claimed statevector is not what the circuit actually reconstructs to.
    /// (The measured `joules_micro` remains attested-only — re-simulation checks
    /// the *result and cost*, never the signer's energy draw.)
    pub fn verify_reconstruction(&self, circuit: &Circuit) -> bool {
        if circuit_hash(circuit) != self.circuit_hash {
            return false;
        }
        if circuit.n_qubits != self.n_qubits || circuit.ops.len() as u32 != self.n_ops {
            return false;
        }
        let Ok(sv) = circuit.simulate() else {
            return false;
        };
        if sv.statevector_hash() != self.statevector_hash {
            return false;
        }
        if let Some(m) = &self.measurement
            && sv.histogram_hash(m.seed, m.shots) != m.histogram_hash
        {
            return false;
        }
        self.verify()
    }

    /// Stable id for chaining a derived receipt via `parent_receipt_hash`.
    pub fn receipt_hash(&self) -> [u8; 32] {
        let mut h = blake3::Hasher::new();
        h.update(DOMAIN_RECEIPT_ID);
        h.update(&self.signing_payload());
        h.update(&self.sig);
        *h.finalize().as_bytes()
    }

    /// Canonical JSON (hex-encoded hashes), fields in sorted key order — the
    /// portable receipt an out-of-band verifier reads.
    pub fn to_json(&self) -> String {
        let parent = match self.parent_receipt_hash {
            Some(h) => format!("\"{}\"", hx(&h)),
            None => "null".into(),
        };
        let measurement = match &self.measurement {
            Some(m) => format!(
                "{{\"histogram_hash\":\"{}\",\"seed\":{},\"shots\":{}}}",
                hx(&m.histogram_hash),
                m.seed,
                m.shots
            ),
            None => "null".into(),
        };
        format!(
            "{{\"kind\":\"quantum-circuit\",\"circuit_hash\":\"{}\",\"joules_micro\":{},\
             \"measurement\":{},\"n_ops\":{},\"n_qubits\":{},\"parent_receipt_hash\":{},\
             \"receipt_hash\":\"{}\",\"root_hash\":\"{}\",\"sig\":\"{}\",\"signer_id\":{},\
             \"signer_pubkey\":\"{}\",\"statevector_hash\":\"{}\",\"work_amp_updates\":{}}}",
            hx(&self.circuit_hash),
            self.joules_micro,
            measurement,
            self.n_ops,
            self.n_qubits,
            parent,
            hx(&self.receipt_hash()),
            hx(&self.merkle_root),
            hx(&self.sig),
            serde_json::to_string(&self.signer_id).unwrap(),
            hx(&self.signer_pubkey),
            hx(&self.statevector_hash),
            self.work_amp_updates,
        )
    }

    /// Parse a receipt from its canonical JSON (for a verifying sink).
    pub fn from_json(s: &str) -> Option<QuantumReceipt> {
        let v: serde_json::Value = serde_json::from_str(s).ok()?;
        let o = v.as_object()?;
        let u = |k: &str| o.get(k).and_then(|x| x.as_u64());
        let measurement = match o.get("measurement") {
            Some(serde_json::Value::Object(m)) => Some(MeasureRecord {
                seed: m.get("seed")?.as_u64()?,
                shots: m.get("shots")?.as_u64()?,
                histogram_hash: from_hex32(m.get("histogram_hash")?.as_str()?)?,
            }),
            _ => None,
        };
        let parent = match o.get("parent_receipt_hash") {
            Some(serde_json::Value::String(s)) => Some(from_hex32(s)?),
            _ => None,
        };
        Some(QuantumReceipt {
            circuit_hash: from_hex32(o.get("circuit_hash")?.as_str()?)?,
            statevector_hash: from_hex32(o.get("statevector_hash")?.as_str()?)?,
            n_qubits: u("n_qubits")? as u8,
            n_ops: u("n_ops")? as u32,
            measurement,
            merkle_root: from_hex32(o.get("root_hash")?.as_str()?)?,
            work_amp_updates: u("work_amp_updates")?,
            joules_micro: u("joules_micro")?,
            parent_receipt_hash: parent,
            signer_pubkey: from_hex32(o.get("signer_pubkey")?.as_str()?)?,
            signer_id: o.get("signer_id")?.as_str()?.to_owned(),
            sig: from_hex64(o.get("sig")?.as_str()?)?,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::quantum::Circuit;

    fn key(s: u8) -> SigningKey {
        SigningKey::from_bytes(&[s; 32])
    }

    #[test]
    fn seals_verifies_and_reconstructs() {
        let mut c = Circuit::new(3);
        c.h(0).cx(0, 1).cx(1, 2); // GHZ-3
        let r =
            QuantumReceipt::seal(&key(1), "did:key:test", &c, None, 117_000, None).unwrap();
        assert!(r.verify());
        assert!(r.verify_reconstruction(&c));
        // work is the exact, recomputable cost: 3 ops · 2^3 = 24 amplitude updates.
        assert_eq!(r.work_amp_updates, 24);
        assert_eq!(r.n_qubits, 3);
        assert_eq!(r.n_ops, 3);
        assert_eq!(r.joules_micro, 117_000);
    }

    #[test]
    fn measurement_histogram_is_vouched() {
        let mut c = Circuit::new(2);
        c.h(0).cx(0, 1); // Bell
        let m = Measure { seed: 0xC0FFEE, shots: 10_000 };
        let r = QuantumReceipt::seal(&key(2), "m", &c, Some(m), 0, None).unwrap();
        assert!(r.verify());
        assert!(r.verify_reconstruction(&c));
        let mr = r.measurement.expect("measurement present");
        assert_eq!(mr.seed, 0xC0FFEE);
        assert_eq!(mr.shots, 10_000);
    }

    #[test]
    fn tamper_breaks_verification() {
        let mut c = Circuit::new(2);
        c.h(0).cx(0, 1);
        let mut r = QuantumReceipt::seal(&key(3), "m", &c, None, 42, None).unwrap();
        // Flipping the claimed energy (a signed field) breaks the signature.
        r.joules_micro = 43;
        assert!(!r.verify());
    }

    #[test]
    fn a_lie_about_the_statevector_is_caught_by_resimulation() {
        let mut c = Circuit::new(2);
        c.h(0).cx(0, 1);
        let honest = QuantumReceipt::seal(&key(4), "m", &c, None, 0, None).unwrap();
        // A different circuit reconstructs to a different statevector; a receipt
        // that claims `honest`'s statevector for it must fail re-simulation.
        let mut other = Circuit::new(2);
        other.h(0); // NOT entangled — different state
        assert!(!honest.verify_reconstruction(&other));
    }

    #[test]
    fn json_round_trips() {
        let mut c = Circuit::new(3);
        c.h(0).cx(0, 1).cx(1, 2);
        let m = Measure { seed: 7, shots: 512 };
        let r = QuantumReceipt::seal(&key(5), "did:key:z6Mk", &c, Some(m), 900, None).unwrap();
        let back = QuantumReceipt::from_json(&r.to_json()).expect("parse");
        assert_eq!(r, back);
        assert!(back.verify());
    }

    #[test]
    fn chains_to_a_parent() {
        let mut c = Circuit::new(2);
        c.h(0).cx(0, 1);
        let root = QuantumReceipt::seal(&key(6), "m", &c, None, 10, None).unwrap();
        let mut c2 = Circuit::new(2);
        c2.h(0).cx(0, 1).z(1); // a derived run
        let child =
            QuantumReceipt::seal(&key(6), "m", &c2, None, 12, Some(root.receipt_hash()))
                .unwrap();
        assert!(child.verify());
        assert_eq!(child.parent_receipt_hash, Some(root.receipt_hash()));
    }
}