soft3/lens/cli/src/main.rs

// ---
// tags: lens, rust
// crystal-type: source
// crystal-domain: comp
// ---
//! lens CLI โ€” commit to a file as a polynomial, open evaluations, verify
//! openings without the file. Wraps every construction of the commitment
//! layer behind one binary. See specs/cli.md.
//!
//! Constructions: Brakedown (default) and Ikat over Goldilocks, Binius over
//! Fโ‚‚ยนยฒโธ, Porphyry over F_q โ€” all via the `Lens` trait and a field-generic
//! command path. Assayer (tropical witness-verify) has its own two commands.

mod algo;
mod artifact;
mod assayer;
mod commands;
mod field;

#[cfg(test)]
mod tests;

use std::process::exit;

use algo::{Algo, parse_algo};
use genies::Fq;
use kuro::F2_128;
use lens::binius::Binius;
use lens::brakedown::Brakedown;
use lens::ikat::Ikat;
use lens::porphyry::Porphyry;
use nebu::Goldilocks;

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    if args.is_empty() {
        print_usage();
        exit(1);
    }
    let cmd = args[0].as_str();
    let rest = &args[1..];

    let result = match cmd {
        "commit" => run_commit(rest),
        "open" => run_open(rest),
        "verify" | "verify-batch" => run_verify(rest),
        "open-batch" => run_open_batch(rest),
        "eval" => run_eval(rest),
        "check" => run_check(rest),
        "params" => run_params(rest),
        "vectors" => run_vectors(),
        "assayer" => run_assayer(rest),
        "assayer-verify" => run_assayer_verify(rest),
        "help" | "-h" | "--help" => {
            print_usage();
            return;
        }
        other => Err(format!("unknown command '{other}' โ€” try `lens help`")),
    };

    if let Err(e) = result {
        eprintln!("error: {e}");
        exit(1);
    }
}

// โ”€โ”€ dispatch: pick (field, construction) from --algo, monomorphize โ”€โ”€

macro_rules! dispatch {
    ($algo:expr, $f:ident $(, $arg:expr)*) => {
        match $algo {
            Algo::Brakedown => commands::$f::($algo $(, $arg)*),
            Algo::Ikat => commands::$f::($algo $(, $arg)*),
            Algo::Binius => commands::$f::($algo $(, $arg)*),
            Algo::Porphyry => commands::$f::($algo $(, $arg)*),
        }
    };
}

fn run_commit(args: &[String]) -> Result<(), String> {
    let Flags { algo, pos, .. } = parse_flags(args)?;
    let file = pos.first().ok_or("usage: lens commit <file> [--algo A]")?;
    dispatch!(algo, commit, file)
}

fn run_open(args: &[String]) -> Result<(), String> {
    let Flags { algo, out, pos, .. } = parse_flags(args)?;
    let (file, point) = pos
        .split_first()
        .ok_or("usage: lens open <file> <point...> [--algo A] [-o opening.lens]")?;
    dispatch!(algo, open, file, point, out.as_deref())
}

fn run_open_batch(args: &[String]) -> Result<(), String> {
    let Flags { algo, out, pos, .. } = parse_flags(args)?;
    if pos.len() != 2 {
        return Err(
            "usage: lens open-batch <file> <points-file> [--algo A] [-o opening.lens]".into(),
        );
    }
    dispatch!(algo, open_batch, &pos[0], &pos[1], out.as_deref())
}

fn run_verify(args: &[String]) -> Result<(), String> {
    if args.len() != 2 {
        return Err("usage: lens verify <commitment> <opening.lens>".into());
    }
    let bytes = std::fs::read(&args[1]).map_err(|e| format!("{}: {e}", args[1]))?;
    let algo = Algo::from_tag(artifact::peek_algo(&bytes)?)?;
    let c = args[0].as_str();
    match algo {
        Algo::Brakedown => commands::verify::<Goldilocks, Brakedown>(algo, c, &bytes),
        Algo::Ikat => commands::verify::<Goldilocks, Ikat>(algo, c, &bytes),
        Algo::Binius => commands::verify::<F2_128, Binius>(algo, c, &bytes),
        Algo::Porphyry => commands::verify::<Fq, Porphyry>(algo, c, &bytes),
    }
}

fn run_eval(args: &[String]) -> Result<(), String> {
    let Flags { algo, pos, .. } = parse_flags(args)?;
    let (file, point) = pos
        .split_first()
        .ok_or("usage: lens eval <file> <point...> [--algo A]")?;
    match algo {
        Algo::Brakedown | Algo::Ikat => commands::eval::<Goldilocks>(file, point),
        Algo::Binius => commands::eval::<F2_128>(file, point),
        Algo::Porphyry => commands::eval::<Fq>(file, point),
    }
}

fn run_check(args: &[String]) -> Result<(), String> {
    let Flags {
        algo, vars, pos, ..
    } = parse_flags(args)?;
    let file = pos.first().map(String::as_str);
    dispatch!(algo, check, file, vars)
}

fn run_params(args: &[String]) -> Result<(), String> {
    let Flags { algo, .. } = parse_flags(args)?;
    let (field, encoding) = match algo {
        Algo::Brakedown => (
            "Goldilocks (p = 2^64 - 2^32 + 1)",
            "Margulis expander + tensor",
        ),
        Algo::Ikat => ("Goldilocks NTT slots (R_q)", "NTT-batched Brakedown"),
        Algo::Binius => ("Fโ‚‚ยนยฒโธ binary tower", "binary folding + hemera Merkle"),
        Algo::Porphyry => ("F_q (CSIDH-512 prime)", "expander codes over deep field"),
    };
    println!("construction : {}", algo.name());
    println!("field        : {field}");
    println!("encoding     : {encoding}");
    println!("commitment   : 32 bytes (hemera)");
    println!("security ฮป   : 128");
    Ok(())
}

fn run_vectors() -> Result<(), String> {
    let inputs: [(&str, &[u8]); 3] = [("empty", b""), ("hello", b"hello"), ("lens", b"lens")];
    println!("{{");
    let algos = [Algo::Brakedown, Algo::Ikat, Algo::Binius, Algo::Porphyry];
    for (ai, algo) in algos.iter().enumerate() {
        println!("  \"{}\": {{", algo.name());
        for (ii, (name, data)) in inputs.iter().enumerate() {
            let comma = if ii + 1 < inputs.len() { "," } else { "" };
            let c = commit_bytes(*algo, data);
            println!("    \"commit_{name}\": \"{c}\"{comma}");
        }
        let comma = if ai + 1 < algos.len() { "," } else { "" };
        println!("  }}{comma}");
    }
    println!("}}");
    Ok(())
}

fn commit_bytes(algo: Algo, data: &[u8]) -> String {
    use lens::Lens;
    match algo {
        Algo::Brakedown => Brakedown::commit(&commands::poly_from_bytes::<Goldilocks>(data))
            .0
            .to_hex(),
        Algo::Ikat => Ikat::commit(&commands::poly_from_bytes::<Goldilocks>(data))
            .0
            .to_hex(),
        Algo::Binius => Binius::commit(&commands::poly_from_bytes::<F2_128>(data))
            .0
            .to_hex(),
        Algo::Porphyry => Porphyry::commit(&commands::poly_from_bytes::<Fq>(data))
            .0
            .to_hex(),
    }
}

fn run_assayer(args: &[String]) -> Result<(), String> {
    let Flags { out, pos, .. } = parse_flags(args)?;
    let problem = pos
        .first()
        .ok_or("usage: lens assayer <problem.json> [-o witness.lens]")?;
    assayer::solve(problem, out.as_deref())
}

fn run_assayer_verify(args: &[String]) -> Result<(), String> {
    if args.len() != 2 {
        return Err("usage: lens assayer-verify <commitment> <witness.lens>".into());
    }
    assayer::verify(&args[0], &args[1])
}

// โ”€โ”€ flags โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

struct Flags {
    algo: Algo,
    out: Option<String>,
    vars: Option<usize>,
    pos: Vec<String>,
}

fn parse_flags(args: &[String]) -> Result<Flags, String> {
    let mut algo = Algo::Brakedown;
    let mut out = None;
    let mut vars = None;
    let mut pos = Vec::new();
    let mut i = 0;
    while i < args.len() {
        match args[i].as_str() {
            "--algo" => algo = parse_algo(next(args, &mut i, "--algo")?)?,
            "-o" => out = Some(next(args, &mut i, "-o")?.to_string()),
            "--vars" => {
                let n = next(args, &mut i, "--vars")?
                    .parse::<usize>()
                    .map_err(|_| "--vars expects a number".to_string())?;
                if n > 24 {
                    return Err("--vars capped at 24 (2^24 evaluations)".into());
                }
                vars = Some(n);
            }
            other => pos.push(other.to_string()),
        }
        i += 1;
    }
    Ok(Flags {
        algo,
        out,
        vars,
        pos,
    })
}

fn next<'a>(args: &'a [String], i: &mut usize, flag: &str) -> Result<&'a str, String> {
    *i += 1;
    args.get(*i)
        .map(String::as_str)
        .ok_or_else(|| format!("{flag} expects a value"))
}

fn print_usage() {
    eprintln!(
        "\
\x1b[31m
    โ–ˆโ–ˆโ•—     โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
\x1b[33m    โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•
\x1b[32m    โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
\x1b[36m    โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•”โ•โ•โ•  โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘
\x1b[34m    โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘
\x1b[35m    โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•
\x1b[0m\x1b[37m    the commitment for superintelligence\x1b[0m
\x1b[90m
    polynomial commitment ยท commit ยท open ยท verify without the polynomial
    Brakedown F_p ยท Ikat R_q ยท Binius Fโ‚‚ยนยฒโธ ยท Porphyry F_q ยท Assayer (min,+)
\x1b[0m
  lens commit <file>                    commit a file, print 32-byte root
  lens open   <file> <point...> [-o f]  open at a point, write proof
  lens verify <commitment> <proof>      verify an opening (no file)
  lens open-batch <file> <points-file>  amortize many openings into one proof
  lens eval   <file> <point...>         evaluate, no proof (ground truth)
  lens check  <file>                    commit + open + verify, print PASS/FAIL
  lens params                           construction parameters
  lens vectors                          print test vectors (JSON)
  lens assayer <problem.json> [-o f]    solve tropical problem, emit witness
  lens assayer-verify <commit> <proof>  verify tropical witness
\x1b[90m
  algos:    brakedown  ikat  binius  porphyry   (default: brakedown)
  points:   decimal or hex (0x prefix), one field element per coordinate
  flags:    --algo <name>   select construction
            --vars N        synthetic 2^N polynomial (check)
            -o <file>       write proof to file
\x1b[0m
  -h, --help  Print this help"
    );
}

Homonyms

cyberia/src/main.rs
soft3/glia/import/main.rs
soft3/tru/cli/main.rs
warriors/trisha/cli/main.rs
soft3/nox/cli/main.rs
cyb/optica/src/main.rs
neural/trident/src/main.rs
cyb/src-tauri/src/main.rs
neural/rune/cli/main.rs
cyb/cyb-boot/src/main.rs
cyb/cyb/cyb-portal/src/main.rs
soft3/zheng/cli/src/main.rs
soft3/radio/radio-cli/src/main.rs
neural/rs/rsc/src/main.rs
cyb/cyb/cyb-ui/src/main.rs
soft3/bbg/cli/src/main.rs
neural/eidos/cli/src/main.rs
soft3/cybergraph/cli/src/main.rs
soft3/radio/particle/src/main.rs
neural/rs/cli/src/main.rs
cyb/cyb/cyb-shell/src/main.rs
neural/rs/link/src/main.rs
soft3/radio/iroh-relay/src/main.rs
soft3/hemera/cli/src/main.rs
soft3/foculus/src/bin/main.rs
neural/rs/macho-linker/src/main.rs
neural/rs/pure-rust-check/src/main.rs
soft3/radio/iroh-dns-server/src/main.rs
soft3/glia/run/cli/main.rs
soft3/strata/jali/cli/src/main.rs
bootloader/go-cyber/mcp/rust/src/main.rs
soft3/strata/nebu/cli/src/main.rs
cyb/wysm/crates/cli/src/main.rs
soft3/strata/trop/cli/src/main.rs
neural/inf/rs/cli/src/main.rs
cyb/honeycrisp/rane/src/probe/main.rs
soft3/strata/kuro/cli/src/main.rs
soft3/strata/genies/cli/src/main.rs
cyb/honeycrisp/acpu/src/probe/main.rs
cyb/honeycrisp/unimem/experiments/iosurface_probe/src/main.rs
cyb/honeycrisp/unimem/experiments/hyp_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