//! Derive the verifying keys of profiles 5 and 6, print their bundles'
//! digests (the pins of `envelope::keys`) and sizes, and time rebuilding
//! the keys from their layouts.
//!
//! `cargo run --release -p zheng --example wrap_keys -- [out-dir]`
//! writes `recursive.keys` and `wrapped.keys` to `out-dir` when given.
//! `ZHENG_PROFILES=5` skips the wrap chain (minutes, tens of GB).
//! Profile 6 derives the prover's chain (printing the inner levels' key
//! roots: `wrapped::INNER_ROOTS`) unless `ZHENG_VERIFIER=1`, which times
//! the verifier's derivation over the pinned roots instead.

use std::time::Instant;
use zheng::envelope::{Profile, keys};
use zheng::recursion::ivc;
use zheng::recursion::wrap::WrapKey;

fn hex(d: &[u8]) -> String {
    d.iter().map(|b| format!("{b:02x}")).collect()
}

fn ms(t: Instant) -> f64 {
    t.elapsed().as_secs_f64() * 1e3
}

fn main() {
    let out = std::env::args().nth(1);
    let profiles: Vec<u8> = std::env::var("ZHENG_PROFILES")
        .ok()
        .map(|v| v.split(',').filter_map(|p| p.parse().ok()).collect())
        .unwrap_or_else(|| vec![5, 6]);
    for p in profiles {
        let profile = if p == 5 {
            Profile::Recursive
        } else {
            Profile::Wrapped
        };
        if p == 6 {
            let t = Instant::now();
            if std::env::var_os("ZHENG_VERIFIER").is_some() {
                zheng::envelope::wrapped::final_key().expect("final key");
                println!(
                    "profile 6: verifier key derivation over pinned roots {:.0} ms",
                    ms(t)
                );
            } else {
                match zheng::envelope::wrapped::chain_keys() {
                    Ok(_) => println!(
                        "profile 6: prover chain {:.0} ms (roots match the pins)",
                        ms(t)
                    ),
                    Err(e) => println!("profile 6: prover chain {:.0} ms: {e}", ms(t)),
                }
            }
        }
        let t = Instant::now();
        let bundle = keys::export(profile).expect("export");
        let derive = ms(t);
        let digest = keys::digest(&bundle);
        println!(
            "profile {p}: derive {derive:.0} ms · bundle {} B · digest {}",
            bundle.len(),
            hex(&digest)
        );
        // the layouts rebuild keys whose layouts are the same bytes
        let ik = ivc::key(&zheng::envelope::recursive::params(), 15).expect("ivc key");
        let t = Instant::now();
        let lb = ik.layout_bytes();
        let back = ivc::Key::from_layout(&lb).expect("ivc layout");
        println!(
            "  ivc layout {} B · rebuild {:.1} ms · round trip {}",
            lb.len(),
            ms(t),
            back.layout_bytes() == lb
        );
        if p == 6 {
            let fk = zheng::envelope::wrapped::final_key().expect("final key");
            let t = Instant::now();
            let lb = fk.layout_bytes();
            let back = WrapKey::from_layout(&lb).expect("wrap layout");
            println!(
                "  final layout {} B · rebuild {:.1} ms · round trip {} · g nodes {} = {}",
                lb.len(),
                ms(t),
                back.layout_bytes() == lb,
                back.g.nodes.len(),
                fk.g.nodes.len()
            );
        }
        let t = Instant::now();
        let _ = keys::digest(&bundle);
        println!("  digest {:.1} ms", ms(t));
        if let Some(dir) = &out {
            let name = if p == 5 {
                "recursive.keys"
            } else {
                "wrapped.keys"
            };
            std::fs::write(format!("{dir}/{name}"), &bundle).expect("write");
        }
    }
}

Homonyms

cyber/src/main.rs
cyb/cli/src/main.rs
soft3/nox/cli/main.rs
neural/trident/src/main.rs
cyb/optica/src/main.rs
soft3/glia/import/main.rs
cyberia/cyberia-my/src/main.rs
cyb/apps/src/main.rs
soft3/tru/cli/main.rs
neural/rune/cli/main.rs
warriors/trisha/cli/main.rs
warriors/joy/cli/main.rs
cyb/shell/src/main.rs
soft3/conformance/rs/src/main.rs
neural/eidos/cli/src/main.rs
soft3/radio/iroh-dns-server/src/main.rs
soft3/radio/iroh-relay/src/main.rs
soft3/radio/particle/src/main.rs
soft3/strata/cli/src/main.rs
soft3/zheng/cli/src/main.rs
neural/rs/pure-rust-check/src/main.rs
soft3/hemera/cli/src/main.rs
soft3/neuron/cli/src/main.rs
soft3/glia/run/cli/main.rs
neural/rs/link/src/main.rs
soft3/radio/radio-cli/src/main.rs
soft3/foculus/src/bin/main.rs
neural/rs/macho-linker/src/main.rs
soft3/bbg/cli/src/main.rs
neural/rs/rsc/src/main.rs
neural/rs/cli/src/main.rs
soft3/lens/cli/src/main.rs
soft3/cybergraph/cli/src/main.rs
warriors/erga/cli/src/main.rs
soft3/zheng/rs/examples/ivc_bench/main.rs
soft3/zheng/rs/examples/wrap_plan/main.rs
cyb/honeycrisp/acpu/src/probe/main.rs
soft3/strata/jali/cli/src/main.rs
soft3/mudra/audit/quantus-mldsa-crosscheck/src/main.rs
soft3/zheng/rs/examples/envelope_profiles/main.rs
soft3/zheng/specs/proto/zheng_spartan/main.rs
soft3/zheng/rs/examples/wrap_chain/main.rs
warriors/erga/rs/rtable-bench/src/main.rs
soft3/strata/kuro/cli/src/main.rs
soft3/strata/trop/cli/src/main.rs
soft3/zheng/rs/examples/wrap_flip/main.rs
soft3/zheng/rs/examples/wrap_bench/main.rs
warriors/trisha/tools/neptune-policy-oracle/src/main.rs
soft3/zheng/specs/proto/zheng_bug/main.rs
soft3/zheng/specs/proto/zheng_inner/main.rs
soft3/zheng/rs/examples/fast_path/main.rs
soft3/zheng/specs/proto/zheng_spartan_fixed/main.rs
warriors/erga/rs/mine-bench/src/main.rs
soft3/zheng/rs/examples/wrapped_sizes/main.rs
soft3/zheng/rs/examples/wrap_verify/main.rs
soft3/zheng/rs/examples/ivc_plan/main.rs
soft3/zheng/rs/examples/ivc_flip/main.rs
soft3/zheng/rs/examples/machine_bench/main.rs
soft3/zheng/rs/examples/succinct_bakeoff/main.rs
soft3/zheng/specs/proto/zheng_outer/main.rs
neural/inf/rs/cli/src/main.rs
cyb/wysm/crates/cli/src/main.rs
warriors/erga/rs/blake-bench/src/main.rs
soft3/strata/nebu/cli/src/main.rs
soft3/lytics/rs/agent/src/main.rs
cyb/honeycrisp/rane/src/probe/main.rs
neural/trident/silicon/src/bin/main.rs
soft3/strata/genies/cli/src/main.rs
soft3/lytics/rs/ingest/src/main.rs
soft3/radio/audit/2026-10-12-bao-bounded-proof/nostd/src/main.rs
soft3/radio/audit/2026-10-12-bao-proof-research/probe/src/main.rs
soft3/mudra/audit/signature-optimality/xnt-predicate-check/src/main.rs
cyb/honeycrisp/unimem/experiments/hyp_probe/src/main.rs
soft3/radio/audit/2026-10-12-bao-bounded-proof/fixture-probe/src/main.rs
soft3/radio/audit/2026-10-12-bao-bounded-proof/nostd-parent/src/main.rs
soft3/radio/audit/2026-10-12-bao-proof-research/primary-probe/src/main.rs
cyb/honeycrisp/unimem/experiments/iosurface_probe/src/main.rs
cyb/honeycrisp/unimem/experiments/dext_contiguous_alloc/client/src/main.rs
cyb/honeycrisp/unimem/experiments/dext_iosurface_pa/client/src/main.rs

Graph