commit
b0a0dd265f
29 changed files with 196 additions and 188 deletions
|
@ -30,7 +30,7 @@ echo "Published zokrates/zokrates:$TAG"
|
|||
# Release on Github
|
||||
git tag -f latest
|
||||
git tag $TAG
|
||||
git push origin --delete latest
|
||||
git push origin -f latest
|
||||
git push origin $TAG
|
||||
|
||||
# Build zokrates js
|
||||
|
|
|
@ -83,9 +83,6 @@ const options = {
|
|||
source: "def main() -> (): return",
|
||||
location: importLocation
|
||||
};
|
||||
},
|
||||
config: {
|
||||
is_release: true
|
||||
}
|
||||
};
|
||||
const artifacts = zokratesProvider.compile(source, options);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_cli"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
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"
|
||||
|
|
|
@ -19,7 +19,7 @@ use std::io::{stdin, BufReader, BufWriter, Read, Write};
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::string::String;
|
||||
use zokrates_abi::Encode;
|
||||
use zokrates_core::compile::{check, compile, CompilationArtifacts, CompileConfig, CompileError};
|
||||
use zokrates_core::compile::{check, compile, CompilationArtifacts, CompileError};
|
||||
use zokrates_core::ir::{self, ProgEnum};
|
||||
use zokrates_core::proof_system::bellman::groth16::G16;
|
||||
#[cfg(feature = "libsnark")]
|
||||
|
@ -274,8 +274,6 @@ fn cli_compile<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
|
||||
let hr_output_path = bin_output_path.to_path_buf().with_extension("ztf");
|
||||
|
||||
let is_release = sub_matches.occurrences_of("release") > 0;
|
||||
|
||||
let file = File::open(path.clone())
|
||||
.map_err(|why| format!("Couldn't open input file {}: {}", path.display(), why))?;
|
||||
|
||||
|
@ -294,11 +292,9 @@ fn cli_compile<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
)
|
||||
};
|
||||
|
||||
let compilation_config = CompileConfig::default().with_is_release(is_release);
|
||||
|
||||
let resolver = FileSystemResolver::new();
|
||||
let artifacts: CompilationArtifacts<T> =
|
||||
compile(source, path, Some(&resolver), &compilation_config).map_err(|e| {
|
||||
compile(source, path, Some(&resolver)).map_err(|e| {
|
||||
format!(
|
||||
"Compilation failed:\n\n{}",
|
||||
e.0.iter()
|
||||
|
@ -482,10 +478,6 @@ fn cli() -> Result<(), String> {
|
|||
.long("light")
|
||||
.help("Skip logs and human readable output")
|
||||
.required(false)
|
||||
).arg(Arg::with_name("release")
|
||||
.long("release")
|
||||
.help("Apply release optimisations to minimise constraint count. This increases compilation time.")
|
||||
.required(false)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("check")
|
||||
|
@ -1009,7 +1001,7 @@ mod tests {
|
|||
|
||||
let resolver = FileSystemResolver::new();
|
||||
let _: CompilationArtifacts<Bn128Field> =
|
||||
compile(source, path, Some(&resolver), &CompileConfig::default()).unwrap();
|
||||
compile(source, path, Some(&resolver)).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1031,7 +1023,7 @@ mod tests {
|
|||
|
||||
let resolver = FileSystemResolver::new();
|
||||
let artifacts: CompilationArtifacts<Bn128Field> =
|
||||
compile(source, path, Some(&resolver), &CompileConfig::default()).unwrap();
|
||||
compile(source, path, Some(&resolver)).unwrap();
|
||||
|
||||
let interpreter = ir::Interpreter::default();
|
||||
|
||||
|
@ -1060,7 +1052,7 @@ mod tests {
|
|||
|
||||
let resolver = FileSystemResolver::new();
|
||||
let artifacts: CompilationArtifacts<Bn128Field> =
|
||||
compile(source, path, Some(&resolver), &CompileConfig::default()).unwrap();
|
||||
compile(source, path, Some(&resolver)).unwrap();
|
||||
|
||||
let interpreter = ir::Interpreter::default();
|
||||
|
||||
|
|
1
zokrates_cli/tests/code/no_public.arguments.json
Normal file
1
zokrates_cli/tests/code/no_public.arguments.json
Normal file
|
@ -0,0 +1 @@
|
|||
[]
|
0
zokrates_cli/tests/code/no_public.expected.witness
Normal file
0
zokrates_cli/tests/code/no_public.expected.witness
Normal file
2
zokrates_cli/tests/code/no_public.zok
Normal file
2
zokrates_cli/tests/code/no_public.zok
Normal file
|
@ -0,0 +1,2 @@
|
|||
def main():
|
||||
return
|
|
@ -85,50 +85,32 @@ let jsonInterface = JSON.parse(solc.compile(jsonContractSource));
|
|||
}
|
||||
}
|
||||
|
||||
if (abiVersion == "v1") {
|
||||
if (format == "g16" || format == "gm17") {
|
||||
return verifyTxG16_GM17_ABIV1(proof, account, correct).on('receipt', handleReceipt)
|
||||
.catch(handleError);
|
||||
} else if (format == "pghr13") {
|
||||
return verifyTxPGHR13_ABIV1(proof, account, correct).on('receipt', handleReceipt)
|
||||
.catch(handleError);
|
||||
}
|
||||
} else {
|
||||
return verifyTxABIV2(proof, account, correct).on('receipt', handleReceipt)
|
||||
.catch(handleError);
|
||||
}
|
||||
return abiVersion == "v1" ?
|
||||
verifyTx_ABIV1(proof, account, correct).on('receipt', handleReceipt)
|
||||
.catch(handleError)
|
||||
:
|
||||
verifyTx_ABIV2(proof, account, correct).on('receipt', handleReceipt)
|
||||
.catch(handleError)
|
||||
}
|
||||
|
||||
function verifyTxABIV2(proof, account, correct) {
|
||||
contract.methods.verifyTx(proof[0], proof[1]).send({
|
||||
function verifyTx_ABIV2(proof, account, correct) {
|
||||
|
||||
var arguments = proof[0]
|
||||
arguments = proof[1].length > 0 ? [arguments[0], proof[1]] : arguments
|
||||
|
||||
contract.methods.verifyTx(...arguments).send({
|
||||
from: account,
|
||||
gas: 5000000
|
||||
})
|
||||
}
|
||||
|
||||
function verifyTxG16_GM17_ABIV1(proof, account, correct) {
|
||||
return contract.methods.verifyTx(
|
||||
proof[0][0],
|
||||
proof[0][1],
|
||||
proof[0][2],
|
||||
proof[1]
|
||||
).send({
|
||||
from: account,
|
||||
gas: 5000000
|
||||
})
|
||||
}
|
||||
function verifyTx_ABIV1(proof, account, correct) {
|
||||
|
||||
var arguments = proof[0]
|
||||
arguments = proof[1].length > 0 ? [...arguments, proof[1]] : arguments
|
||||
|
||||
function verifyTxPGHR13_ABIV1(proof, account, correct) {
|
||||
return contract.methods.verifyTx(
|
||||
proof[0][0],
|
||||
proof[0][1],
|
||||
proof[0][2],
|
||||
proof[0][3],
|
||||
proof[0][4],
|
||||
proof[0][5],
|
||||
proof[0][6],
|
||||
proof[0][7],
|
||||
proof[1]
|
||||
...arguments
|
||||
).send({
|
||||
from: account,
|
||||
gas: 5000000
|
||||
|
|
|
@ -163,11 +163,14 @@ mod integration {
|
|||
flattened_path.to_str().unwrap(),
|
||||
"-o",
|
||||
inline_witness_path.to_str().unwrap(),
|
||||
"-a",
|
||||
];
|
||||
|
||||
for arg in &inputs_raw {
|
||||
compute_inline.push(arg);
|
||||
if inputs_raw.len() > 0 {
|
||||
compute_inline.push("-a");
|
||||
|
||||
for arg in &inputs_raw {
|
||||
compute_inline.push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
assert_cli::Assert::command(&compute_inline)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_core"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>"]
|
||||
repository = "https://github.com/JacobEberhardt/ZoKrates"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -140,29 +140,12 @@ impl fmt::Display for CompileErrorInner {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct CompileConfig {
|
||||
is_release: bool,
|
||||
}
|
||||
|
||||
impl CompileConfig {
|
||||
pub fn with_is_release(mut self, is_release: bool) -> Self {
|
||||
self.is_release = is_release;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn is_release(&self) -> bool {
|
||||
self.is_release
|
||||
}
|
||||
}
|
||||
|
||||
type FilePath = PathBuf;
|
||||
|
||||
pub fn compile<T: Field, E: Into<imports::Error>>(
|
||||
source: String,
|
||||
location: FilePath,
|
||||
resolver: Option<&dyn Resolver<E>>,
|
||||
config: &CompileConfig,
|
||||
) -> Result<CompilationArtifacts<T>, CompileErrors> {
|
||||
let arena = Arena::new();
|
||||
|
||||
|
@ -178,7 +161,7 @@ pub fn compile<T: Field, E: Into<imports::Error>>(
|
|||
let ir_prog = ir::Prog::from(program_flattened);
|
||||
|
||||
// optimize
|
||||
let optimized_ir_prog = ir_prog.optimize(config);
|
||||
let optimized_ir_prog = ir_prog.optimize();
|
||||
|
||||
// analyse (check for unused constraints)
|
||||
let optimized_ir_prog = optimized_ir_prog.analyse();
|
||||
|
@ -280,7 +263,6 @@ mod test {
|
|||
source,
|
||||
"./path/to/file".into(),
|
||||
None::<&dyn Resolver<io::Error>>,
|
||||
&CompileConfig::default(),
|
||||
);
|
||||
assert!(res.unwrap_err().0[0]
|
||||
.value()
|
||||
|
@ -299,7 +281,6 @@ mod test {
|
|||
source,
|
||||
"./path/to/file".into(),
|
||||
None::<&dyn Resolver<io::Error>>,
|
||||
&CompileConfig::default(),
|
||||
);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
@ -380,7 +361,6 @@ struct Bar { field a }
|
|||
main.to_string(),
|
||||
"main".into(),
|
||||
Some(&CustomResolver),
|
||||
&CompileConfig::default(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ pub struct LinComb<T>(pub Vec<(FlatVariable, T)>);
|
|||
|
||||
impl<T: Field> PartialEq for LinComb<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.as_canonical() == other.as_canonical()
|
||||
self.clone().into_canonical() == other.clone().into_canonical()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,42 +152,51 @@ impl<T: Field> LinComb<T> {
|
|||
}
|
||||
|
||||
impl<T: Field> LinComb<T> {
|
||||
pub fn as_canonical(&self) -> CanonicalLinComb<T> {
|
||||
CanonicalLinComb(self.0.clone().into_iter().fold(
|
||||
BTreeMap::new(),
|
||||
|mut acc, (val, coeff)| {
|
||||
// if we're adding 0 times some variable, we can ignore this term
|
||||
if coeff != T::zero() {
|
||||
match acc.entry(val) {
|
||||
Entry::Occupied(o) => {
|
||||
// if the new value is non zero, update, else remove the term entirely
|
||||
if o.get().clone() + coeff.clone() != T::zero() {
|
||||
*o.into_mut() = o.get().clone() + coeff;
|
||||
} else {
|
||||
o.remove();
|
||||
pub fn into_canonical(self) -> CanonicalLinComb<T> {
|
||||
CanonicalLinComb(
|
||||
self.0
|
||||
.into_iter()
|
||||
.fold(BTreeMap::new(), |mut acc, (val, coeff)| {
|
||||
// if we're adding 0 times some variable, we can ignore this term
|
||||
if coeff != T::zero() {
|
||||
match acc.entry(val) {
|
||||
Entry::Occupied(o) => {
|
||||
// if the new value is non zero, update, else remove the term entirely
|
||||
if o.get().clone() + coeff.clone() != T::zero() {
|
||||
*o.into_mut() = o.get().clone() + coeff;
|
||||
} else {
|
||||
o.remove();
|
||||
}
|
||||
}
|
||||
Entry::Vacant(v) => {
|
||||
// We checked earlier but let's make sure we're not creating zero-coeff terms
|
||||
assert!(coeff != T::zero());
|
||||
v.insert(coeff);
|
||||
}
|
||||
}
|
||||
Entry::Vacant(v) => {
|
||||
// We checked earlier but let's make sure we're not creating zero-coeff terms
|
||||
assert!(coeff != T::zero());
|
||||
v.insert(coeff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
acc
|
||||
},
|
||||
))
|
||||
acc
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn reduce(self) -> Self {
|
||||
self.into_canonical().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> QuadComb<T> {
|
||||
pub fn as_canonical(&self) -> CanonicalQuadComb<T> {
|
||||
pub fn into_canonical(self) -> CanonicalQuadComb<T> {
|
||||
CanonicalQuadComb {
|
||||
left: self.left.as_canonical(),
|
||||
right: self.right.as_canonical(),
|
||||
left: self.left.into_canonical(),
|
||||
right: self.right.into_canonical(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reduce(self) -> Self {
|
||||
self.into_canonical().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field> fmt::Display for LinComb<T> {
|
||||
|
@ -197,7 +206,8 @@ impl<T: Field> fmt::Display for LinComb<T> {
|
|||
false => write!(
|
||||
f,
|
||||
"{}",
|
||||
self.as_canonical()
|
||||
self.clone()
|
||||
.into_canonical()
|
||||
.0
|
||||
.iter()
|
||||
.map(|(k, v)| format!("{} * {}", v.to_compact_dec_string(), k))
|
||||
|
|
|
@ -13,19 +13,14 @@ use self::directive::DirectiveOptimizer;
|
|||
use self::duplicate::DuplicateOptimizer;
|
||||
use self::redefinition::RedefinitionOptimizer;
|
||||
use self::tautology::TautologyOptimizer;
|
||||
use compile::CompileConfig;
|
||||
|
||||
use crate::ir::Prog;
|
||||
use zokrates_field::Field;
|
||||
|
||||
impl<T: Field> Prog<T> {
|
||||
pub fn optimize(self, config: &CompileConfig) -> Self {
|
||||
let r = if config.is_release() {
|
||||
// remove redefinitions
|
||||
RedefinitionOptimizer::optimize(self)
|
||||
} else {
|
||||
self
|
||||
};
|
||||
pub fn optimize(self) -> Self {
|
||||
// remove redefinitions
|
||||
let r = RedefinitionOptimizer::optimize(self);
|
||||
// remove constraints that are always satisfied
|
||||
let r = TautologyOptimizer::optimize(r);
|
||||
// // deduplicate directives which take the same input
|
||||
|
|
|
@ -46,7 +46,7 @@ use zokrates_field::Field;
|
|||
#[derive(Debug)]
|
||||
pub struct RedefinitionOptimizer<T: Field> {
|
||||
/// Map of renamings for reassigned variables while processing the program.
|
||||
substitution: HashMap<FlatVariable, LinComb<T>>,
|
||||
substitution: HashMap<FlatVariable, CanonicalLinComb<T>>,
|
||||
/// Set of variables that should not be substituted
|
||||
ignore: HashSet<FlatVariable>,
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ impl<T: Field> Folder<T> for RedefinitionOptimizer<T> {
|
|||
// insert into the substitution map
|
||||
match to_insert {
|
||||
Some((k, v)) => {
|
||||
self.substitution.insert(k, v);
|
||||
self.substitution.insert(k, v.into_canonical());
|
||||
}
|
||||
None => {}
|
||||
};
|
||||
|
@ -121,9 +121,9 @@ impl<T: Field> Folder<T> for RedefinitionOptimizer<T> {
|
|||
// check if the inputs are constants, ie reduce to the form `coeff * ~one`
|
||||
let inputs = d
|
||||
.inputs
|
||||
.iter()
|
||||
.into_iter()
|
||||
// we need to reduce to the canonical form to interpret `a + 1 - a` as `1`
|
||||
.map(|i| QuadComb::from(i.as_canonical()))
|
||||
.map(|i| i.reduce())
|
||||
.map(|q| match q.try_linear() {
|
||||
Some(l) => match l.0.len() {
|
||||
// 0 is constant and can be represented by an empty lincomb
|
||||
|
@ -155,7 +155,8 @@ impl<T: Field> Folder<T> for RedefinitionOptimizer<T> {
|
|||
|
||||
// insert the results in the substitution
|
||||
for (output, value) in d.outputs.into_iter().zip(outputs.into_iter()) {
|
||||
self.substitution.insert(output, value.into());
|
||||
self.substitution
|
||||
.insert(output, LinComb::from(value).into_canonical());
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
|
@ -193,7 +194,7 @@ impl<T: Field> Folder<T> for RedefinitionOptimizer<T> {
|
|||
.map(|(variable, coefficient)| {
|
||||
self.substitution
|
||||
.get(&variable)
|
||||
.map(|l| l.clone() * &coefficient)
|
||||
.map(|l| LinComb::from(l.clone()) * &coefficient)
|
||||
.unwrap_or(LinComb::summand(coefficient, variable))
|
||||
})
|
||||
.fold(LinComb::zero(), |acc, x| acc + x)
|
||||
|
|
|
@ -143,6 +143,8 @@ impl<T: Field> ProofSystem<T> for G16 {
|
|||
let vk_gamma_abc_len_regex = Regex::new(r#"(<%vk_gamma_abc_length%>)"#).unwrap();
|
||||
let vk_gamma_abc_repeat_regex = Regex::new(r#"(<%vk_gamma_abc_pts%>)"#).unwrap();
|
||||
let vk_input_len_regex = Regex::new(r#"(<%vk_input_length%>)"#).unwrap();
|
||||
let input_loop = Regex::new(r#"(<%input_loop%>)"#).unwrap();
|
||||
let input_argument = Regex::new(r#"(<%input_argument%>)"#).unwrap();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.alpha.to_string().as_str())
|
||||
|
@ -175,6 +177,31 @@ impl<T: Field> ProofSystem<T> for G16 {
|
|||
)
|
||||
.into_owned();
|
||||
|
||||
// feed input values only if there are any
|
||||
template_text = if gamma_abc_count > 1 {
|
||||
input_loop.replace(
|
||||
template_text.as_str(),
|
||||
r#"
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}"#,
|
||||
)
|
||||
} else {
|
||||
input_loop.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
// take input values as argument only if there are any
|
||||
template_text = if gamma_abc_count > 1 {
|
||||
input_argument.replace(
|
||||
template_text.as_str(),
|
||||
format!(", uint[{}] memory input", gamma_abc_count - 1).as_str(),
|
||||
)
|
||||
} else {
|
||||
input_argument.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
let mut gamma_abc_repeat_text = String::new();
|
||||
for (i, g1) in vk.gamma_abc.iter().enumerate() {
|
||||
gamma_abc_repeat_text.push_str(
|
||||
|
@ -286,13 +313,10 @@ contract Verifier {
|
|||
return 0;
|
||||
}
|
||||
function verifyTx(
|
||||
Proof memory proof,
|
||||
uint[<%vk_input_length%>] memory input
|
||||
Proof memory proof<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -346,17 +370,14 @@ contract Verifier {
|
|||
function verifyTx(
|
||||
uint[2] memory a,
|
||||
uint[2][2] memory b,
|
||||
uint[2] memory c,
|
||||
uint[<%vk_input_length%>] memory input
|
||||
uint[2] memory c<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
Proof memory proof;
|
||||
proof.a = Pairing.G1Point(a[0], a[1]);
|
||||
proof.b = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
|
||||
proof.c = Pairing.G1Point(c[0], c[1]);
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}
|
||||
uint[] memory inputValues = new uint[](<%vk_input_length%>);
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -136,19 +136,19 @@ impl<T: Field> Prog<T> {
|
|||
match statement {
|
||||
Statement::Constraint(quad, lin) => {
|
||||
let a = &bellman_combination(
|
||||
quad.left.clone().as_canonical(),
|
||||
quad.left.into_canonical(),
|
||||
cs,
|
||||
&mut symbols,
|
||||
&mut witness,
|
||||
);
|
||||
let b = &bellman_combination(
|
||||
quad.right.clone().as_canonical(),
|
||||
quad.right.into_canonical(),
|
||||
cs,
|
||||
&mut symbols,
|
||||
&mut witness,
|
||||
);
|
||||
let c =
|
||||
&bellman_combination(lin.as_canonical(), cs, &mut symbols, &mut witness);
|
||||
&bellman_combination(lin.into_canonical(), cs, &mut symbols, &mut witness);
|
||||
|
||||
cs.enforce(|| "Constraint", |lc| lc + a, |lc| lc + b, |lc| lc + c);
|
||||
}
|
||||
|
|
|
@ -149,6 +149,8 @@ impl ProofSystem<Bn128Field> for GM17 {
|
|||
let vk_query_len_regex = Regex::new(r#"(<%vk_query_length%>)"#).unwrap();
|
||||
let vk_query_repeat_regex = Regex::new(r#"(<%vk_query_pts%>)"#).unwrap();
|
||||
let vk_input_len_regex = Regex::new(r#"(<%vk_input_length%>)"#).unwrap();
|
||||
let input_loop = Regex::new(r#"(<%input_loop%>)"#).unwrap();
|
||||
let input_argument = Regex::new(r#"(<%input_argument%>)"#).unwrap();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.h.to_string().as_str())
|
||||
|
@ -182,6 +184,31 @@ impl ProofSystem<Bn128Field> for GM17 {
|
|||
)
|
||||
.into_owned();
|
||||
|
||||
// feed input values only if there are any
|
||||
template_text = if query_count > 1 {
|
||||
input_loop.replace(
|
||||
template_text.as_str(),
|
||||
r#"
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}"#,
|
||||
)
|
||||
} else {
|
||||
input_loop.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
// take input values as argument only if there are any
|
||||
template_text = if query_count > 1 {
|
||||
input_argument.replace(
|
||||
template_text.as_str(),
|
||||
format!(", uint[{}] memory input", query_count - 1).as_str(),
|
||||
)
|
||||
} else {
|
||||
input_argument.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
let mut query_repeat_text = String::new();
|
||||
for (i, g1) in vk.query.iter().enumerate() {
|
||||
query_repeat_text.push_str(
|
||||
|
@ -293,13 +320,10 @@ contract Verifier {
|
|||
return 0;
|
||||
}
|
||||
function verifyTx(
|
||||
Proof memory proof,
|
||||
uint[<%vk_input_length%>] memory input
|
||||
Proof memory proof<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -360,17 +384,14 @@ contract Verifier {
|
|||
function verifyTx(
|
||||
uint[2] memory a,
|
||||
uint[2][2] memory b,
|
||||
uint[2] memory c,
|
||||
uint[<%vk_input_length%>] memory input
|
||||
uint[2] memory c<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
Proof memory proof;
|
||||
proof.a = Pairing.G1Point(a[0], a[1]);
|
||||
proof.b = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
|
||||
proof.c = Pairing.G1Point(c[0], c[1]);
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -156,6 +156,8 @@ impl ProofSystem<Bn128Field> for PGHR13 {
|
|||
let vk_ic_len_regex = Regex::new(r#"(<%vk_ic_length%>)"#).unwrap();
|
||||
let vk_ic_repeat_regex = Regex::new(r#"(<%vk_ic_pts%>)"#).unwrap();
|
||||
let vk_input_len_regex = Regex::new(r#"(<%vk_input_length%>)"#).unwrap();
|
||||
let input_loop = Regex::new(r#"(<%input_loop%>)"#).unwrap();
|
||||
let input_argument = Regex::new(r#"(<%input_argument%>)"#).unwrap();
|
||||
|
||||
template_text = vk_regex
|
||||
.replace(template_text.as_str(), vk.a.to_string().as_str())
|
||||
|
@ -194,6 +196,31 @@ impl ProofSystem<Bn128Field> for PGHR13 {
|
|||
.replace(template_text.as_str(), format!("{}", ic_count - 1).as_str())
|
||||
.into_owned();
|
||||
|
||||
// feed input values only if there are any
|
||||
template_text = if ic_count > 1 {
|
||||
input_loop.replace(
|
||||
template_text.as_str(),
|
||||
r#"
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}"#,
|
||||
)
|
||||
} else {
|
||||
input_loop.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
// take input values as argument only if there are any
|
||||
template_text = if ic_count > 1 {
|
||||
input_argument.replace(
|
||||
template_text.as_str(),
|
||||
format!(", uint[{}] memory input", ic_count - 1).as_str(),
|
||||
)
|
||||
} else {
|
||||
input_argument.replace(template_text.as_str(), "")
|
||||
}
|
||||
.to_string();
|
||||
|
||||
let mut ic_repeat_text = String::new();
|
||||
for (i, g1) in vk.ic.iter().enumerate() {
|
||||
ic_repeat_text.push_str(
|
||||
|
@ -316,13 +343,10 @@ const CONTRACT_TEMPLATE_V2: &str = r#"contract Verifier {
|
|||
return 0;
|
||||
}
|
||||
function verifyTx(
|
||||
Proof memory proof,
|
||||
uint[<%vk_input_length%>] memory input
|
||||
Proof memory proof<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -399,8 +423,7 @@ const CONTRACT_TEMPLATE: &str = r#"contract Verifier {
|
|||
uint[2] memory c,
|
||||
uint[2] memory c_p,
|
||||
uint[2] memory h,
|
||||
uint[2] memory k,
|
||||
uint[<%vk_input_length%>] memory input
|
||||
uint[2] memory k<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
Proof memory proof;
|
||||
proof.a = Pairing.G1Point(a[0], a[1]);
|
||||
|
@ -412,9 +435,7 @@ const CONTRACT_TEMPLATE: &str = r#"contract Verifier {
|
|||
proof.h = Pairing.G1Point(h[0], h[1]);
|
||||
proof.k = Pairing.G1Point(k[0], k[1]);
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
for(uint i = 0; i < input.length; i++){
|
||||
inputValues[i] = input[i];
|
||||
}
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,7 @@ extern crate zokrates_field;
|
|||
use std::io;
|
||||
use zokrates_common::Resolver;
|
||||
use zokrates_core::{
|
||||
compile::{compile, CompilationArtifacts, CompileConfig},
|
||||
compile::{compile, CompilationArtifacts},
|
||||
ir::Interpreter,
|
||||
};
|
||||
use zokrates_field::Bn128Field;
|
||||
|
@ -28,7 +28,6 @@ fn out_of_range() {
|
|||
source,
|
||||
"./path/to/file".into(),
|
||||
None::<&dyn Resolver<io::Error>>,
|
||||
&CompileConfig::default(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_fs_resolver"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
authors = ["Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||
repository = "https://github.com/JacobEberhardt/ZoKrates.git"
|
||||
edition = "2018"
|
||||
|
|
12
zokrates_js/Cargo.lock
generated
12
zokrates_js/Cargo.lock
generated
|
@ -1013,7 +1013,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_abi"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
@ -1028,7 +1028,7 @@ version = "0.1.0"
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_core"
|
||||
version = "0.4.3"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"bellman_ce",
|
||||
"bincode 0.8.0",
|
||||
|
@ -1054,7 +1054,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_field"
|
||||
version = "0.3.6"
|
||||
version = "0.3.7"
|
||||
dependencies = [
|
||||
"bellman_ce",
|
||||
"bincode 0.8.0",
|
||||
|
@ -1070,7 +1070,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_js"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
dependencies = [
|
||||
"bincode 1.3.1",
|
||||
"console_error_panic_hook",
|
||||
|
@ -1086,7 +1086,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_parser"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
|
@ -1094,7 +1094,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_pest_ast"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
dependencies = [
|
||||
"from-pest",
|
||||
"lazy_static",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_js"
|
||||
version = "1.0.24"
|
||||
version = "1.0.25"
|
||||
authors = ["Darko Macesic"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
5
zokrates_js/index.d.ts
vendored
5
zokrates_js/index.d.ts
vendored
|
@ -7,14 +7,9 @@ declare module 'zokrates-js' {
|
|||
export type SolidityAbi = "v1" | "v2";
|
||||
export type ResolveCallback = (location: string, path: string) => ResolverResult;
|
||||
|
||||
export interface CompileConfig {
|
||||
is_release: boolean
|
||||
}
|
||||
|
||||
export interface CompileOptions {
|
||||
location?: string,
|
||||
resolveCallback?: ResolveCallback,
|
||||
config?: CompileConfig
|
||||
}
|
||||
|
||||
export interface VerificationKey {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import wrapper from './wrapper';
|
||||
import wrapper from './wrapper.js';
|
||||
import stdlib from './stdlib.json';
|
||||
import metadata from './metadata.json';
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "zokrates-js",
|
||||
"main": "index.js",
|
||||
"author": "Darko Macesic <darem966@gmail.com>",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"keywords": [
|
||||
"zokrates",
|
||||
"wasm-bindgen",
|
||||
|
|
|
@ -5,9 +5,7 @@ use std::path::PathBuf;
|
|||
use wasm_bindgen::prelude::*;
|
||||
use zokrates_abi::{parse_strict, Decode, Encode, Inputs};
|
||||
use zokrates_common::Resolver;
|
||||
use zokrates_core::compile::{
|
||||
compile as core_compile, CompilationArtifacts, CompileConfig, CompileError,
|
||||
};
|
||||
use zokrates_core::compile::{compile as core_compile, CompilationArtifacts, CompileError};
|
||||
use zokrates_core::imports::Error;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::proof_system::bellman::groth16::G16;
|
||||
|
@ -102,14 +100,12 @@ pub fn compile(
|
|||
config: JsValue,
|
||||
) -> Result<JsValue, JsValue> {
|
||||
let resolver = JsResolver::new(resolve_callback);
|
||||
let config: CompileConfig = config.into_serde().unwrap_or(CompileConfig::default());
|
||||
|
||||
let fmt_error = |e: &CompileError| format!("{}:{}", e.file().display(), e.value());
|
||||
let artifacts: CompilationArtifacts<Bn128Field> = core_compile(
|
||||
source.as_string().unwrap(),
|
||||
PathBuf::from(location.as_string().unwrap()),
|
||||
Some(&resolver),
|
||||
&config,
|
||||
)
|
||||
.map_err(|ce| {
|
||||
JsValue::from_str(&format!(
|
||||
|
|
|
@ -36,11 +36,11 @@ module.exports = (dep) => {
|
|||
|
||||
return {
|
||||
compile: (source, options = {}) => {
|
||||
const { location = "main.zok", resolveCallback = () => null, config } = options;
|
||||
const { location = "main.zok", resolveCallback = () => null } = options;
|
||||
const callback = (currentLocation, importLocation) => {
|
||||
return resolveFromStdlib(currentLocation, importLocation) || resolveCallback(currentLocation, importLocation);
|
||||
};
|
||||
const { program, abi } = zokrates.compile(source, location, callback, config);
|
||||
const { program, abi } = zokrates.compile(source, location, callback);
|
||||
return {
|
||||
program: Array.from(program),
|
||||
abi
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_test"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
authors = ["schaeff <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ fn compare<T: Field>(result: ir::ExecutionResult<T>, expected: TestResult) -> Re
|
|||
}
|
||||
|
||||
use std::io::{BufReader, Read};
|
||||
use zokrates_core::compile::{compile, CompileConfig};
|
||||
use zokrates_core::compile::compile;
|
||||
use zokrates_fs_resolver::FileSystemResolver;
|
||||
|
||||
pub fn test_inner(test_path: &str) {
|
||||
|
@ -104,18 +104,10 @@ fn compile_and_run<T: Field>(t: Tests) {
|
|||
let code = std::fs::read_to_string(&t.entry_point).unwrap();
|
||||
|
||||
let resolver = FileSystemResolver::new();
|
||||
let artifacts = compile::<T, _>(
|
||||
code,
|
||||
t.entry_point.clone(),
|
||||
Some(&resolver),
|
||||
&CompileConfig::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let artifacts = compile::<T, _>(code, t.entry_point.clone(), Some(&resolver)).unwrap();
|
||||
|
||||
let bin = artifacts.prog();
|
||||
|
||||
println!("NOTE: We do not compile in release mode here, so the metrics below are conservative");
|
||||
|
||||
match t.max_constraint_count {
|
||||
Some(target_count) => {
|
||||
let count = bin.constraint_count();
|
||||
|
|
Loading…
Reference in a new issue