1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

Merge branch 'develop' of github.com:Zokrates/ZoKrates into u8-playground

This commit is contained in:
schaeff 2019-11-26 15:23:27 +01:00
commit 19be8c463c
10 changed files with 13 additions and 1183 deletions

View file

@ -42,9 +42,9 @@ jobs:
- restore_cache:
keys:
- v4-cargo-cache-{{ arch }}-{{ checksum "Cargo.lock" }}
# - run:
# name: Check format
# command: rustup component add rustfmt; cargo fmt --all -- --check
- run:
name: Check format
command: rustup component add rustfmt; cargo fmt --all -- --check
- run:
name: Install libsnark prerequisites
command: ./scripts/install_libsnark_prerequisites.sh

908
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,6 @@ members = [
"zokrates_core",
"zokrates_cli",
"zokrates_fs_resolver",
"zokrates_github_resolver",
"zokrates_stdlib",
"zokrates_embed",
"zokrates_abi",

View file

@ -6,10 +6,9 @@ repository = "https://github.com/JacobEberhardt/ZoKrates.git"
edition = "2018"
[features]
default = ["github"]
default = []
libsnark = ["zokrates_core/libsnark"]
wasm = ["zokrates_core/wasm"]
github = ["zokrates_github_resolver"]
[dependencies]
clap = "2.26.2"
@ -19,7 +18,6 @@ zokrates_field = { version = "0.3", path = "../zokrates_field" }
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
zokrates_core = { version = "0.4", path = "../zokrates_core" }
zokrates_fs_resolver = { version = "0.4", path = "../zokrates_fs_resolver"}
zokrates_github_resolver = { version = "0.1", path = "../zokrates_github_resolver", optional = true}
serde_json = "1.0"
[dev-dependencies]

View file

@ -7,19 +7,17 @@
use bincode::{deserialize_from, serialize_into, Infinite};
use clap::{App, AppSettings, Arg, SubCommand};
use serde_json::Value;
use std::env;
use std::fs::File;
use std::io::{stdin, BufReader, BufWriter, Read, Write};
use std::path::{Path, PathBuf};
use std::string::String;
use std::{env, io};
use zokrates_abi::Encode;
use zokrates_core::compile::compile;
use zokrates_core::ir;
use zokrates_core::proof_system::*;
use zokrates_field::field::{Field, FieldPrime};
use zokrates_fs_resolver::resolve as fs_resolve;
#[cfg(feature = "github")]
use zokrates_github_resolver::{is_github_import, resolve as github_resolve};
fn main() {
cli().unwrap_or_else(|e| {
@ -28,19 +26,6 @@ fn main() {
})
}
fn resolve<'a>(
location: Option<String>,
source: &'a str,
) -> Result<(BufReader<File>, String, &'a str), io::Error> {
#[cfg(feature = "github")]
{
if is_github_import(source) {
return github_resolve(location, source);
};
}
fs_resolve(location, source)
}
fn cli() -> Result<(), String> {
const FLATTENED_CODE_DEFAULT_PATH: &str = "out";
const VERIFICATION_KEY_DEFAULT_PATH: &str = "verification.key";
@ -287,7 +272,7 @@ fn cli() -> Result<(), String> {
let mut reader = BufReader::new(file);
let program_flattened: ir::Prog<FieldPrime> =
compile(&mut reader, Some(location), Some(resolve))
compile(&mut reader, Some(location), Some(fs_resolve))
.map_err(|e| format!("Compilation failed:\n\n {}", e))?;
// number of constraints the flattened program will translate to.
@ -604,7 +589,7 @@ mod tests {
.unwrap();
let _: ir::Prog<FieldPrime> =
compile(&mut reader, Some(location), Some(resolve)).unwrap();
compile(&mut reader, Some(location), Some(fs_resolve)).unwrap();
}
}
@ -631,7 +616,7 @@ mod tests {
let mut reader = BufReader::new(file);
let program_flattened: ir::Prog<FieldPrime> =
compile(&mut reader, Some(location), Some(resolve)).unwrap();
compile(&mut reader, Some(location), Some(fs_resolve)).unwrap();
let _ = program_flattened
.execute(&vec![FieldPrime::from(0)])
@ -663,7 +648,7 @@ mod tests {
let mut reader = BufReader::new(file);
let program_flattened: ir::Prog<FieldPrime> =
compile(&mut reader, Some(location), Some(resolve)).unwrap();
compile(&mut reader, Some(location), Some(fs_resolve)).unwrap();
let _ = program_flattened
.execute(&vec![FieldPrime::from(0)])

View file

@ -1446,7 +1446,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
let ebytes_be = e.to_be_bytes();
// convert the bytes to bits, remove leading zeroes (we only need powers up to the highest non-zero bit)
let ebits_be: Vec<_> = ebytes_be
.into_iter()
.iter()
.flat_map(|byte| (0..8).rev().map(move |i| byte & (1 << i) != 0)) // byte to bit, big endian
.skip_while(|b| !b) // skip trailing false bits
.collect();

View file

@ -1,18 +0,0 @@
[package]
name = "zokrates_github_resolver"
version = "0.1.1"
authors = ["Evgenii P. <eupn@protonmail.com>", "schaeff <thibaut@schaeff.fr>"]
repository = "https://github.com/eupn/ZoKrates.git"
edition = "2018"
[features]
default = []
[dependencies]
reqwest = "0.9"
tempfile = "3"
[dev-dependencies]
mockito = "0.17"
[lib]

View file

@ -1,224 +0,0 @@
//! # GitHub import resolver
//!
//! GitHub import resolver allows to import files located in github.com repos.
//!
//! To import file from github, use following syntax:
//! ```zokrates
//! import "github:user/repo/branch/path/to/file"
//! ```
//!
//! For example:
//! ```zokrates
//! import "github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/merkleTree/sha256PathProof3" as merkleTreeProof
//! ```
//!
//! Example above imports file `zokrates_cli/examples/merkleTree/sha256PathProof3.zok` located at ZoKrates
//! repository's `master` branch by downloading from URL:
//! https://raw.githubusercontent.com/Zokrates/ZoKrates/master/zokrates_cli/examples/merkleTree/sha256PathProof3.zok
//!
use reqwest;
use std::fs::File;
use std::io::{self, copy, BufReader};
use std::path::{Path, PathBuf};
use tempfile::NamedTempFile;
#[cfg(test)]
use mockito::{self, Mock};
/// Prefix for github import source to be distinguished.
const GITHUB_IMPORT_PREFIX: &str = "github.com/";
/// GitHub download URL base
#[cfg(not(test))]
const GITHUB_URL_BASE: &str = "https://raw.githubusercontent.com";
/// Resolves import from the Github.
/// This importer needs to be provided with location since relative paths could be used inside the
/// files that are imported from github.
pub fn resolve<'a>(
location: Option<String>,
path: &'a str,
) -> Result<(BufReader<File>, String, &'a str), io::Error> {
if let Some(location) = location {
let path = Path::new(path);
let (root, repo, branch, file_path) = parse_input_path(&path)?;
#[cfg(not(test))]
let url = GITHUB_URL_BASE;
#[cfg(test)]
let url = mockito::server_url();
let pb = download_from_github(&url, &root, &repo, &branch, &file_path)?;
let file = File::open(&pb)?;
let br = BufReader::new(file);
let alias = path.file_stem().unwrap().to_str().unwrap();
Ok((br, location.to_owned(), &alias))
} else {
Err(io::Error::new(io::ErrorKind::Other, "No location provided"))
}
}
/// Checks that import source is using github import location.
pub fn is_github_import(source: &str) -> bool {
source.starts_with(GITHUB_IMPORT_PREFIX)
}
/// Parses github import syntax: "github.com/<root>/<repo>/<branch>/<path/to/file>"
/// Where:
/// - <root> is the user or organization name
/// - <repo> is the repository name
/// - <branch> is the branch/snapshot name, e.g. `master`
/// - <path/to/file> is the absolute path to file in the specified branch of the repository
fn parse_input_path<'a>(path: &'a Path) -> Result<(&'a str, &'a str, &'a str, &'a str), io::Error> {
//let path_owned = path.replacen(GITHUB_IMPORT_PREFIX, "", 1);
if path.to_str().unwrap().contains("..") {
return Err(io::Error::new(
io::ErrorKind::Other,
"Invalid github import syntax. It must not contain '..'",
));
}
let mut components = path.components();
// Check that root, repo, branch & path are specified
if components.clone().count() < 5 {
return Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Invalid github import syntax. Should be: {}<root>/<repo>/<branch>/<path>",
GITHUB_IMPORT_PREFIX
),
));
}
let _ = components.next().unwrap().as_os_str().to_str().unwrap();
let root = components.next().unwrap().as_os_str().to_str().unwrap();
let repo = components.next().unwrap().as_os_str().to_str().unwrap();
let branch = components.next().unwrap().as_os_str().to_str().unwrap();
let path = components.as_path().to_str().unwrap(); // Collect the rest of the import path into single string
Ok((root, repo, branch, path))
}
/// Downloads the file from github by specific root (user/org), repository, branch and path.
fn download_from_github(
github: &str,
root: &str,
repo: &str,
branch: &str,
path: &str,
) -> Result<PathBuf, io::Error> {
let url = format!(
"{github}/{root}/{repo}/{branch}/{path}{extension}",
github = github,
root = root,
repo = repo,
branch = branch,
path = path,
extension = ".zok"
);
download_url(&url)
}
fn download_url(url: &str) -> Result<PathBuf, io::Error> {
let mut response = reqwest::get(url).map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("Unable to access github: {}", e.to_string()),
)
})?;
if !response.status().is_success() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Unable to access github: {}", response.status()),
));
}
let (mut dest, pb) = NamedTempFile::new()?.keep()?;
copy(&mut response, &mut dest)?;
Ok(pb)
}
#[cfg(test)]
mod tests {
use super::*;
/// Initializes github.com mocks for `import_github` example to run from `examples` tests.
/// Note that returned mock objects should be alive prior to github requests.
fn init_github_mock() -> (Mock, Mock) {
let m1 = mockito::mock(
"GET",
"/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/foo.zok",
)
.with_status(200)
.with_body_from_file("./static/foo.zok")
.create();
let m2 = mockito::mock(
"GET",
"/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/notfound.zok",
)
.with_status(404)
.create();
(m1, m2)
}
#[test]
pub fn import_simple() {
let res = parse_input_path(Path::new(
"github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/import",
))
.unwrap();
let (root, repo, branch, path) = res;
assert_eq!(root, "Zokrates");
assert_eq!(repo, "ZoKrates");
assert_eq!(branch, "master");
assert_eq!(path, "zokrates_cli/examples/imports/import");
}
#[test]
#[should_panic]
pub fn import_no_branch() {
// Correct syntax should be: github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/import
// but branch name is not specified
parse_input_path(Path::new("github.com/Zokrates/ZoKrates/test")).unwrap();
}
#[test]
#[should_panic]
pub fn import_relative_paths() {
// Relative paths should not be allowed
parse_input_path(Path::new(
"github.com/Zokrates/ZoKrates/master/examples/../imports",
))
.unwrap();
}
#[test]
pub fn resolve_ok() {
let (_m0, _m1) = init_github_mock();
let res = resolve(
Some("".to_string()),
&"github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/foo",
);
assert!(res.is_ok());
}
#[test]
pub fn resolve_err() {
let (_m0, _m1) = init_github_mock();
assert!(resolve(
Some("".to_string()),
&"github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/notfound"
)
.is_err());
}
}

View file

@ -122,8 +122,6 @@ WHITESPACE = _{ " " | "\t" | "\\" ~ NEWLINE}
COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
// TODO: Order by alphabet
keyword = @{"for" | "endfor" | "as" | "in" | "return" | "byte" | "field" | "bool" | "if" | "do" | "else" | "export" | "false" |
"def" | "for" | "import" | "uint" |
"in" | "public" | "private" | "return" |
"struct" | "true"
}
keyword = @{"as"|"bool"|"byte"|"def"|"do"|"else"|"endfor"|"export"|"false"|"field"|"for"|"if"|"import"|
"in"|"private"|"public"|"return"|"struct"|"true"|"uint"
}