warriors/trisha/rs/examples/recursive_baselines.rs

//! Generate genuine native proofs and independent hand-assembly benchmark fixtures.
//! Does not compile or execute any Trident source to obtain expected results.
use std::path::Path;
use trident::runtime::ProgramInput;
use trisha_rs::recursive;
use triton_vm::prelude::*;

fn fields(values: &[u64]) -> String {
    format!(
        "[{}]",
        values
            .iter()
            .map(|v| format!("\"{v}\""))
            .collect::<Vec<_>>()
            .join(", ")
    )
}

fn fixture(
    root: &Path,
    name: &str,
    source: &str,
    hand: &str,
    prefix: &str,
    input: &ProgramInput,
    output: &[u64],
    failure: bool,
    library: bool,
) {
    let directory = root.join("baselines/triton/fixtures").join(name);
    std::fs::create_dir_all(&directory).unwrap();
    let libraries = if library {
        "[\"../../os/neptune/proof.tasm\"]"
    } else {
        "[]"
    };
    let witness_files = if name.starts_with("recursive-aggregate") {
        "[\"../recursive-witnesses/first.toml\", \"../recursive-witnesses/second.toml\"]"
    } else {
        "[\"../recursive-witnesses/first.toml\"]"
    };
    let text = format!(
        r#"source = "../../../../examples/triton/{source}.tri"
hand = "../../os/neptune/{hand}.tasm"
target = "triton"
input = {public}
output = {output}
witness_files = {witness_files}
hand_prefix = "{prefix}"
hand_libraries = {libraries}
expect_failure = {failure}
max_cycles = 3000000
reference = "Official default-security Triton7 proof for read_io1 +3 write_io1, inputs2/9 outputs5/12. Expected full-claim commitments computed by native Tip5(BFieldCodec Claim); published Triton7 verifier hand linkage is independent of Trident compilation. Version1 full-proof ABI replaces invalid configurable-FRI prototype."
"#,
        public = fields(&input.public),
        output = fields(output)
    );
    std::fs::write(directory.join("vector.bench.toml"), text).unwrap();
}

fn main() {
    let root = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap();
    let program = Program::from_code("read_io 1 push 3 add write_io 1 halt").unwrap();
    let mut witnesses = Vec::new();
    for value in [2, 9] {
        let (trace, output) = VM::trace_execution(
            program.clone(),
            vec![BFieldElement::new(value)].into(),
            NonDeterminism::default(),
        )
        .unwrap();
        assert_eq!(output, vec![BFieldElement::new(value + 3)]);
        let claim = Claim::about_program(&program)
            .with_input(vec![BFieldElement::new(value)])
            .with_output(output);
        let proof = Stark::default().prove(&claim, &trace).unwrap();
        witnesses.push(recursive::encode(&claim, &proof).unwrap());
    }
    let witness_dir = root.join("baselines/triton/fixtures/recursive-witnesses");
    std::fs::create_dir_all(&witness_dir).unwrap();
    for (name, witness) in ["first", "second"].into_iter().zip(&witnesses) {
        let digests = witness
            .digests
            .iter()
            .flatten()
            .copied()
            .collect::<Vec<_>>();
        std::fs::write(
            witness_dir.join(format!("{name}.toml")),
            format!(
                "secret = {}\ndigests = {}\n",
                fields(&witness.secret),
                fields(&digests)
            ),
        )
        .unwrap();
    }
    let hand_root = root.join("baselines/triton/os/neptune");
    std::fs::write(hand_root.join("proof.tasm"), format!("// Version1 real default-security verifier. Generated by recursive_baselines.\n// Historical filename retained in the43-entry benchmark inventory; VM ownership is Trisha.\n{}", recursive::assembly())).unwrap();
    std::fs::write(hand_root.join("programs/recursive_verifier.tasm"), "// Version1: public full-claim commitment; output1 after verification.\n__main: read_io 5 call trisha_recursive_verify_v1 push 1 write_io 1 halt\n").unwrap();
    let relay = "read_io 5 dup 4 dup 4 dup 4 dup 4 dup 4 call trisha_recursive_verify_v1 swap 4 swap 1 swap 3 swap 1 write_io 5";
    std::fs::write(
        hand_root.join("programs/proof_relay.tasm"),
        format!("// Version1: output the verified full-claim commitment.\n__main: {relay} halt\n"),
    )
    .unwrap();
    std::fs::write(hand_root.join("programs/proof_aggregator.tasm"), format!("// Version1: bounded1..16 independent full proofs.\n__main: read_io 1 dup 0 push 0 eq push 0 eq assert push 17 dup 1 lt assert call __aggregate_loop pop 1 halt\n__aggregate_loop: dup 0 push 0 eq skiz return\n{relay}\npush -1 add recurse\n")).unwrap();
    for (name, source, hand, prefix, output, library) in [
        (
            "recursive-proof",
            "recursive_verifier",
            "proof",
            "read_io 5 call trisha_recursive_verify_v1 push 1 write_io 1 halt\\n",
            vec![1],
            false,
        ),
        (
            "recursive-verifier",
            "recursive_verifier",
            "programs/recursive_verifier",
            "call __main halt\\n",
            vec![1],
            true,
        ),
        (
            "recursive-relay",
            "proof_relay",
            "programs/proof_relay",
            "call __main halt\\n",
            witnesses[0].public.clone(),
            true,
        ),
    ] {
        fixture(
            root,
            name,
            source,
            hand,
            prefix,
            &witnesses[0],
            &output,
            false,
            library,
        );
        let mut wrong = witnesses[0].clone();
        wrong.public[0] = (wrong.public[0] + 1) % BFieldElement::P;
        fixture(
            root,
            &format!("{name}-bad-claim"),
            source,
            hand,
            prefix,
            &wrong,
            &[],
            true,
            library,
        );
    }
    let mut aggregate = ProgramInput {
        public: vec![2],
        secret: vec![],
        digests: vec![],
    };
    let mut output = Vec::new();
    for witness in witnesses {
        output.extend(&witness.public);
        aggregate.public.extend(witness.public);
        aggregate.secret.extend(witness.secret);
        aggregate.digests.extend(witness.digests);
    }
    fixture(
        root,
        "recursive-aggregate-two",
        "proof_aggregator",
        "programs/proof_aggregator",
        "call __main halt\\n",
        &aggregate,
        &output,
        false,
        true,
    );
    for invalid_count in [0, 17, 1u64 << 32] {
        let mut invalid = aggregate.clone();
        invalid.public[0] = invalid_count;
        fixture(
            root,
            &format!("recursive-aggregate-count-{invalid_count}"),
            "proof_aggregator",
            "programs/proof_aggregator",
            "call __main halt\\n",
            &invalid,
            &[],
            true,
            true,
        );
    }
    aggregate.public[6] = (aggregate.public[6] + 1) % BFieldElement::P;
    fixture(
        root,
        "recursive-aggregate-bad-second",
        "proof_aggregator",
        "programs/proof_aggregator",
        "call __main halt\\n",
        &aggregate,
        &[],
        true,
        true,
    );
    println!("Generated eleven positive/negative fixtures covering four actual recursive baselines; transaction validation remains a separate protocol.");
}

Graph