integrate with backend api, activate with --backend g16
This commit is contained in:
commit
b0e8b9d042
21 changed files with 337 additions and 390 deletions
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -3,7 +3,7 @@ name = "aho-corasick"
|
|||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -83,7 +83,7 @@ dependencies = [
|
|||
"ff 0.5.0 (git+https://github.com/matterinc/ff)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pairing 0.15.2 (git+https://github.com/matterinc/pairing)",
|
||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -330,7 +330,7 @@ version = "0.1.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -440,12 +440,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.1.3"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
|
@ -523,7 +519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.9.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -735,7 +731,7 @@ dependencies = [
|
|||
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -770,7 +766,7 @@ version = "0.2.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1089,7 +1085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_cli"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
dependencies = [
|
||||
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1097,14 +1093,14 @@ dependencies = [
|
|||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zokrates_core 0.3.5",
|
||||
"zokrates_core 0.3.6",
|
||||
"zokrates_field 0.3.2",
|
||||
"zokrates_fs_resolver 0.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zokrates_core"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
dependencies = [
|
||||
"assert_cli 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bellman 0.1.3 (git+https://github.com/matterinc/bellman)",
|
||||
|
@ -1210,7 +1206,7 @@ dependencies = [
|
|||
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
|
||||
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
||||
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||
"checksum memchr 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1dd4eaac298c32ce07eb6ed9242eda7d82955b9170b7d6db59b2e02cc63fcb8"
|
||||
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
|
@ -1221,7 +1217,7 @@ dependencies = [
|
|||
"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124"
|
||||
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238"
|
||||
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)" = "1bb974e77de925ef426b6bc82fce15fd45bdcbeb5728bffcfc7cdeeb7ce1c2d6"
|
||||
"checksum pairing 0.15.2 (git+https://github.com/matterinc/pairing)" = "<none>"
|
||||
|
|
1
proof.json
Normal file
1
proof.json
Normal file
|
@ -0,0 +1 @@
|
|||
˜2°J«—ִגי*דמEָt—„<EFBFBD>S9ֻ“"ֹrפWחw™״{1
תל
ה%ע>•כ®ְpsמqtA)§בD<EFBFBD>Zװ>ƒד€M?„<EFBFBD>h..´Vה<EFBFBD>C}÷†”[¨p°5<EFBFBD>U¬NGHרI½—{>ְװ¦™<EFBFBD>י<EFBFBD>05<EFBFBD>0OLד`\ןj
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_cli"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
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"
|
||||
|
@ -16,11 +16,11 @@ regex = "0.2"
|
|||
zokrates_field = { version = "0.3", path = "../zokrates_field" }
|
||||
zokrates_core = { version = "0.3", path = "../zokrates_core" }
|
||||
zokrates_fs_resolver = { version = "0.4", path = "../zokrates_fs_resolver"}
|
||||
serde_json = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.2.11"
|
||||
assert_cli = "0.5"
|
||||
serde_json = "1.0"
|
||||
|
||||
[[bin]]
|
||||
name = "zokrates"
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
use bincode::{deserialize_from, serialize_into, Infinite};
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
#[cfg(feature = "libsnark")]
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, BufWriter, Write};
|
||||
|
@ -15,10 +13,7 @@ use std::path::{Path, PathBuf};
|
|||
use std::string::String;
|
||||
use zokrates_core::compile::compile;
|
||||
use zokrates_core::ir;
|
||||
#[cfg(feature = "libsnark")]
|
||||
use zokrates_core::ir::r1cs_program;
|
||||
#[cfg(feature = "libsnark")]
|
||||
use zokrates_core::proof_system::{ProofSystem, GM17, PGHR13};
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_field::field::{Field, FieldPrime};
|
||||
use zokrates_fs_resolver::resolve as fs_resolve;
|
||||
|
||||
|
@ -42,7 +37,7 @@ fn cli() -> Result<(), String> {
|
|||
// cli specification using clap library
|
||||
let matches = App::new("ZoKrates")
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.version("0.4.1")
|
||||
.version("0.4.2")
|
||||
.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")
|
||||
|
@ -202,8 +197,16 @@ fn cli() -> Result<(), String> {
|
|||
.takes_value(true)
|
||||
.required(false)
|
||||
.default_value(JSON_PROOF_PATH)
|
||||
).arg(Arg::with_name("meta-information")
|
||||
).arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("Path of compiled code")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
.default_value(FLATTENED_CODE_DEFAULT_PATH)
|
||||
).arg(Arg::with_name("meta-information")
|
||||
.short("m")
|
||||
.long("meta-information")
|
||||
.help("Path of file containing meta information for variable transformation")
|
||||
.value_name("FILE")
|
||||
|
@ -373,13 +376,18 @@ fn cli() -> Result<(), String> {
|
|||
let output_file = File::create(&output_path)
|
||||
.map_err(|why| format!("couldn't create {}: {}", output_path.display(), why))?;
|
||||
|
||||
//println!("{:?}", witness);
|
||||
|
||||
let mut bw = BufWriter::new(output_file);
|
||||
write!(&mut bw, "{}", witness)
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
write!(
|
||||
&mut bw,
|
||||
"{}",
|
||||
&serde_json::to_string_pretty(&ir::WitnessVec::from(witness)).unwrap()
|
||||
)
|
||||
.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())?;
|
||||
|
||||
|
@ -395,8 +403,13 @@ fn cli() -> Result<(), String> {
|
|||
// print deserialized flattened program
|
||||
println!("{}", program);
|
||||
|
||||
// transform to R1CS
|
||||
let (variables, public_variables_count, a, b, c) = r1cs_program(program);
|
||||
// get paths for proving and verification keys
|
||||
let pk_path = sub_matches.value_of("proving-key-path").unwrap();
|
||||
let vk_path = sub_matches.value_of("verification-key-path").unwrap();
|
||||
|
||||
// run setup phase
|
||||
// number of inputs in the zkSNARK sense, i.e., input variables + output variables
|
||||
let metadata = backend.setup(program, pk_path, vk_path);
|
||||
|
||||
// write variables meta information to file
|
||||
let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap());
|
||||
|
@ -406,41 +419,13 @@ fn cli() -> Result<(), String> {
|
|||
|
||||
write!(
|
||||
&mut bw,
|
||||
"Private inputs offset:\n{}\n",
|
||||
public_variables_count
|
||||
"{}",
|
||||
&serde_json::to_string_pretty(&metadata).unwrap()
|
||||
)
|
||||
.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)
|
||||
.map_err(|_| "Unable to write data to file.".to_string())?;
|
||||
}
|
||||
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();
|
||||
let vk_path = sub_matches.value_of("verification-key-path").unwrap();
|
||||
|
||||
// run setup phase
|
||||
// number of inputs in the zkSNARK sense, i.e., input variables + output variables
|
||||
println!(
|
||||
"setup successful: {:?}",
|
||||
backend.setup(
|
||||
variables,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
public_variables_count - 1,
|
||||
pk_path,
|
||||
vk_path
|
||||
)
|
||||
);
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
("export-verifier", Some(sub_matches)) => {
|
||||
{
|
||||
let backend = get_backend(sub_matches.value_of("backend").unwrap())?;
|
||||
|
@ -466,7 +451,6 @@ fn cli() -> Result<(), String> {
|
|||
println!("Finished exporting verifier.");
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
("generate-proof", Some(sub_matches)) => {
|
||||
println!("Generating proof...");
|
||||
|
||||
|
@ -474,74 +458,43 @@ fn cli() -> Result<(), String> {
|
|||
|
||||
// deserialize witness
|
||||
let witness_path = Path::new(sub_matches.value_of("witness").unwrap());
|
||||
let witness_file = File::open(&witness_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", witness_path.display(), why))?;
|
||||
let witness_file = match File::open(&witness_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", witness_path.display(), why),
|
||||
};
|
||||
|
||||
let reader = BufReader::new(witness_file);
|
||||
let mut lines = reader.lines();
|
||||
let mut witness_map = HashMap::new();
|
||||
let witness: ir::WitnessVec<FieldPrime> =
|
||||
serde_json::from_reader(BufReader::new(witness_file)).unwrap();
|
||||
|
||||
loop {
|
||||
match lines.next() {
|
||||
Some(Ok(ref x)) => {
|
||||
let pairs: Vec<&str> = x.split_whitespace().collect();
|
||||
witness_map.insert(
|
||||
pairs[0].to_string(),
|
||||
FieldPrime::from_dec_string(pairs[1].to_string()),
|
||||
);
|
||||
}
|
||||
None => break,
|
||||
Some(Err(err)) => return Err(format!("Error reading witness: {}", err)),
|
||||
}
|
||||
}
|
||||
let witness = ir::Witness::from(witness);
|
||||
|
||||
// determine variable order
|
||||
let var_inf_path = Path::new(sub_matches.value_of("meta-information").unwrap());
|
||||
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();
|
||||
println!("Using Witness: {}", witness);
|
||||
|
||||
// get private inputs offset
|
||||
let private_inputs_offset;
|
||||
if let Some(Ok(ref o)) = var_lines.nth(1) {
|
||||
// consumes first 2 lines
|
||||
private_inputs_offset = o
|
||||
.parse()
|
||||
.map_err(|_| "Failed parsing private inputs offset")?;
|
||||
} else {
|
||||
return Err(format!("Error reading private inputs offset"));
|
||||
}
|
||||
// deserialize metadata
|
||||
let metadata_path = Path::new(sub_matches.value_of("meta-information").unwrap());
|
||||
|
||||
// get variables vector
|
||||
let mut variables: Vec<String> = Vec::new();
|
||||
if let Some(Ok(ref v)) = var_lines.nth(1) {
|
||||
let iter = v.split_whitespace();
|
||||
for i in iter {
|
||||
variables.push(i.to_string());
|
||||
}
|
||||
} else {
|
||||
return Err(format!("Error reading variables"));
|
||||
}
|
||||
let metadata_file = match File::open(&metadata_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", metadata_path.display(), why),
|
||||
};
|
||||
|
||||
println!("Using Witness: {:?}", witness_map);
|
||||
|
||||
let witness: Vec<_> = variables.iter().map(|x| witness_map[x].clone()).collect();
|
||||
|
||||
// split witness into public and private inputs at offset
|
||||
let mut public_inputs: Vec<_> = witness.clone();
|
||||
let private_inputs: Vec<_> = public_inputs.split_off(private_inputs_offset);
|
||||
|
||||
println!("Public inputs: {:?}", public_inputs);
|
||||
println!("Private inputs: {:?}", private_inputs);
|
||||
let metadata: Metadata =
|
||||
serde_json::from_reader(BufReader::new(metadata_file)).unwrap();
|
||||
|
||||
let pk_path = sub_matches.value_of("provingkey").unwrap();
|
||||
let proof_path = sub_matches.value_of("proofpath").unwrap();
|
||||
|
||||
let program_path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let mut program_file = File::open(&program_path)
|
||||
.map_err(|why| format!("couldn't open {}: {}", program_path.display(), why))?;
|
||||
|
||||
let program: ir::Prog<FieldPrime> = deserialize_from(&mut program_file, Infinite)
|
||||
.map_err(|why| format!("{:?}", why))?;
|
||||
|
||||
// run libsnark
|
||||
println!(
|
||||
"generate-proof successful: {:?}",
|
||||
backend.generate_proof(pk_path, proof_path, public_inputs, private_inputs)
|
||||
backend.generate_proof(program, witness, metadata, pk_path, proof_path)
|
||||
);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -549,11 +502,13 @@ fn cli() -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "libsnark")]
|
||||
fn get_backend(backend_str: &str) -> Result<&'static ProofSystem, String> {
|
||||
match backend_str.to_lowercase().as_ref() {
|
||||
#[cfg(feature = "libsnark")]
|
||||
"pghr13" => Ok(&PGHR13 {}),
|
||||
#[cfg(feature = "libsnark")]
|
||||
"gm17" => Ok(&GM17 {}),
|
||||
"g16" => Ok(&G16 {}),
|
||||
s => Err(format!("Backend \"{}\" not supported", s)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,11 +199,13 @@ mod integration {
|
|||
assert_cli::Assert::command(&[
|
||||
"../target/release/zokrates",
|
||||
"generate-proof",
|
||||
"-i",
|
||||
flattened_path.to_str().unwrap(),
|
||||
"-w",
|
||||
witness_path.to_str().unwrap(),
|
||||
"-p",
|
||||
proving_key_path.to_str().unwrap(),
|
||||
"-i",
|
||||
"-m",
|
||||
variable_information_path.to_str().unwrap(),
|
||||
"--backend",
|
||||
backend,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_core"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>"]
|
||||
repository = "https://github.com/JacobEberhardt/ZoKrates"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -49,7 +49,6 @@ impl Flattener {
|
|||
fn load_corelib<T: Field>(&mut self, functions_flattened: &mut Vec<FlatFunction<T>>) -> () {
|
||||
// Load type casting functions
|
||||
functions_flattened.push(cast(&Type::Boolean, &Type::FieldElement));
|
||||
functions_flattened.push(cast(&Type::FieldElement, &Type::Boolean));
|
||||
|
||||
// Load IfElse helper
|
||||
let ie = TypedFunction {
|
||||
|
|
|
@ -72,7 +72,7 @@ fn alloc<CS: ConstraintSystem<Bn256>>(
|
|||
witness: &Witness<FieldPrime>,
|
||||
) -> Result<Variable, SynthesisError> {
|
||||
match var.is_output() {
|
||||
true => cs.alloc(
|
||||
true => cs.alloc_input(
|
||||
|| format!("{}", var),
|
||||
|| {
|
||||
// let w = witness.ok_or(SynthesisError::AssignmentMissing)?;
|
||||
|
@ -83,7 +83,7 @@ fn alloc<CS: ConstraintSystem<Bn256>>(
|
|||
Ok(Fr::from(val.clone()))
|
||||
},
|
||||
),
|
||||
false => cs.alloc_input(
|
||||
false => cs.alloc(
|
||||
|| format!("{}", var),
|
||||
|| {
|
||||
// let witness = witness.ok_or(SynthesisError::AssignmentMissing)?;
|
||||
|
@ -107,7 +107,7 @@ impl Prog<FieldPrime> {
|
|||
|
||||
let mut arguments = vec![];
|
||||
|
||||
let witness = witness.unwrap();
|
||||
let witness = witness.unwrap_or(Witness::empty());
|
||||
|
||||
for (index, (var, private)) in self
|
||||
.main
|
||||
|
@ -178,6 +178,39 @@ impl Prog<FieldPrime> {
|
|||
}
|
||||
|
||||
impl Computation<FieldPrime> {
|
||||
pub fn prove(self, params: Parameters<Bn256>) -> Proof<Bn256> {
|
||||
let rng = &mut thread_rng();
|
||||
let proof = create_random_proof(self.clone(), ¶ms, rng).unwrap();
|
||||
|
||||
let pvk = prepare_verifying_key(¶ms.vk);
|
||||
|
||||
// extract public inputs
|
||||
let public_inputs: Vec<Fr> = self
|
||||
.program
|
||||
.main
|
||||
.arguments
|
||||
.clone()
|
||||
.iter()
|
||||
.zip(self.program.private.clone())
|
||||
.filter(|(_, p)| !p)
|
||||
.map(|(a, _)| a)
|
||||
.chain(
|
||||
self.witness
|
||||
.clone()
|
||||
.unwrap()
|
||||
.0
|
||||
.keys()
|
||||
.filter(|k| k.is_output()),
|
||||
)
|
||||
.map(|v| self.witness.clone().unwrap().0.get(v).unwrap().clone())
|
||||
.map(|v| Fr::from(v.clone()))
|
||||
.collect();
|
||||
|
||||
assert!(verify_proof(&pvk, &proof, &public_inputs).unwrap());
|
||||
|
||||
proof
|
||||
}
|
||||
|
||||
pub fn setup_prove_verify(self) -> Proof<Bn256> {
|
||||
// run setup phase
|
||||
let params = self.clone().setup();
|
||||
|
@ -285,7 +318,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn empty_program() {
|
||||
fn empty() {
|
||||
let program: Prog<FieldPrime> = Prog {
|
||||
main: Function {
|
||||
id: String::from("main"),
|
||||
|
@ -301,6 +334,54 @@ mod tests {
|
|||
|
||||
let _proof = computation.setup_prove_verify();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn identity() {
|
||||
let program: Prog<FieldPrime> = Prog {
|
||||
main: Function {
|
||||
id: String::from("main"),
|
||||
arguments: vec![FlatVariable::new(0)],
|
||||
returns: vec![FlatVariable::public(0)],
|
||||
statements: vec![Statement::Constraint(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatVariable::public(0).into(),
|
||||
)],
|
||||
},
|
||||
private: vec![true],
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(0)])
|
||||
.unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let _proof = computation.setup_prove_verify();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_identity() {
|
||||
let program: Prog<FieldPrime> = Prog {
|
||||
main: Function {
|
||||
id: String::from("main"),
|
||||
arguments: vec![FlatVariable::new(0)],
|
||||
returns: vec![FlatVariable::public(0)],
|
||||
statements: vec![Statement::Constraint(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatVariable::public(0).into(),
|
||||
)],
|
||||
},
|
||||
private: vec![false],
|
||||
};
|
||||
|
||||
let witness = program
|
||||
.clone()
|
||||
.execute::<FieldPrime>(&vec![FieldPrime::from(0)])
|
||||
.unwrap();
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let _proof = computation.setup_prove_verify();
|
||||
}
|
||||
}
|
||||
|
||||
mod serialize {
|
||||
|
|
|
@ -18,7 +18,11 @@ impl<T: Field> From<FlatFunction<T>> for Function<T> {
|
|||
Function {
|
||||
id: flat_function.id,
|
||||
arguments: flat_function.arguments.into_iter().map(|p| p.id).collect(),
|
||||
returns: return_expressions.into_iter().map(|e| e.into()).collect(),
|
||||
returns: return_expressions
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, _)| FlatVariable::public(index))
|
||||
.collect(),
|
||||
statements: flat_function
|
||||
.statements
|
||||
.into_iter()
|
||||
|
@ -26,6 +30,17 @@ impl<T: Field> From<FlatFunction<T>> for Function<T> {
|
|||
FlatStatement::Return(..) => None,
|
||||
s => Some(s.into()),
|
||||
})
|
||||
.chain(
|
||||
return_expressions
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, expression)| {
|
||||
Statement::Constraint(
|
||||
expression.into(),
|
||||
FlatVariable::public(index).into(),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
@ -43,25 +58,8 @@ impl<T: Field> From<FlatProg<T>> for Prog<T> {
|
|||
// get the interface of the program, ie which inputs are private and public
|
||||
let private = main.arguments.iter().map(|p| p.private).collect();
|
||||
|
||||
// convert the main function to this IR for functions
|
||||
let main: Function<T> = main.into();
|
||||
let main = main.into();
|
||||
|
||||
// contrary to other functions, we need to make sure that return values are identifiers, so we define new (public) variables
|
||||
let definitions =
|
||||
main.returns.iter().enumerate().map(|(index, e)| {
|
||||
Statement::Constraint(e.clone(), FlatVariable::public(index).into())
|
||||
});
|
||||
|
||||
// update the main function with the extra definition statements and replace the return values
|
||||
let main = Function {
|
||||
returns: (0..main.returns.len())
|
||||
.map(|i| FlatVariable::public(i).into())
|
||||
.collect(),
|
||||
statements: main.statements.into_iter().chain(definitions).collect(),
|
||||
..main
|
||||
};
|
||||
|
||||
let main = Function::from(main);
|
||||
Prog { private, main }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,21 @@ use zokrates_field::field::Field;
|
|||
|
||||
pub type ExecutionResult<T> = Result<Witness<T>, Error>;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct WitnessVec<T: Field>(Vec<(FlatVariable, T)>);
|
||||
|
||||
impl<T: Field> From<Witness<T>> for WitnessVec<T> {
|
||||
fn from(w: Witness<T>) -> WitnessVec<T> {
|
||||
WitnessVec(w.0.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> From<WitnessVec<T>> for Witness<T> {
|
||||
fn from(w: WitnessVec<T>) -> Witness<T> {
|
||||
Witness(w.0.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Witness<T: Field>(pub BTreeMap<FlatVariable, T>);
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::fmt;
|
|||
use std::mem;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
mod backend;
|
||||
pub mod backend;
|
||||
mod expression;
|
||||
mod from_flat;
|
||||
mod interpreter;
|
||||
|
@ -14,8 +14,7 @@ mod interpreter;
|
|||
use self::expression::LinComb;
|
||||
use self::expression::QuadComb;
|
||||
|
||||
pub use self::interpreter::Error;
|
||||
pub use self::interpreter::ExecutionResult;
|
||||
pub use self::interpreter::{Error, ExecutionResult, Witness, WitnessVec};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub enum Statement<T: Field> {
|
||||
|
@ -64,7 +63,7 @@ pub struct Function<T: Field> {
|
|||
pub id: String,
|
||||
pub statements: Vec<Statement<T>>,
|
||||
pub arguments: Vec<FlatVariable>,
|
||||
pub returns: Vec<QuadComb<T>>,
|
||||
pub returns: Vec<FlatVariable>,
|
||||
}
|
||||
|
||||
impl<T: Field> fmt::Display for Function<T> {
|
||||
|
|
|
@ -41,5 +41,5 @@ pub mod flat_absy;
|
|||
pub mod ir;
|
||||
#[cfg(feature = "libsnark")]
|
||||
pub mod libsnark;
|
||||
#[cfg(feature = "libsnark")]
|
||||
// #[cfg(feature = "libsnark")]
|
||||
pub mod proof_system;
|
||||
|
|
47
zokrates_core/src/proof_system/bn128/g16.rs
Normal file
47
zokrates_core/src/proof_system/bn128/g16.rs
Normal file
|
@ -0,0 +1,47 @@
|
|||
use bellman::groth16::Parameters;
|
||||
use ir;
|
||||
use ir::backend::Computation;
|
||||
use proof_system::Metadata;
|
||||
use proof_system::ProofSystem;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
pub struct G16 {}
|
||||
impl ProofSystem for G16 {
|
||||
fn setup(&self, program: ir::Prog<FieldPrime>, pk_path: &str, _vk_path: &str) -> Metadata {
|
||||
let parameters = Computation::without_witness(program).setup();
|
||||
let parameters_file = File::create(PathBuf::from(pk_path)).unwrap();
|
||||
parameters.write(parameters_file).unwrap();
|
||||
// TODO write pk, vk to files
|
||||
Metadata {
|
||||
offset: 42,
|
||||
variables: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_proof(
|
||||
&self,
|
||||
program: ir::Prog<FieldPrime>,
|
||||
witness: ir::Witness<FieldPrime>,
|
||||
_metadata: Metadata,
|
||||
pk_path: &str,
|
||||
proof_path: &str,
|
||||
) -> bool {
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
let parameters_file = File::open(PathBuf::from(pk_path)).unwrap();
|
||||
|
||||
let params = Parameters::read(parameters_file, true).unwrap();
|
||||
|
||||
let proof = computation.prove(params);
|
||||
|
||||
let proof_file = File::create(PathBuf::from(proof_path)).unwrap();
|
||||
proof.write(proof_file).unwrap();
|
||||
true
|
||||
}
|
||||
|
||||
fn export_solidity_verifier(&self, reader: BufReader<File>) -> String {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
extern crate libc;
|
||||
|
||||
use self::libc::{c_char, c_int, uint8_t};
|
||||
use flat_absy::flat_variable::FlatVariable;
|
||||
use ir;
|
||||
use proof_system::utils::{
|
||||
prepare_generate_proof, prepare_setup, SOLIDITY_G2_ADDITION_LIB, SOLIDITY_PAIRING_LIB,
|
||||
};
|
||||
use proof_system::ProofSystem;
|
||||
use proof_system::{Metadata, ProofSystem};
|
||||
use regex::Regex;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
@ -46,16 +46,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
impl ProofSystem for GM17 {
|
||||
fn setup(
|
||||
&self,
|
||||
variables: Vec<FlatVariable>,
|
||||
a: Vec<Vec<(usize, FieldPrime)>>,
|
||||
b: Vec<Vec<(usize, FieldPrime)>>,
|
||||
c: Vec<Vec<(usize, FieldPrime)>>,
|
||||
num_inputs: usize,
|
||||
pk_path: &str,
|
||||
vk_path: &str,
|
||||
) -> bool {
|
||||
fn setup(&self, program: ir::Prog<FieldPrime>, pk_path: &str, vk_path: &str) -> Metadata {
|
||||
let (
|
||||
a_arr,
|
||||
b_arr,
|
||||
|
@ -68,7 +59,8 @@ impl ProofSystem for GM17 {
|
|||
num_inputs,
|
||||
pk_path_cstring,
|
||||
vk_path_cstring,
|
||||
) = prepare_setup(variables, a, b, c, num_inputs, pk_path, vk_path);
|
||||
metadata,
|
||||
) = prepare_setup(program, pk_path, vk_path);
|
||||
|
||||
unsafe {
|
||||
_gm17_setup(
|
||||
|
@ -83,32 +75,35 @@ impl ProofSystem for GM17 {
|
|||
num_inputs as i32,
|
||||
pk_path_cstring.as_ptr(),
|
||||
vk_path_cstring.as_ptr(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
metadata
|
||||
}
|
||||
|
||||
fn generate_proof(
|
||||
&self,
|
||||
_: ir::Prog<FieldPrime>,
|
||||
witness: ir::Witness<FieldPrime>,
|
||||
metadata: Metadata,
|
||||
pk_path: &str,
|
||||
proof_path: &str,
|
||||
publquery_inputs: Vec<FieldPrime>,
|
||||
private_inputs: Vec<FieldPrime>,
|
||||
) -> bool {
|
||||
let (
|
||||
pk_path_cstring,
|
||||
proof_path_cstring,
|
||||
publquery_inputs_arr,
|
||||
publquery_inputs_length,
|
||||
public_inputs_arr,
|
||||
public_inputs_length,
|
||||
private_inputs_arr,
|
||||
private_inputs_length,
|
||||
) = prepare_generate_proof(pk_path, proof_path, publquery_inputs, private_inputs);
|
||||
) = prepare_generate_proof(pk_path, proof_path, witness, metadata);
|
||||
|
||||
unsafe {
|
||||
_gm17_generate_proof(
|
||||
pk_path_cstring.as_ptr(),
|
||||
proof_path_cstring.as_ptr(),
|
||||
publquery_inputs_arr[0].as_ptr(),
|
||||
publquery_inputs_length as i32,
|
||||
public_inputs_arr[0].as_ptr(),
|
||||
public_inputs_length as i32,
|
||||
private_inputs_arr[0].as_ptr(),
|
||||
private_inputs_length as i32,
|
||||
)
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
mod g16;
|
||||
#[cfg(feature = "libsnark")]
|
||||
mod gm17;
|
||||
#[cfg(feature = "libsnark")]
|
||||
mod pghr13;
|
||||
|
||||
pub use self::g16::G16;
|
||||
#[cfg(feature = "libsnark")]
|
||||
pub use self::gm17::GM17;
|
||||
#[cfg(feature = "libsnark")]
|
||||
pub use self::pghr13::PGHR13;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
extern crate libc;
|
||||
|
||||
use self::libc::{c_char, c_int, uint8_t};
|
||||
use flat_absy::flat_variable::FlatVariable;
|
||||
use ir;
|
||||
use proof_system::utils::{
|
||||
prepare_generate_proof, prepare_setup, SOLIDITY_G2_ADDITION_LIB, SOLIDITY_PAIRING_LIB,
|
||||
};
|
||||
use proof_system::ProofSystem;
|
||||
use proof_system::{Metadata, ProofSystem};
|
||||
|
||||
use regex::Regex;
|
||||
use std::fs::File;
|
||||
|
@ -47,16 +47,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
impl ProofSystem for PGHR13 {
|
||||
fn setup(
|
||||
&self,
|
||||
variables: Vec<FlatVariable>,
|
||||
a: Vec<Vec<(usize, FieldPrime)>>,
|
||||
b: Vec<Vec<(usize, FieldPrime)>>,
|
||||
c: Vec<Vec<(usize, FieldPrime)>>,
|
||||
num_inputs: usize,
|
||||
pk_path: &str,
|
||||
vk_path: &str,
|
||||
) -> bool {
|
||||
fn setup(&self, program: ir::Prog<FieldPrime>, pk_path: &str, vk_path: &str) -> Metadata {
|
||||
let (
|
||||
a_arr,
|
||||
b_arr,
|
||||
|
@ -69,7 +60,8 @@ impl ProofSystem for PGHR13 {
|
|||
num_inputs,
|
||||
pk_path_cstring,
|
||||
vk_path_cstring,
|
||||
) = prepare_setup(variables, a, b, c, num_inputs, pk_path, vk_path);
|
||||
metadata,
|
||||
) = prepare_setup(program, pk_path, vk_path);
|
||||
|
||||
unsafe {
|
||||
_pghr13_setup(
|
||||
|
@ -84,16 +76,19 @@ impl ProofSystem for PGHR13 {
|
|||
num_inputs as i32,
|
||||
pk_path_cstring.as_ptr(),
|
||||
vk_path_cstring.as_ptr(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
metadata
|
||||
}
|
||||
|
||||
fn generate_proof(
|
||||
&self,
|
||||
_: ir::Prog<FieldPrime>,
|
||||
witness: ir::Witness<FieldPrime>,
|
||||
metadata: Metadata,
|
||||
pk_path: &str,
|
||||
proof_path: &str,
|
||||
public_inputs: Vec<FieldPrime>,
|
||||
private_inputs: Vec<FieldPrime>,
|
||||
) -> bool {
|
||||
let (
|
||||
pk_path_cstring,
|
||||
|
@ -102,7 +97,7 @@ impl ProofSystem for PGHR13 {
|
|||
public_inputs_length,
|
||||
private_inputs_arr,
|
||||
private_inputs_length,
|
||||
) = prepare_generate_proof(pk_path, proof_path, public_inputs, private_inputs);
|
||||
) = prepare_generate_proof(pk_path, proof_path, witness, metadata);
|
||||
|
||||
unsafe {
|
||||
_pghr13_generate_proof(
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
mod bn128;
|
||||
#[cfg(feature = "libsnark")]
|
||||
mod utils;
|
||||
|
||||
use flat_absy::flat_variable::FlatVariable;
|
||||
use std::fs::File;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
pub use self::bn128::G16;
|
||||
#[cfg(feature = "libsnark")]
|
||||
pub use self::bn128::GM17;
|
||||
#[cfg(feature = "libsnark")]
|
||||
pub use self::bn128::PGHR13;
|
||||
use flat_absy::flat_variable::FlatVariable;
|
||||
|
||||
use ir;
|
||||
use std::io::BufReader;
|
||||
|
||||
pub trait ProofSystem {
|
||||
fn setup(
|
||||
&self,
|
||||
variables: Vec<FlatVariable>,
|
||||
a: Vec<Vec<(usize, FieldPrime)>>,
|
||||
b: Vec<Vec<(usize, FieldPrime)>>,
|
||||
c: Vec<Vec<(usize, FieldPrime)>>,
|
||||
num_inputs: usize,
|
||||
pk_path: &str,
|
||||
vk_path: &str,
|
||||
) -> bool;
|
||||
fn setup(&self, program: ir::Prog<FieldPrime>, pk_path: &str, vk_path: &str) -> Metadata;
|
||||
|
||||
fn generate_proof(
|
||||
&self,
|
||||
program: ir::Prog<FieldPrime>,
|
||||
witness: ir::Witness<FieldPrime>,
|
||||
metadata: Metadata,
|
||||
pk_path: &str,
|
||||
proof_path: &str,
|
||||
public_inputs: Vec<FieldPrime>,
|
||||
private_inputs: Vec<FieldPrime>,
|
||||
) -> bool;
|
||||
|
||||
fn export_solidity_verifier(&self, reader: BufReader<File>) -> String;
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Metadata {
|
||||
offset: usize,
|
||||
variables: Vec<FlatVariable>,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use flat_absy::flat_variable::FlatVariable;
|
||||
use ir;
|
||||
use proof_system::Metadata;
|
||||
use std::cmp::max;
|
||||
use std::ffi::CString;
|
||||
use zokrates_field::field::Field;
|
||||
|
@ -15,11 +17,7 @@ fn vec_as_u8_32_array(vec: &Vec<u8>) -> [u8; 32] {
|
|||
|
||||
// proof-system-independent preparation for the setup phase
|
||||
pub fn prepare_setup<T: Field>(
|
||||
variables: Vec<FlatVariable>,
|
||||
a: Vec<Vec<(usize, T)>>,
|
||||
b: Vec<Vec<(usize, T)>>,
|
||||
c: Vec<Vec<(usize, T)>>,
|
||||
num_inputs: usize,
|
||||
program: ir::Prog<T>,
|
||||
pk_path: &str,
|
||||
vk_path: &str,
|
||||
) -> (
|
||||
|
@ -34,10 +32,21 @@ pub fn prepare_setup<T: Field>(
|
|||
usize,
|
||||
CString,
|
||||
CString,
|
||||
Metadata,
|
||||
) {
|
||||
// transform to R1CS
|
||||
let (variables, public_variables_count, a, b, c) = ir::r1cs_program(program);
|
||||
|
||||
let num_inputs = public_variables_count - 1;
|
||||
|
||||
let num_constraints = a.len();
|
||||
let num_variables = variables.len();
|
||||
|
||||
let metadata = Metadata {
|
||||
offset: public_variables_count,
|
||||
variables,
|
||||
};
|
||||
|
||||
// Create single A,B,C vectors of tuples (constraint_number, variable_id, variable_value)
|
||||
let mut a_vec = vec![];
|
||||
let mut b_vec = vec![];
|
||||
|
@ -142,6 +151,7 @@ pub fn prepare_setup<T: Field>(
|
|||
num_inputs,
|
||||
pk_path_cstring,
|
||||
vk_path_cstring,
|
||||
metadata,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -149,9 +159,19 @@ pub fn prepare_setup<T: Field>(
|
|||
pub fn prepare_generate_proof<T: Field>(
|
||||
pk_path: &str,
|
||||
proof_path: &str,
|
||||
public_inputs: Vec<T>,
|
||||
private_inputs: Vec<T>,
|
||||
witness: ir::Witness<T>,
|
||||
metadata: Metadata,
|
||||
) -> (CString, CString, Vec<[u8; 32]>, usize, Vec<[u8; 32]>, usize) {
|
||||
let witness: Vec<_> = metadata
|
||||
.variables
|
||||
.iter()
|
||||
.map(|x| witness.0[x].clone())
|
||||
.collect();
|
||||
|
||||
// split witness into public and private inputs at offset
|
||||
let mut public_inputs: Vec<_> = witness.clone();
|
||||
let private_inputs: Vec<_> = public_inputs.split_off(metadata.offset);
|
||||
|
||||
let pk_path_cstring = CString::new(pk_path).unwrap();
|
||||
let proof_path_cstring = CString::new(proof_path).unwrap();
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
use zokrates_field::field::Field;
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Debug)]
|
||||
pub struct Constraints<T: Field> {
|
||||
pub constraints: Vec<Constraint<T>>,
|
||||
}
|
||||
|
||||
impl<T: Field> Constraints<T> {
|
||||
pub fn none() -> Constraints<T> {
|
||||
Constraints {
|
||||
constraints: vec![],
|
||||
}
|
||||
}
|
||||
pub fn boolean() -> Constraints<T> {
|
||||
Constraints {
|
||||
constraints: vec![Constraint {
|
||||
a: box [T::from(1)],
|
||||
b: box [T::from(1)],
|
||||
c: box [T::from(1)],
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Debug)]
|
||||
pub struct Constraint<T: Field> {
|
||||
pub a: Box<[T]>,
|
||||
pub b: Box<[T]>,
|
||||
pub c: Box<[T]>,
|
||||
}
|
|
@ -3,8 +3,6 @@ use flat_absy::flat_parameter::FlatParameter;
|
|||
use flat_absy::flat_variable::FlatVariable;
|
||||
use flat_absy::*;
|
||||
use helpers::{DirectiveStatement, Helper};
|
||||
use reduce::Reduce;
|
||||
use types::constraints::Constraint;
|
||||
use types::signature::Signature;
|
||||
use types::Type;
|
||||
use zokrates_field::field::Field;
|
||||
|
@ -167,94 +165,24 @@ pub fn cast<T: Field>(from: &Type, to: &Type) -> FlatFunction<T> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let directive_inputs = (0..from.get_primitive_count())
|
||||
let binding_inputs: Vec<_> = (0..from.get_primitive_count())
|
||||
.map(|index| use_variable(&mut bijection, format!("i{}", index), &mut counter))
|
||||
.collect();
|
||||
let directive_outputs: Vec<FlatVariable> = (0..to.get_primitive_count())
|
||||
let binding_outputs: Vec<FlatVariable> = (0..to.get_primitive_count())
|
||||
.map(|index| use_variable(&mut bijection, format!("o{}", index), &mut counter))
|
||||
.collect();
|
||||
|
||||
let constraints = to.get_constraints::<T>().constraints;
|
||||
|
||||
let intermediate_variables = match constraints.len() {
|
||||
0 => vec![],
|
||||
_ => constraints[0]
|
||||
.a
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(_, index)| use_variable(&mut bijection, format!("inter{}", index), &mut counter))
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let conditions: Vec<FlatStatement<T>> = to
|
||||
.get_constraints()
|
||||
.constraints
|
||||
let outputs = binding_outputs
|
||||
.iter()
|
||||
.map(|constraint: &Constraint<T>| {
|
||||
let rhs_a = match constraint
|
||||
.a
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(key, val)| {
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(val.clone()),
|
||||
box FlatExpression::Identifier(intermediate_variables[key]),
|
||||
)
|
||||
})
|
||||
.reduce(|acc, e| FlatExpression::Add(box acc, box e))
|
||||
{
|
||||
Some(e @ FlatExpression::Mult(..)) => {
|
||||
FlatExpression::Add(box FlatExpression::Number(T::zero()), box e)
|
||||
} // the R1CS serializer only recognizes Add
|
||||
Some(e) => e,
|
||||
None => FlatExpression::Number(T::zero()),
|
||||
};
|
||||
|
||||
let rhs_b = match constraint
|
||||
.b
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(key, val)| {
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(val.clone()),
|
||||
box FlatExpression::Identifier(intermediate_variables[key]),
|
||||
)
|
||||
})
|
||||
.reduce(|acc, e| FlatExpression::Add(box acc, box e))
|
||||
{
|
||||
Some(e @ FlatExpression::Mult(..)) => {
|
||||
FlatExpression::Add(box FlatExpression::Number(T::zero()), box e)
|
||||
} // the R1CS serializer only recognizes Add
|
||||
Some(e) => e,
|
||||
None => FlatExpression::Number(T::zero()),
|
||||
};
|
||||
|
||||
let lhs = match constraint
|
||||
.c
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(key, val)| {
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(val.clone()),
|
||||
box FlatExpression::Identifier(intermediate_variables[key]),
|
||||
)
|
||||
})
|
||||
.reduce(|acc, e| FlatExpression::Add(box acc, box e))
|
||||
{
|
||||
Some(e @ FlatExpression::Mult(..)) => {
|
||||
FlatExpression::Add(box FlatExpression::Number(T::zero()), box e)
|
||||
} // the R1CS serializer only recognizes Add
|
||||
Some(e) => e,
|
||||
None => FlatExpression::Number(T::zero()),
|
||||
};
|
||||
|
||||
FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
|
||||
})
|
||||
.map(|o| FlatExpression::Identifier(o.clone()))
|
||||
.collect();
|
||||
|
||||
let helper = match (from, to) {
|
||||
(Type::Boolean, Type::FieldElement) => Helper::identity(),
|
||||
(Type::FieldElement, Type::Boolean) => Helper::identity(),
|
||||
let bindings: Vec<_> = match (from, to) {
|
||||
(Type::Boolean, Type::FieldElement) => binding_outputs
|
||||
.into_iter()
|
||||
.zip(binding_inputs.into_iter())
|
||||
.map(|(o, i)| FlatStatement::Definition(o, i.into()))
|
||||
.collect(),
|
||||
_ => panic!(format!("can't cast {} to {}", from, to)),
|
||||
};
|
||||
|
||||
|
@ -263,26 +191,13 @@ pub fn cast<T: Field>(from: &Type, to: &Type) -> FlatFunction<T> {
|
|||
outputs: vec![to.clone()],
|
||||
};
|
||||
|
||||
let outputs = directive_outputs
|
||||
.iter()
|
||||
.map(|o| FlatExpression::Identifier(o.clone()))
|
||||
let statements = bindings
|
||||
.into_iter()
|
||||
.chain(std::iter::once(FlatStatement::Return(FlatExpressionList {
|
||||
expressions: outputs,
|
||||
})))
|
||||
.collect();
|
||||
|
||||
let mut statements = conditions;
|
||||
|
||||
statements.insert(
|
||||
0,
|
||||
FlatStatement::Directive(DirectiveStatement::new(
|
||||
directive_outputs,
|
||||
helper,
|
||||
directive_inputs,
|
||||
)),
|
||||
);
|
||||
|
||||
statements.push(FlatStatement::Return(FlatExpressionList {
|
||||
expressions: outputs,
|
||||
}));
|
||||
|
||||
FlatFunction {
|
||||
id: format!("_{}_to_{}", from, to),
|
||||
arguments,
|
||||
|
@ -300,32 +215,6 @@ mod tests {
|
|||
mod cast {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn field_to_bool() {
|
||||
let f2b: FlatFunction<FieldPrime> = cast(&Type::FieldElement, &Type::Boolean);
|
||||
assert_eq!(f2b.id, String::from("_field_to_bool"));
|
||||
assert_eq!(
|
||||
f2b.arguments,
|
||||
vec![FlatParameter::private(FlatVariable::new(0))]
|
||||
);
|
||||
assert_eq!(f2b.statements.len(), 3); // 1 directive, 1 constraint, 1 return
|
||||
assert_eq!(
|
||||
f2b.statements[0],
|
||||
FlatStatement::Directive(DirectiveStatement::new(
|
||||
vec![FlatVariable::new(1)],
|
||||
Helper::identity(),
|
||||
vec![FlatVariable::new(0)]
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
f2b.statements[2],
|
||||
FlatStatement::Return(FlatExpressionList {
|
||||
expressions: vec![FlatExpression::Identifier(FlatVariable::new(1))]
|
||||
})
|
||||
);
|
||||
assert_eq!(f2b.signature.outputs.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bool_to_field() {
|
||||
let b2f: FlatFunction<FieldPrime> = cast(&Type::Boolean, &Type::FieldElement);
|
||||
|
@ -334,14 +223,10 @@ mod tests {
|
|||
b2f.arguments,
|
||||
vec![FlatParameter::private(FlatVariable::new(0))]
|
||||
);
|
||||
assert_eq!(b2f.statements.len(), 2); // 1 directive, 1 return
|
||||
assert_eq!(b2f.statements.len(), 2); // 1 definition, 1 return
|
||||
assert_eq!(
|
||||
b2f.statements[0],
|
||||
FlatStatement::Directive(DirectiveStatement::new(
|
||||
vec![FlatVariable::new(1)],
|
||||
Helper::identity(),
|
||||
vec![FlatVariable::new(0)]
|
||||
))
|
||||
FlatStatement::Definition(FlatVariable::new(1), FlatVariable::new(0).into())
|
||||
);
|
||||
assert_eq!(
|
||||
b2f.statements[1],
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use std::fmt;
|
||||
use types::constraints::Constraints;
|
||||
pub use types::signature::Signature;
|
||||
use zokrates_field::field::Field;
|
||||
|
||||
mod constraints;
|
||||
pub mod conversions;
|
||||
mod signature;
|
||||
|
||||
|
@ -35,14 +32,6 @@ impl fmt::Debug for Type {
|
|||
}
|
||||
|
||||
impl Type {
|
||||
fn get_constraints<T: Field>(&self) -> Constraints<T> {
|
||||
match self {
|
||||
Type::FieldElement => Constraints::none(),
|
||||
Type::Boolean => Constraints::boolean(),
|
||||
Type::FieldElementArray(_) => Type::FieldElement.get_constraints(),
|
||||
}
|
||||
}
|
||||
|
||||
// the number of field elements the type maps to
|
||||
pub fn get_primitive_count(&self) -> usize {
|
||||
match self {
|
||||
|
@ -64,21 +53,11 @@ impl Type {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use zokrates_field::field::FieldPrime;
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
let t = Type::FieldElementArray(42);
|
||||
assert_eq!(t.get_primitive_count(), 42);
|
||||
assert_eq!(t.get_constraints::<FieldPrime>(), Constraints::none());
|
||||
assert_eq!(t.to_slug(), "f[42]");
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn array_of_arrays() {
|
||||
// let t = Type::FieldElementArray(42, box Type::FieldElementArray(33, box Type::Boolean));
|
||||
// assert_eq!(t.get_primitive_count(), 1);
|
||||
// assert_eq!(t.get_constraints::<FieldPrime>(), Constraints::boolean());
|
||||
// assert_eq!(t.to_slug(), "[]");
|
||||
// }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue