Merge pull request #235 from Zokrates/clean-cli-hints
Clean CLI hints and error handling
This commit is contained in:
commit
6e7d368a74
5 changed files with 143 additions and 158 deletions
|
@ -3,6 +3,7 @@ name = "zokrates_cli"
|
|||
version = "0.3.3"
|
||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>", "Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||
repository = "https://github.com/JacobEberhardt/ZoKrates.git"
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = ["libsnark"]
|
||||
|
|
|
@ -4,13 +4,6 @@
|
|||
// @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
// @date 2017
|
||||
|
||||
extern crate bincode;
|
||||
extern crate clap;
|
||||
extern crate regex;
|
||||
extern crate zokrates_core;
|
||||
extern crate zokrates_field;
|
||||
extern crate zokrates_fs_resolver;
|
||||
|
||||
use bincode::{deserialize_from, serialize_into, Infinite};
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
#[cfg(feature = "libsnark")]
|
||||
|
@ -29,16 +22,14 @@ use zokrates_core::proof_system::{ProofSystem, GM17, PGHR13};
|
|||
use zokrates_field::field::{Field, FieldPrime};
|
||||
use zokrates_fs_resolver::resolve as fs_resolve;
|
||||
|
||||
#[cfg(feature = "libsnark")]
|
||||
fn get_backend(backend_str: &str) -> &'static ProofSystem {
|
||||
match backend_str.to_lowercase().as_ref() {
|
||||
"pghr13" => &PGHR13 {},
|
||||
"gm17" => &GM17 {},
|
||||
s => panic!("Backend \"{}\" not supported", s),
|
||||
}
|
||||
fn main() {
|
||||
cli().unwrap_or_else(|e| {
|
||||
println!("{}", e);
|
||||
std::process::exit(1);
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn cli() -> Result<(), String> {
|
||||
const FLATTENED_CODE_DEFAULT_PATH: &str = "out";
|
||||
const VERIFICATION_KEY_DEFAULT_PATH: &str = "verification.key";
|
||||
const PROVING_KEY_DEFAULT_PATH: &str = "proving.key";
|
||||
|
@ -55,18 +46,18 @@ fn main() {
|
|||
.author("Jacob Eberhardt, Thibaut Schaeffer, Dennis Kuhnert")
|
||||
.about("Supports generation of zkSNARKs from high level language code including Smart Contracts for proof verification on the Ethereum Blockchain.\n'I know that I show nothing!'")
|
||||
.subcommand(SubCommand::with_name("compile")
|
||||
.about("Compiles into flattened conditions. Produces two files: human-readable '.code' file and binary file")
|
||||
.about("Compiles into flattened conditions. Produces two files: human-readable '.code' file for debugging and binary file")
|
||||
.arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("path of source code file to compile.")
|
||||
.help("Path of the source code")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
).arg(Arg::with_name("output")
|
||||
.short("o")
|
||||
.long("output")
|
||||
.help("output file path.")
|
||||
.help("Path of the output file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -78,11 +69,11 @@ fn main() {
|
|||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("setup")
|
||||
.about("Performs a trusted setup for a given constraint system.")
|
||||
.about("Performs a trusted setup for a given constraint system")
|
||||
.arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("path of compiled code.")
|
||||
.help("Path of compiled code")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -91,7 +82,7 @@ fn main() {
|
|||
.arg(Arg::with_name("proving-key-path")
|
||||
.short("p")
|
||||
.long("proving-key-path")
|
||||
.help("Path of the generated proving key file.")
|
||||
.help("Path of the generated proving key file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -100,7 +91,7 @@ fn main() {
|
|||
.arg(Arg::with_name("verification-key-path")
|
||||
.short("v")
|
||||
.long("verification-key-path")
|
||||
.help("Path of the generated verification key file.")
|
||||
.help("Path of the generated verification key file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -109,7 +100,7 @@ fn main() {
|
|||
.arg(Arg::with_name("meta-information")
|
||||
.short("m")
|
||||
.long("meta-information")
|
||||
.help("Path of file containing meta information for variable transformation.")
|
||||
.help("Path of the file containing meta-information for variable transformation")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -126,11 +117,11 @@ fn main() {
|
|||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("export-verifier")
|
||||
.about("Exports a verifier as Solidity smart contract.")
|
||||
.about("Exports a verifier as Solidity smart contract")
|
||||
.arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("path of verifier.")
|
||||
.help("Path of the verifier")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -139,7 +130,7 @@ fn main() {
|
|||
.arg(Arg::with_name("output")
|
||||
.short("o")
|
||||
.long("output")
|
||||
.help("output file path.")
|
||||
.help("Path of the output file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -155,11 +146,11 @@ fn main() {
|
|||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("compute-witness")
|
||||
.about("Calculates a witness for a given constraint system, i.e., a variable assignment which satisfies all constraints. Private inputs are specified interactively.")
|
||||
.about("Calculates a witness for a given constraint system")
|
||||
.arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("path of compiled code.")
|
||||
.help("Path of compiled code")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -167,7 +158,7 @@ fn main() {
|
|||
).arg(Arg::with_name("output")
|
||||
.short("o")
|
||||
.long("output")
|
||||
.help("output file path.")
|
||||
.help("Path of the output file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -175,13 +166,13 @@ fn main() {
|
|||
).arg(Arg::with_name("arguments")
|
||||
.short("a")
|
||||
.long("arguments")
|
||||
.help("Arguments for the program's main method. Space separated list.")
|
||||
.help("Arguments for the program's main method as a space separated list")
|
||||
.takes_value(true)
|
||||
.multiple(true) // allows multiple values
|
||||
.required(false)
|
||||
).arg(Arg::with_name("interactive")
|
||||
.long("interactive")
|
||||
.help("enter private inputs interactively.")
|
||||
.help("Enter private inputs interactively. Public inputs still need to be passed non-interactively")
|
||||
.required(false)
|
||||
)
|
||||
)
|
||||
|
@ -190,7 +181,7 @@ fn main() {
|
|||
.arg(Arg::with_name("witness")
|
||||
.short("w")
|
||||
.long("witness")
|
||||
.help("Path of witness file.")
|
||||
.help("Path of the witness file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -198,7 +189,7 @@ fn main() {
|
|||
).arg(Arg::with_name("provingkey")
|
||||
.short("p")
|
||||
.long("provingkey")
|
||||
.help("Path of proving key file.")
|
||||
.help("Path of the proving key file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -206,7 +197,7 @@ fn main() {
|
|||
).arg(Arg::with_name("proofpath")
|
||||
.short("j")
|
||||
.long("proofpath")
|
||||
.help("Path of the json proof file")
|
||||
.help("Path of the JSON proof file")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -214,7 +205,7 @@ fn main() {
|
|||
).arg(Arg::with_name("meta-information")
|
||||
.short("i")
|
||||
.long("meta-information")
|
||||
.help("Path of file containing meta information for variable transformation.")
|
||||
.help("Path of file containing meta information for variable transformation")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
|
@ -256,34 +247,31 @@ fn main() {
|
|||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_flattened: ir::Prog<FieldPrime> =
|
||||
match compile(&mut reader, Some(location), Some(fs_resolve)) {
|
||||
Ok(p) => p,
|
||||
Err(why) => panic!("Compilation failed: {}", why),
|
||||
};
|
||||
compile(&mut reader, Some(location), Some(fs_resolve))
|
||||
.map_err(|e| format!("Compilation failed: {}", e))?;
|
||||
|
||||
// number of constraints the flattened program will translate to.
|
||||
let num_constraints = program_flattened.constraint_count();
|
||||
|
||||
// serialize flattened program and write to binary file
|
||||
let mut bin_output_file = match File::create(&bin_output_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't create {}: {}", bin_output_path.display(), why),
|
||||
};
|
||||
let mut bin_output_file = File::create(&bin_output_path)
|
||||
.map_err(|why| format!("couldn't create {}: {}", bin_output_path.display(), why))?;
|
||||
|
||||
serialize_into(&mut bin_output_file, &program_flattened, Infinite)
|
||||
.expect("Unable to write data to file.");
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
|
||||
if !light {
|
||||
// write human-readable output file
|
||||
let hr_output_file = match File::create(&hr_output_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't create {}: {}", hr_output_path.display(), why),
|
||||
};
|
||||
let hr_output_file = File::create(&hr_output_path).map_err(|why| {
|
||||
format!("couldn't create {}: {}", hr_output_path.display(), why)
|
||||
})?;
|
||||
|
||||
let mut hrofb = BufWriter::new(hr_output_file);
|
||||
write!(&mut hrofb, "{}\n", program_flattened)
|
||||
.expect("Unable to write data to file.");
|
||||
hrofb.flush().expect("Unable to flush buffer.");
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
hrofb
|
||||
.flush()
|
||||
.map_err(|_| "Unable to flush buffer.".to_string())?;
|
||||
}
|
||||
|
||||
if !light {
|
||||
|
@ -304,34 +292,21 @@ fn main() {
|
|||
|
||||
// read compiled program
|
||||
let path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let mut file = match File::open(&path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", path.display(), why),
|
||||
};
|
||||
let mut file = File::open(&path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", path.display(), why))?;
|
||||
|
||||
let program_ast: ir::Prog<FieldPrime> = match deserialize_from(&mut file, Infinite) {
|
||||
Ok(x) => x,
|
||||
Err(why) => {
|
||||
println!("{:?}", why);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let program_ast: ir::Prog<FieldPrime> =
|
||||
deserialize_from(&mut file, Infinite).map_err(|why| why.to_string())?;
|
||||
|
||||
// print deserialized flattened program
|
||||
println!("{}", program_ast);
|
||||
|
||||
// validate #arguments
|
||||
let mut cli_arguments: Vec<FieldPrime> = Vec::new();
|
||||
match sub_matches.values_of("arguments") {
|
||||
Some(p) => {
|
||||
let arg_strings: Vec<&str> = p.collect();
|
||||
cli_arguments = arg_strings
|
||||
.into_iter()
|
||||
.map(|x| FieldPrime::from(x))
|
||||
.collect();
|
||||
}
|
||||
None => {}
|
||||
let cli_arguments = match sub_matches.values_of("arguments") {
|
||||
Some(p) => p.map(|x| FieldPrime::try_from_str(x)).collect(),
|
||||
None => Ok(vec![]),
|
||||
}
|
||||
.map_err(|_| "Could not parse arguments".to_string())?;
|
||||
|
||||
// handle interactive and non-interactive modes
|
||||
let is_interactive = sub_matches.occurrences_of("interactive") > 0;
|
||||
|
@ -344,12 +319,11 @@ fn main() {
|
|||
};
|
||||
|
||||
if cli_arguments.len() != expected_cli_args_count {
|
||||
println!(
|
||||
return Err(format!(
|
||||
"Wrong number of arguments. Given: {}, Required: {}.",
|
||||
cli_arguments.len(),
|
||||
expected_cli_args_count
|
||||
);
|
||||
std::process::exit(1);
|
||||
));
|
||||
}
|
||||
|
||||
let mut cli_arguments_iter = cli_arguments.into_iter();
|
||||
|
@ -359,62 +333,64 @@ fn main() {
|
|||
.map(|x| {
|
||||
match x.private && is_interactive {
|
||||
// private inputs are passed interactively when the flag is present
|
||||
true => {
|
||||
true => loop {
|
||||
println!("Please enter a value for {:?}:", x.id);
|
||||
let mut input = String::new();
|
||||
let stdin = stdin();
|
||||
stdin
|
||||
.lock()
|
||||
.read_line(&mut input)
|
||||
.expect("Did not enter a correct String");
|
||||
FieldPrime::from(input.trim())
|
||||
}
|
||||
// otherwise, they are taken from the CLI arguments
|
||||
false => match cli_arguments_iter.next() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
std::process::exit(1);
|
||||
}
|
||||
let r = stdin.lock().read_line(&mut input);
|
||||
|
||||
match r {
|
||||
Ok(_) => {
|
||||
let input = input.trim();
|
||||
match FieldPrime::try_from_str(&input) {
|
||||
Ok(v) => return v,
|
||||
Err(_) => {
|
||||
println!("Not a correct String, try again");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
println!("Not a correct String, try again");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
},
|
||||
// otherwise, they are taken from the CLI arguments
|
||||
false => cli_arguments_iter.next().unwrap(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let witness = program_ast
|
||||
.execute(&arguments)
|
||||
.unwrap_or_else(|e| panic!(format!("Execution failed: {}", e)));
|
||||
.map_err(|e| format!("Execution failed: {}", e))?;
|
||||
|
||||
println!("\nWitness: \n\n{}", witness.format_outputs());
|
||||
|
||||
// write witness to file
|
||||
let output_path = Path::new(sub_matches.value_of("output").unwrap());
|
||||
let output_file = match File::create(&output_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't create {}: {}", output_path.display(), why),
|
||||
};
|
||||
let output_file = File::create(&output_path)
|
||||
.map_err(|why| format!("couldn't create {}: {}", output_path.display(), why))?;
|
||||
|
||||
let mut bw = BufWriter::new(output_file);
|
||||
write!(&mut bw, "{}", witness).expect("Unable to write data to file.");
|
||||
bw.flush().expect("Unable to flush buffer.");
|
||||
write!(&mut bw, "{}", witness)
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
bw.flush()
|
||||
.map_err(|_| "Unable to flush buffer.".to_string())?;
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
("setup", Some(sub_matches)) => {
|
||||
let backend = get_backend(sub_matches.value_of("backend").unwrap())?;
|
||||
|
||||
println!("Performing setup...");
|
||||
|
||||
let backend = get_backend(sub_matches.value_of("backend").unwrap());
|
||||
|
||||
let path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let mut file = match File::open(&path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", path.display(), why),
|
||||
};
|
||||
let mut file = File::open(&path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", path.display(), why))?;
|
||||
|
||||
let program: ir::Prog<FieldPrime> = match deserialize_from(&mut file, Infinite) {
|
||||
Ok(x) => x,
|
||||
Err(why) => {
|
||||
println!("{:?}", why);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let program: ir::Prog<FieldPrime> =
|
||||
deserialize_from(&mut file, Infinite).map_err(|why| format!("{:?}", why))?;
|
||||
|
||||
// print deserialized flattened program
|
||||
println!("{}", program);
|
||||
|
@ -424,10 +400,8 @@ fn main() {
|
|||
|
||||
// write variables meta information to file
|
||||
let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap());
|
||||
let var_inf_file = match File::create(&var_inf_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", var_inf_path.display(), why),
|
||||
};
|
||||
let var_inf_file = File::create(&var_inf_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", var_inf_path.display(), why))?;
|
||||
let mut bw = BufWriter::new(var_inf_file);
|
||||
|
||||
write!(
|
||||
|
@ -435,14 +409,17 @@ fn main() {
|
|||
"Private inputs offset:\n{}\n",
|
||||
public_variables_count
|
||||
)
|
||||
.expect("Unable to write data to file.");
|
||||
write!(&mut bw, "R1CS variable order:\n").expect("Unable to write data to file.");
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
write!(&mut bw, "R1CS variable order:\n")
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
|
||||
for var in &variables {
|
||||
write!(&mut bw, "{} ", var).expect("Unable to write data to file.");
|
||||
write!(&mut bw, "{} ", var)
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
}
|
||||
write!(&mut bw, "\n").expect("Unable to write data to file.");
|
||||
bw.flush().expect("Unable to flush buffer.");
|
||||
write!(&mut bw, "\n").map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
bw.flush()
|
||||
.map_err(|_| "Unable to flush buffer.".to_string())?;
|
||||
|
||||
// get paths for proving and verification keys
|
||||
let pk_path = sub_matches.value_of("proving-key-path").unwrap();
|
||||
|
@ -466,30 +443,26 @@ fn main() {
|
|||
#[cfg(feature = "libsnark")]
|
||||
("export-verifier", Some(sub_matches)) => {
|
||||
{
|
||||
println!("Exporting verifier...");
|
||||
let backend = get_backend(sub_matches.value_of("backend").unwrap())?;
|
||||
|
||||
let backend = get_backend(sub_matches.value_of("backend").unwrap());
|
||||
println!("Exporting verifier...");
|
||||
|
||||
// read vk file
|
||||
let input_path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let input_file = match File::open(&input_path) {
|
||||
Ok(input_file) => input_file,
|
||||
Err(why) => panic!("couldn't open {}: {}", input_path.display(), why),
|
||||
};
|
||||
let input_file = File::open(&input_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", input_path.display(), why))?;
|
||||
let reader = BufReader::new(input_file);
|
||||
|
||||
let verifier = backend.export_solidity_verifier(reader);
|
||||
|
||||
//write output file
|
||||
let output_path = Path::new(sub_matches.value_of("output").unwrap());
|
||||
let mut output_file = match File::create(&output_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't create {}: {}", output_path.display(), why),
|
||||
};
|
||||
let mut output_file = File::create(&output_path)
|
||||
.map_err(|why| format!("couldn't create {}: {}", output_path.display(), why))?;
|
||||
|
||||
output_file
|
||||
.write_all(&verifier.as_bytes())
|
||||
.expect("Failed writing output to file.");
|
||||
.map_err(|_| "Failed writing output to file.".to_string())?;
|
||||
println!("Finished exporting verifier.");
|
||||
}
|
||||
}
|
||||
|
@ -497,14 +470,12 @@ fn main() {
|
|||
("generate-proof", Some(sub_matches)) => {
|
||||
println!("Generating proof...");
|
||||
|
||||
let backend = get_backend(sub_matches.value_of("backend").unwrap());
|
||||
let backend = get_backend(sub_matches.value_of("backend").unwrap())?;
|
||||
|
||||
// deserialize witness
|
||||
let witness_path = Path::new(sub_matches.value_of("witness").unwrap());
|
||||
let witness_file = match File::open(&witness_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", witness_path.display(), why),
|
||||
};
|
||||
let witness_file = File::open(&witness_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", witness_path.display(), why))?;
|
||||
|
||||
let reader = BufReader::new(witness_file);
|
||||
let mut lines = reader.lines();
|
||||
|
@ -520,16 +491,14 @@ fn main() {
|
|||
);
|
||||
}
|
||||
None => break,
|
||||
Some(Err(err)) => panic!("Error reading witness: {}", err),
|
||||
Some(Err(err)) => return Err(format!("Error reading witness: {}", err)),
|
||||
}
|
||||
}
|
||||
|
||||
// determine variable order
|
||||
let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap());
|
||||
let var_inf_file = match File::open(&var_inf_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", var_inf_path.display(), why),
|
||||
};
|
||||
let var_inf_file = File::open(&var_inf_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", var_inf_path.display(), why))?;
|
||||
let var_reader = BufReader::new(var_inf_file);
|
||||
let mut var_lines = var_reader.lines();
|
||||
|
||||
|
@ -537,9 +506,11 @@ fn main() {
|
|||
let private_inputs_offset;
|
||||
if let Some(Ok(ref o)) = var_lines.nth(1) {
|
||||
// consumes first 2 lines
|
||||
private_inputs_offset = o.parse().expect("Failed parsing private inputs offset");
|
||||
private_inputs_offset = o
|
||||
.parse()
|
||||
.map_err(|_| "Failed parsing private inputs offset")?;
|
||||
} else {
|
||||
panic!("Error reading private inputs offset");
|
||||
return Err(format!("Error reading private inputs offset"));
|
||||
}
|
||||
|
||||
// get variables vector
|
||||
|
@ -550,7 +521,7 @@ fn main() {
|
|||
variables.push(i.to_string());
|
||||
}
|
||||
} else {
|
||||
panic!("Error reading variables.");
|
||||
return Err(format!("Error reading variables"));
|
||||
}
|
||||
|
||||
println!("Using Witness: {:?}", witness_map);
|
||||
|
@ -573,7 +544,17 @@ fn main() {
|
|||
backend.generate_proof(pk_path, proof_path, public_inputs, private_inputs)
|
||||
);
|
||||
}
|
||||
_ => unimplemented!(), // Either no subcommand or one not tested for...
|
||||
_ => unreachable!(),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "libsnark")]
|
||||
fn get_backend(backend_str: &str) -> Result<&'static ProofSystem, String> {
|
||||
match backend_str.to_lowercase().as_ref() {
|
||||
"pghr13" => Ok(&PGHR13 {}),
|
||||
"gm17" => Ok(&GM17 {}),
|
||||
s => Err(format!("Backend \"{}\" not supported", s)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -117,9 +117,10 @@ mod tests {
|
|||
)
|
||||
.unwrap()
|
||||
.to_bytes_le(),
|
||||
FieldPrime::from(
|
||||
FieldPrime::try_from_str(
|
||||
"5472060717959818805561601436314318772174077789324455915672259473661306552146"
|
||||
)
|
||||
.unwrap()
|
||||
.into_byte_vector()
|
||||
);
|
||||
}
|
||||
|
@ -128,15 +129,16 @@ mod tests {
|
|||
fn serialization_bin() {
|
||||
assert_eq!(
|
||||
BigUint::parse_bytes(b"110000011001000100111001110010111000010011000110100000001010011011100001010000010001011011011010000001100000010101100001011101100101111000000101101010100100010110100001110001110010101000110100111100001000001000110000010110110110000111110011111101010010",2).unwrap().to_bytes_le(),
|
||||
FieldPrime::from("5472060717959818805561601436314318772174077789324455915672259473661306552146").into_byte_vector()
|
||||
FieldPrime::try_from_str("5472060717959818805561601436314318772174077789324455915672259473661306552146").unwrap().into_byte_vector()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vec_to_array() {
|
||||
let byte_vector: Vec<u8> = FieldPrime::from(
|
||||
let byte_vector: Vec<u8> = FieldPrime::try_from_str(
|
||||
"5472060717959818805561601436314318772174077789324455915672259473661306552146",
|
||||
)
|
||||
.unwrap()
|
||||
.into_byte_vector();
|
||||
let array: [u8; 32] = vec_as_u8_32_array(&byte_vector);
|
||||
for (index, value) in byte_vector.iter().enumerate() {
|
||||
|
|
|
@ -16,7 +16,7 @@ pub fn parse_num<T: Field>(input: &String, pos: &Position) -> (Token<T>, String,
|
|||
}
|
||||
assert!(end > 0);
|
||||
(
|
||||
Token::Num(T::from(&input[0..end])),
|
||||
Token::Num(T::try_from_str(&input[0..end]).unwrap()),
|
||||
input[end..].to_string(),
|
||||
Position {
|
||||
line: pos.line,
|
||||
|
|
|
@ -32,7 +32,6 @@ pub trait Field:
|
|||
From<i32>
|
||||
+ From<u32>
|
||||
+ From<usize>
|
||||
+ for<'a> From<&'a str>
|
||||
+ Zero
|
||||
+ One
|
||||
+ Clone
|
||||
|
@ -70,6 +69,8 @@ pub trait Field:
|
|||
fn max_value() -> Self;
|
||||
/// Returns the number of required bits to represent this field type.
|
||||
fn get_required_bits() -> usize;
|
||||
/// Tries to parse a string into this representation
|
||||
fn try_from_str<'a>(s: &'a str) -> Result<Self, ()>;
|
||||
}
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
|
@ -122,6 +123,12 @@ impl Field for FieldPrime {
|
|||
fn get_required_bits() -> usize {
|
||||
(*P).bits()
|
||||
}
|
||||
fn try_from_str<'a>(s: &'a str) -> Result<Self, ()> {
|
||||
let x = BigInt::parse_bytes(s.as_bytes(), 10).ok_or(())?;
|
||||
Ok(FieldPrime {
|
||||
value: &x - x.div_floor(&*P) * &*P,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FieldPrime {
|
||||
|
@ -171,18 +178,6 @@ impl From<usize> for FieldPrime {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for FieldPrime {
|
||||
fn from(s: &'a str) -> Self {
|
||||
let x = match BigInt::parse_bytes(s.as_bytes(), 10) {
|
||||
Some(x) => x,
|
||||
None => panic!("Could not parse {:?} to BigInt!", &s),
|
||||
};
|
||||
FieldPrime {
|
||||
value: &x - x.div_floor(&*P) * &*P,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Zero for FieldPrime {
|
||||
fn zero() -> FieldPrime {
|
||||
FieldPrime {
|
||||
|
@ -353,6 +348,12 @@ fn extended_euclid(a: &BigInt, b: &BigInt) -> (BigInt, BigInt, BigInt) {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
impl<'a> From<&'a str> for FieldPrime {
|
||||
fn from(s: &'a str) -> FieldPrime {
|
||||
FieldPrime::try_from_str(s).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod field_prime {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in a new issue