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()));
}
}
}
}
|