aboutsummaryrefslogtreecommitdiff
path: root/zkvms/zkwasm/host/src/main.rs
blob: 6a2350444f326ab07504a89f78873f40fdde4761 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::io::{self, Write};
use std::process::{Command, Stdio};
use zkvms_host_io::{
    benchmarkable, foreach_private_input_field, foreach_public_input_field, read_args,
    PrivateInput, PublicInput,
    RunType::{Execute, Prove, Verify},
    RunWith,
    output_proof_size_raw,
};

static PUBLIC_INPUT_PATH: &str = "public_input.bin";
static PRIVATE_INPUT_PATH: &str = "private_input.bin";

/// Creates an anonymous function which takes `run_info`, "serializes" the
/// specified input, outputs it into a file and returns a "path:<PATH>"
/// argument, ready to be passed to zkWasm.
///
/// The macro takes three arguments: run_info input expression, path for file
/// output and the name of a foreach macro.
///
/// For collection types, first the size is emitted and afterwards its actual
/// values.
macro_rules! build_input {
    ($input:expr , $path:ident , $type:ident) => {
        |run_info: &RunWith| {
            let mut all = Vec::new();
            $type! {
                all.extend(tobytes::to_bytes!($input.yield));
            }
            let bytes = all
                .into_iter()
                .map(|x: u64| x.to_be_bytes())
                .flatten()
                .collect::<Vec<u8>>();
            std::fs::write($path, bytes);
            format!("{}:file", $path)
        }
    };
}

fn zkwasm_command(subcmd: &str) -> Command {
    let mut command = Command::new("zkwasm-cli");
    command
        .arg("--params")
        .arg("./params")
        .arg("prog")
        .arg(subcmd)
        .arg("--wasm")
        .arg(env!("GUEST_PATH"));
    command
}

fn run(cmd: &mut Command) {
    assert!(cmd.status().expect("couldn't execute command!").success());
}

fn main() {
    let run_info = read_args();

    let k = run_info.env_or("ZKWASM_K", "19");

    let scheme = run_info.env_or("ZKWASM_SCHEME", "shplonk");

    run(zkwasm_command("setup")
        .arg("-k")
        .arg(k)
        .arg("--scheme")
        .arg(scheme));

    let public_input = build_input!(
        run_info.public_input,
        PUBLIC_INPUT_PATH,
        foreach_public_input_field
    )(&run_info);

    let private_input = build_input!(
        run_info.private_input,
        PRIVATE_INPUT_PATH,
        foreach_private_input_field
    )(&run_info);

    let output = run_info.env_or("ZKWASM_OUTPUT", "./output");

    let params = run_info.env_or("ZKWASM_PARAMS", "./params");

    match run_info.run_type {
        Execute => benchmarkable! {
            run(zkwasm_command("dry-run")
                .arg("--public").arg(public_input.clone())
                .arg("--private").arg(private_input.clone())
                .arg("--output").arg(output.clone()));
        },
        Prove => benchmarkable! {
            run(zkwasm_command("prove")
                .arg("--public").arg(public_input.clone())
                .arg("--private").arg(private_input.clone())
                .arg("--output").arg(output.clone()));

            let proofSize = std::fs::metadata(output.clone() + "/prog.0.transcript.data").unwrap().len();
            output_proof_size_raw(proofSize as usize);
        },
        Verify => {
            run(zkwasm_command("prove")
                .arg("--public")
                .arg(public_input)
                .arg("--private")
                .arg(private_input)
                .arg("--output")
                .arg(output.clone()));

            let proofSize = std::fs::metadata(output.clone() + "/prog.0.transcript.data").unwrap().len();
            output_proof_size_raw(proofSize as usize);

            benchmarkable! {
                run(Command::new("zkwasm-cli")
                    .arg("--params").arg(params.clone())
                    .arg("prog").arg("verify")
                    .arg("--output").arg(output.clone()));
            }
        }
    }
}