1
0
Fork 0
mirror of synced 2025-09-23 04:08:33 +00:00

add allow-unconstrained-variables compilation flag

This commit is contained in:
dark64 2020-12-10 11:59:01 +01:00
parent 194e57c5e7
commit 7e534e29b2
9 changed files with 84 additions and 155 deletions

View file

@ -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, CompileError};
use zokrates_core::compile::{check, compile, CompilationArtifacts, CompileConfig, CompileError};
use zokrates_core::ir::{self, ProgEnum};
use zokrates_core::proof_system::{
@ -181,7 +181,7 @@ fn cli_compute<T: Field>(ir_prog: ir::Prog<T>, sub_matches: &ArgMatches) -> Resu
let signature = match is_abi {
true => {
let path = Path::new(sub_matches.value_of("abi_spec").unwrap());
let path = Path::new(sub_matches.value_of("abi-spec").unwrap());
let file = File::open(&path)
.map_err(|why| format!("couldn't open {}: {}", path.display(), why))?;
let mut reader = BufReader::new(file);
@ -280,7 +280,7 @@ fn cli_compile<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
let bin_output_path = Path::new(sub_matches.value_of("output").unwrap());
let abi_spec_path = Path::new(sub_matches.value_of("abi_spec").unwrap());
let abi_spec_path = Path::new(sub_matches.value_of("abi-spec").unwrap());
let hr_output_path = bin_output_path.to_path_buf().with_extension("ztf");
@ -304,8 +304,13 @@ fn cli_compile<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
let resolver =
FileSystemResolver::with_stdlib_root(sub_matches.value_of("stdlib-path").unwrap());
let artifacts: CompilationArtifacts<T> =
compile(source, path, Some(&resolver)).map_err(|e| {
let config = CompileConfig {
allow_unconstrained_variables: sub_matches.is_present("allow-unconstrained-variables"),
};
let artifacts: CompilationArtifacts<T> = compile(source, path, Some(&resolver), &config)
.map_err(|e| {
format!(
"Compilation failed:\n\n{}",
e.0.iter()
@ -476,9 +481,9 @@ fn cli() -> Result<(), String> {
.required(false)
.env("ZOKRATES_STDLIB")
.default_value(default_stdlib_path.to_str().unwrap_or(""))
).arg(Arg::with_name("abi_spec")
).arg(Arg::with_name("abi-spec")
.short("s")
.long("abi_spec")
.long("abi-spec")
.help("Path of the ABI specification")
.value_name("FILE")
.takes_value(true)
@ -504,6 +509,10 @@ fn cli() -> Result<(), String> {
.long("light")
.help("Skip logs and human readable output")
.required(false)
).arg(Arg::with_name("allow-unconstrained-variables")
.long("allow-unconstrained-variables")
.help("Allow unconstrained variables by inserting dummy constraints")
.required(false)
)
)
.subcommand(SubCommand::with_name("check")
@ -636,9 +645,9 @@ fn cli() -> Result<(), String> {
.takes_value(true)
.required(false)
.default_value(FLATTENED_CODE_DEFAULT_PATH)
).arg(Arg::with_name("abi_spec")
).arg(Arg::with_name("abi-spec")
.short("s")
.long("abi_spec")
.long("abi-spec")
.help("Path of the ABI specification")
.value_name("FILE")
.takes_value(true)
@ -1098,7 +1107,8 @@ mod tests {
let stdlib = std::fs::canonicalize("../zokrates_stdlib/stdlib").unwrap();
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let res = compile::<Bn128Field, _>(source, path, Some(&resolver));
let res =
compile::<Bn128Field, _>(source, path, Some(&resolver), &CompileConfig::default());
assert_eq!(res.is_err(), should_error);
}
@ -1124,7 +1134,7 @@ mod tests {
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let artifacts: CompilationArtifacts<Bn128Field> =
compile(source, path, Some(&resolver)).unwrap();
compile(source, path, Some(&resolver), &CompileConfig::default()).unwrap();
let interpreter = ir::Interpreter::default();
@ -1154,7 +1164,7 @@ mod tests {
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let artifacts: CompilationArtifacts<Bn128Field> =
compile(source, path, Some(&resolver)).unwrap();
compile(source, path, Some(&resolver), &CompileConfig::default()).unwrap();
let interpreter = ir::Interpreter::default();

View file

@ -13,6 +13,7 @@ use crate::static_analysis::Analyse;
use crate::typed_absy::abi::Abi;
use crate::zir::ZirProgram;
use macros::process_macros;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt;
use std::io;
@ -140,19 +141,25 @@ impl fmt::Display for CompileErrorInner {
}
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct CompileConfig {
pub allow_unconstrained_variables: bool,
}
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();
let (typed_ast, abi) = check_with_arena(source, location, resolver, &arena)?;
// flatten input program
let program_flattened = Flattener::flatten(typed_ast);
let program_flattened = Flattener::flatten(typed_ast, config);
// analyse (constant propagation after call resolution)
let program_flattened = program_flattened.analyse();
@ -263,6 +270,7 @@ mod test {
source,
"./path/to/file".into(),
None::<&dyn Resolver<io::Error>>,
&CompileConfig::default(),
);
assert!(res.unwrap_err().0[0]
.value()
@ -281,6 +289,7 @@ mod test {
source,
"./path/to/file".into(),
None::<&dyn Resolver<io::Error>>,
&CompileConfig::default(),
);
assert!(res.is_ok());
}
@ -361,6 +370,7 @@ struct Bar { field a }
main.to_string(),
"main".into(),
Some(&CustomResolver),
&CompileConfig::default(),
)
.unwrap();

View file

@ -9,6 +9,7 @@ mod utils;
use self::utils::flat_expression_from_bits;
use crate::compile::CompileConfig;
use crate::flat_absy::*;
use crate::ir;
use crate::solvers::Solver;
@ -24,6 +25,7 @@ type FlatStatements<T> = Vec<FlatStatement<T>>;
/// Flattener, computes flattened program.
#[derive(Debug)]
pub struct Flattener<'ast, T: Field> {
config: &'ast CompileConfig,
/// Index of the next introduced variable while processing the program.
next_var_idx: usize,
/// `FlatVariable`s corresponding to each `Identifier`
@ -148,14 +150,15 @@ impl<T: Field> FlatUExpression<T> {
}
impl<'ast, T: Field> Flattener<'ast, T> {
pub fn flatten(p: ZirProgram<'ast, T>) -> FlatProg<T> {
Flattener::new().flatten_program(p)
pub fn flatten(p: ZirProgram<'ast, T>, config: &CompileConfig) -> FlatProg<T> {
Flattener::new(config).flatten_program(p)
}
/// Returns a `Flattener` with fresh `layout`.
fn new() -> Flattener<'ast, T> {
fn new(config: &'ast CompileConfig) -> Flattener<'ast, T> {
Flattener {
config,
next_var_idx: 0,
layout: HashMap::new(),
flat_cache: HashMap::new(),
@ -2196,7 +2199,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
));
}
Type::FieldElement => {
if parameter.private {
if self.config.allow_unconstrained_variables && parameter.private {
// we insert dummy condition statement for private field elements
// to avoid unconstrained variables
// translates to y == x * x
@ -2280,7 +2283,8 @@ mod tests {
},
};
let mut flattener = Flattener::new();
let config = CompileConfig::default();
let mut flattener = Flattener::new(&config);
let expected = FlatFunction {
arguments: vec![],
@ -2339,7 +2343,8 @@ mod tests {
},
};
let mut flattener = Flattener::new();
let config = CompileConfig::default();
let mut flattener = Flattener::new(&config);
let expected = FlatFunction {
arguments: vec![],
@ -2418,7 +2423,8 @@ mod tests {
},
};
let mut flattener = Flattener::new();
let config = CompileConfig::default();
let mut flattener = Flattener::new(&config);
let expected = FlatFunction {
arguments: vec![],
@ -2482,6 +2488,7 @@ mod tests {
#[test]
fn if_else() {
let config = CompileConfig::default();
let expression = FieldElementExpression::IfElse(
box BooleanExpression::FieldEq(
box FieldElementExpression::Number(Bn128Field::from(32)),
@ -2491,14 +2498,15 @@ mod tests {
box FieldElementExpression::Number(Bn128Field::from(51)),
);
let mut flattener = Flattener::new();
let mut flattener = Flattener::new(&config);
flattener.flatten_field_expression(&HashMap::new(), &mut FlatStatements::new(), expression);
}
#[test]
fn geq_leq() {
let mut flattener = Flattener::new();
let config = CompileConfig::default();
let mut flattener = Flattener::new(&config);
let expression_le = BooleanExpression::Le(
box FieldElementExpression::Number(Bn128Field::from(32)),
box FieldElementExpression::Number(Bn128Field::from(4)),
@ -2509,7 +2517,7 @@ mod tests {
expression_le,
);
let mut flattener = Flattener::new();
let mut flattener = Flattener::new(&config);
let expression_ge = BooleanExpression::Ge(
box FieldElementExpression::Number(Bn128Field::from(32)),
box FieldElementExpression::Number(Bn128Field::from(4)),
@ -2523,7 +2531,8 @@ mod tests {
#[test]
fn bool_and() {
let mut flattener = Flattener::new();
let config = CompileConfig::default();
let mut flattener = Flattener::new(&config);
let expression = FieldElementExpression::IfElse(
box BooleanExpression::And(
@ -2546,8 +2555,8 @@ mod tests {
#[test]
fn div() {
// a = 5 / b / b
let mut flattener = Flattener::new();
let config = CompileConfig::default();
let mut flattener = Flattener::new(&config);
let mut statements_flattened = FlatStatements::new();
let definition = ZirStatement::Definition(
@ -2646,7 +2655,8 @@ mod tests {
#[test]
#[should_panic]
fn next_variable() {
let mut flattener: Flattener<Bn128Field> = Flattener::new();
let config = CompileConfig::default();
let mut flattener: Flattener<Bn128Field> = Flattener::new(&config);
assert_eq!(
FlatVariable::new(0),
flattener.use_variable(&Variable::field_element("a"))

View file

@ -4,6 +4,7 @@ extern crate zokrates_field;
use std::io;
use zokrates_common::Resolver;
use zokrates_core::compile::CompileConfig;
use zokrates_core::{
compile::{compile, CompilationArtifacts},
ir::Interpreter,
@ -28,6 +29,7 @@ fn out_of_range() {
source,
"./path/to/file".into(),
None::<&dyn Resolver<io::Error>>,
&CompileConfig::default(),
)
.unwrap();

123
zokrates_js/Cargo.lock generated
View file

@ -24,86 +24,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "ark-bls12-377"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/curves#23e87bf224c23be5c5bccc6084aae31fff8bb83f"
dependencies = [
"ark-ec",
"ark-ff",
"ark-std",
]
[[package]]
name = "ark-bn254"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/curves#23e87bf224c23be5c5bccc6084aae31fff8bb83f"
dependencies = [
"ark-ec",
"ark-ff",
"ark-std",
]
[[package]]
name = "ark-bw6-761"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/curves#23e87bf224c23be5c5bccc6084aae31fff8bb83f"
dependencies = [
"ark-bls12-377",
"ark-ec",
"ark-ff",
"ark-std",
]
[[package]]
name = "ark-ec"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/algebra#9bc541722707e1ac495e82fbf86446bbfde38a82"
dependencies = [
"ark-ff",
"ark-serialize",
"ark-std",
"derivative",
"num-traits 0.2.12",
"rand 0.7.3",
]
[[package]]
name = "ark-ff"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/algebra#9bc541722707e1ac495e82fbf86446bbfde38a82"
dependencies = [
"ark-ff-asm",
"ark-serialize",
"ark-std",
"derivative",
"num-traits 0.2.12",
"rand 0.7.3",
"rustc_version",
]
[[package]]
name = "ark-ff-asm"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/algebra#9bc541722707e1ac495e82fbf86446bbfde38a82"
dependencies = [
"quote 1.0.7",
"syn 1.0.34",
]
[[package]]
name = "ark-serialize"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/algebra#9bc541722707e1ac495e82fbf86446bbfde38a82"
dependencies = [
"ark-std",
]
[[package]]
name = "ark-std"
version = "0.1.0"
source = "git+https://github.com/arkworks-rs/utils#f6974ac72f59339b7ab798a728a84c5a7b8bac45"
[[package]]
name = "autocfg"
version = "1.0.0"
@ -256,17 +176,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "derivative"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
dependencies = [
"proc-macro2 1.0.18",
"quote 1.0.7",
"syn 1.0.34",
]
[[package]]
name = "digest"
version = "0.8.1"
@ -896,39 +805,12 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
[[package]]
name = "rustc_version"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65c94201b44764d6d1f7e37c15a8289ed55e546c1762c7f1d57f616966e0c181"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ef146c2ad5e5f4b037cd6ce2ebb775401729b19a82040c1beac9d36c7d1428"
dependencies = [
"pest",
]
[[package]]
name = "serde"
version = "1.0.114"
@ -1229,11 +1111,6 @@ dependencies = [
name = "zokrates_field"
version = "0.3.7"
dependencies = [
"ark-bls12-377",
"ark-bn254",
"ark-bw6-761",
"ark-ec",
"ark-ff",
"bellman_ce",
"bincode 0.8.0",
"lazy_static",

View file

@ -10,9 +10,14 @@ declare module 'zokrates-js' {
export type SolidityAbi = "v1" | "v2";
export type ResolveCallback = (location: string, path: string) => ResolverResult;
export interface CompileConfig {
allow_unconstrained_variables?: boolean
}
export interface CompileOptions {
location?: string,
resolveCallback?: ResolveCallback,
config?: CompileConfig
}
export interface VerificationKey {

View file

@ -5,7 +5,9 @@ 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, CompileError};
use zokrates_core::compile::{
compile as core_compile, CompilationArtifacts, CompileConfig, CompileError,
};
use zokrates_core::imports::Error;
use zokrates_core::ir;
use zokrates_core::proof_system::bellman::Bellman;
@ -92,14 +94,17 @@ pub fn compile(
source: JsValue,
location: JsValue,
resolve_callback: &js_sys::Function,
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!(

View file

@ -36,11 +36,15 @@ module.exports = (dep) => {
return {
compile: (source, options = {}) => {
const { location = "main.zok", resolveCallback = () => null } = options;
const createConfig = (config) => ({
allow_unconstrained_variables: false,
...config
});
const { location = "main.zok", resolveCallback = () => null, config = {} } = options;
const callback = (currentLocation, importLocation) => {
return resolveFromStdlib(currentLocation, importLocation) || resolveCallback(currentLocation, importLocation);
};
const { program, abi } = zokrates.compile(source, location, callback);
const { program, abi } = zokrates.compile(source, location, callback, createConfig(config));
return {
program: Array.from(program),
abi

View file

@ -86,7 +86,7 @@ fn compare<T: Field>(result: ir::ExecutionResult<T>, expected: TestResult) -> Re
}
use std::io::{BufReader, Read};
use zokrates_core::compile::compile;
use zokrates_core::compile::{compile, CompileConfig};
use zokrates_fs_resolver::FileSystemResolver;
pub fn test_inner(test_path: &str) {
@ -110,7 +110,13 @@ fn compile_and_run<T: Field>(t: Tests) {
let stdlib = std::fs::canonicalize("../zokrates_stdlib/stdlib").unwrap();
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let artifacts = compile::<T, _>(code, t.entry_point.clone(), Some(&resolver)).unwrap();
let artifacts = compile::<T, _>(
code,
t.entry_point.clone(),
Some(&resolver),
&CompileConfig::default(),
)
.unwrap();
let bin = artifacts.prog();