commit
8296339603
6 changed files with 107 additions and 42 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,3 +17,4 @@ witness
|
||||||
# Cargo.lock
|
# Cargo.lock
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
|
56
Jenkinsfile
vendored
Normal file
56
Jenkinsfile
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#!/usr/bin/env groovy
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
stages {
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
withDockerContainer('kyroy/zokrates-test') {
|
||||||
|
sh 'RUSTFLAGS="-D warnings" cargo build'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Test') {
|
||||||
|
steps {
|
||||||
|
withDockerContainer('kyroy/zokrates-test') {
|
||||||
|
sh 'RUSTFLAGS="-D warnings" cargo test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Integration Test') {
|
||||||
|
when {
|
||||||
|
expression { env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'develop' }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
withDockerContainer('kyroy/zokrates-test') {
|
||||||
|
sh 'RUSTFLAGS="-D warnings" cargo test -- --ignored'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Docker Build & Push') {
|
||||||
|
when {
|
||||||
|
expression { env.BRANCH_NAME == 'master' }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def dockerImage = docker.build("kyroy/zokrates")
|
||||||
|
docker.withRegistry('https://registry.hub.docker.com', 'dockerhub-kyroy') {
|
||||||
|
dockerImage.push("latest")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
// junit allowEmptyResults: true, testResults: '*test.xml'
|
||||||
|
deleteDir()
|
||||||
|
}
|
||||||
|
changed {
|
||||||
|
notifyStatusChange notificationRecipients: 'mail@kyroy.com', componentName: 'ZoKrates'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
# Zokrates
|
# Zokrates
|
||||||
|
|
||||||
[](https://gitter.im/ZoKrates/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/ZoKrates/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
Zokrates is a toolbox for zkSNARKs on Ethereum.
|
Zokrates is a toolbox for zkSNARKs on Ethereum.
|
||||||
|
|
||||||
|
@ -17,13 +20,19 @@ Zokrates bridges this gap. It helps you create offchain programs and link them t
|
||||||
|
|
||||||
Using Docker is currently the recommended way to get started with Zokrates.
|
Using Docker is currently the recommended way to get started with Zokrates.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -ti kyroy/zokrates /bin/bash
|
||||||
```
|
```
|
||||||
|
Or build yourself with the following commands.
|
||||||
|
```bash
|
||||||
git clone https://github.com/JacobEberhardt/ZoKrates
|
git clone https://github.com/JacobEberhardt/ZoKrates
|
||||||
cd ZoKrates
|
cd ZoKrates
|
||||||
docker build -t zokrates .
|
docker build -t zokrates .
|
||||||
docker run -ti zokrates /bin/bash
|
docker run -ti zokrates /bin/bash
|
||||||
cd ZoKrates/target/release
|
cd ZoKrates/target/release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
# Example
|
# Example
|
||||||
|
|
||||||
To execute the program, perform the setup for the program, generate a proof
|
To execute the program, perform the setup for the program, generate a proof
|
||||||
|
|
2
build.rs
2
build.rs
|
@ -4,7 +4,7 @@ extern crate gcc;
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(not(feature = "nolibsnark"))]
|
#[cfg(not(feature = "nolibsnark"))]
|
||||||
{
|
{
|
||||||
gcc::Config::new()
|
gcc::Build::new()
|
||||||
.cpp(true)
|
.cpp(true)
|
||||||
.debug(true)
|
.debug(true)
|
||||||
.include("/usr/local/include")
|
.include("/usr/local/include")
|
||||||
|
|
|
@ -246,9 +246,9 @@ bool _setup(const uint8_t* A, const uint8_t* B, const uint8_t* C, int constraint
|
||||||
r1cs_constraint_system<Fr<alt_bn128_pp>> cs;
|
r1cs_constraint_system<Fr<alt_bn128_pp>> cs;
|
||||||
cs = createConstraintSystem(A, B ,C , constraints, variables, inputs);
|
cs = createConstraintSystem(A, B ,C , constraints, variables, inputs);
|
||||||
|
|
||||||
assert(cs.num_variables() >= inputs);
|
assert(cs.num_variables() >= (unsigned)inputs);
|
||||||
assert(cs.num_inputs() == inputs);
|
assert(cs.num_inputs() == (unsigned)inputs);
|
||||||
assert(cs.num_constraints() == constraints);
|
assert(cs.num_constraints() == (unsigned)constraints);
|
||||||
|
|
||||||
// create keypair
|
// create keypair
|
||||||
r1cs_ppzksnark_keypair<alt_bn128_pp> keypair = r1cs_ppzksnark_generator<alt_bn128_pp>(cs);
|
r1cs_ppzksnark_keypair<alt_bn128_pp> keypair = r1cs_ppzksnark_generator<alt_bn128_pp>(cs);
|
||||||
|
|
|
@ -39,15 +39,6 @@ impl Checker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
pub fn new_with_args(scope: HashSet<Symbol>, level: usize, functions: HashSet<FunctionDeclaration>) -> Checker {
|
|
||||||
Checker {
|
|
||||||
scope: scope,
|
|
||||||
functions: functions,
|
|
||||||
level: level,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check_program<T: Field>(&mut self, prog: Prog<T>) -> Result<(), String> {
|
pub fn check_program<T: Field>(&mut self, prog: Prog<T>) -> Result<(), String> {
|
||||||
for func in prog.functions {
|
for func in prog.functions {
|
||||||
self.check_function(&func)?;
|
self.check_function(&func)?;
|
||||||
|
@ -64,8 +55,8 @@ impl Checker {
|
||||||
fn check_single_main(&mut self) -> Result<(), String> {
|
fn check_single_main(&mut self) -> Result<(), String> {
|
||||||
match self.functions.clone().into_iter().filter(|fun| fun.id == "main").count() {
|
match self.functions.clone().into_iter().filter(|fun| fun.id == "main").count() {
|
||||||
1 => Ok(()),
|
1 => Ok(()),
|
||||||
0 => Err((format!("No main function found"))),
|
0 => Err(format!("No main function found")),
|
||||||
n => Err((format!("Only one main function allowed, found {}", n)))
|
n => Err(format!("Only one main function allowed, found {}", n))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +168,7 @@ impl Checker {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Expression::IfElse(box condition, box consequence, box alternative) => {
|
Expression::IfElse(box condition, box consequence, box alternative) => {
|
||||||
self.check_condition(condition)?;
|
self.check_condition(condition)?;
|
||||||
self.check_expression(consequence)?;
|
self.check_expression(consequence)?;
|
||||||
self.check_expression(alternative)?;
|
self.check_expression(alternative)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -232,6 +223,14 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use field::FieldPrime;
|
use field::FieldPrime;
|
||||||
|
|
||||||
|
pub fn new_with_args(scope: HashSet<Symbol>, level: usize, functions: HashSet<FunctionDeclaration>) -> Checker {
|
||||||
|
Checker {
|
||||||
|
scope: scope,
|
||||||
|
functions: functions,
|
||||||
|
level: level,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn undefined_variable_in_statement() {
|
fn undefined_variable_in_statement() {
|
||||||
// a = b
|
// a = b
|
||||||
|
@ -257,7 +256,7 @@ mod tests {
|
||||||
id: String::from("b"),
|
id: String::from("b"),
|
||||||
level: 0
|
level: 0
|
||||||
});
|
});
|
||||||
let mut checker = Checker::new_with_args(scope, 1, HashSet::new());
|
let mut checker = new_with_args(scope, 1, HashSet::new());
|
||||||
assert_eq!(checker.check_statement(statement), Ok(()));
|
assert_eq!(checker.check_statement(statement), Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +285,7 @@ mod tests {
|
||||||
bar_statements.push(Statement::Return(
|
bar_statements.push(Statement::Return(
|
||||||
ExpressionList {
|
ExpressionList {
|
||||||
expressions: vec![Expression::Identifier(String::from("a"))]
|
expressions: vec![Expression::Identifier(String::from("a"))]
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
let bar = Function {
|
let bar = Function {
|
||||||
id: "bar".to_string(),
|
id: "bar".to_string(),
|
||||||
|
@ -441,7 +440,7 @@ mod tests {
|
||||||
// c = foo()
|
// c = foo()
|
||||||
// should fail
|
// should fail
|
||||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::MultipleDefinition(
|
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::MultipleDefinition(
|
||||||
vec!["c".to_string()],
|
vec!["c".to_string()],
|
||||||
Expression::FunctionCall("foo".to_string(), vec![])
|
Expression::FunctionCall("foo".to_string(), vec![])
|
||||||
)];
|
)];
|
||||||
|
|
||||||
|
@ -461,8 +460,8 @@ mod tests {
|
||||||
return_count: 1
|
return_count: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, functions);
|
let mut checker = new_with_args(HashSet::new(), 0, functions);
|
||||||
assert_eq!(checker.check_function(bar), Err("foo returns 2 values but left side is of size 1".to_string()));
|
assert_eq!(checker.check_function(&bar), Err("foo returns 2 values but left side is of size 1".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -493,8 +492,8 @@ mod tests {
|
||||||
return_count: 1
|
return_count: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, functions);
|
let mut checker = new_with_args(HashSet::new(), 0, functions);
|
||||||
assert_eq!(checker.check_function(bar), Err("foo returns 2 values but is called outside of a definition".to_string()));
|
assert_eq!(checker.check_function(&bar), Err("foo returns 2 values but is called outside of a definition".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -503,7 +502,7 @@ mod tests {
|
||||||
// c = foo()
|
// c = foo()
|
||||||
// should fail
|
// should fail
|
||||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::MultipleDefinition(
|
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::MultipleDefinition(
|
||||||
vec!["c".to_string()],
|
vec!["c".to_string()],
|
||||||
Expression::FunctionCall("foo".to_string(), vec![])
|
Expression::FunctionCall("foo".to_string(), vec![])
|
||||||
)];
|
)];
|
||||||
|
|
||||||
|
@ -514,8 +513,8 @@ mod tests {
|
||||||
return_count: 1
|
return_count: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new());
|
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
|
||||||
assert_eq!(checker.check_function(bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string()));
|
assert_eq!(checker.check_function(&bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -524,7 +523,7 @@ mod tests {
|
||||||
// 1 = foo()
|
// 1 = foo()
|
||||||
// should fail
|
// should fail
|
||||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::Condition(
|
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::Condition(
|
||||||
Expression::Number(FieldPrime::from(1)),
|
Expression::Number(FieldPrime::from(1)),
|
||||||
Expression::FunctionCall("foo".to_string(), vec![])
|
Expression::FunctionCall("foo".to_string(), vec![])
|
||||||
)];
|
)];
|
||||||
|
|
||||||
|
@ -535,8 +534,8 @@ mod tests {
|
||||||
return_count: 1
|
return_count: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new());
|
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
|
||||||
assert_eq!(checker.check_function(bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string()));
|
assert_eq!(checker.check_function(&bar), Err("Function definition for function foo with 0 argument(s) not found.".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -558,8 +557,8 @@ mod tests {
|
||||||
return_count: 2
|
return_count: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, HashSet::new());
|
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
|
||||||
assert_eq!(checker.check_function(bar), Err("a is undefined".to_string()));
|
assert_eq!(checker.check_function(&bar), Err("a is undefined".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -573,13 +572,13 @@ mod tests {
|
||||||
// should pass
|
// should pass
|
||||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![
|
let bar_statements: Vec<Statement<FieldPrime>> = vec![
|
||||||
Statement::MultipleDefinition(
|
Statement::MultipleDefinition(
|
||||||
vec!["a".to_string(), "b".to_string()],
|
vec!["a".to_string(), "b".to_string()],
|
||||||
Expression::FunctionCall("foo".to_string(), vec![])
|
Expression::FunctionCall("foo".to_string(), vec![])
|
||||||
),
|
),
|
||||||
Statement::Return(
|
Statement::Return(
|
||||||
ExpressionList { expressions: vec![
|
ExpressionList { expressions: vec![
|
||||||
Expression::Add(
|
Expression::Add(
|
||||||
box Expression::Identifier("a".to_string()),
|
box Expression::Identifier("a".to_string()),
|
||||||
box Expression::Identifier("b".to_string())
|
box Expression::Identifier("b".to_string())
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
@ -602,7 +601,7 @@ mod tests {
|
||||||
return_count: 1
|
return_count: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, functions);
|
let mut checker = new_with_args(HashSet::new(), 0, functions);
|
||||||
assert_eq!(checker.check_function(&bar), Ok(()));
|
assert_eq!(checker.check_function(&bar), Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +615,7 @@ mod tests {
|
||||||
// should fail
|
// should fail
|
||||||
let foo2_statements: Vec<Statement<FieldPrime>> = vec![
|
let foo2_statements: Vec<Statement<FieldPrime>> = vec![
|
||||||
Statement::Return(
|
Statement::Return(
|
||||||
ExpressionList {
|
ExpressionList {
|
||||||
expressions: vec![
|
expressions: vec![
|
||||||
Expression::Number(FieldPrime::from(1))
|
Expression::Number(FieldPrime::from(1))
|
||||||
]
|
]
|
||||||
|
@ -625,7 +624,7 @@ mod tests {
|
||||||
];
|
];
|
||||||
|
|
||||||
let foo2_arguments = vec![
|
let foo2_arguments = vec![
|
||||||
Parameter { id: 'c'.to_string(), private: true },
|
Parameter { id: 'c'.to_string(), private: true },
|
||||||
Parameter { id: 'd'.to_string(), private: true }
|
Parameter { id: 'd'.to_string(), private: true }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -645,8 +644,8 @@ mod tests {
|
||||||
return_count: 1
|
return_count: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new_with_args(HashSet::new(), 0, functions);
|
let mut checker = new_with_args(HashSet::new(), 0, functions);
|
||||||
assert_eq!(checker.check_function(&foo2), Err(("Duplicate definition for function foo with 2 arguments".to_string())));
|
assert_eq!(checker.check_function(&foo2), Err("Duplicate definition for function foo with 2 arguments".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -659,7 +658,7 @@ mod tests {
|
||||||
// should fail
|
// should fail
|
||||||
let main1_statements: Vec<Statement<FieldPrime>> = vec![
|
let main1_statements: Vec<Statement<FieldPrime>> = vec![
|
||||||
Statement::Return(
|
Statement::Return(
|
||||||
ExpressionList {
|
ExpressionList {
|
||||||
expressions: vec![
|
expressions: vec![
|
||||||
Expression::Number(FieldPrime::from(1))
|
Expression::Number(FieldPrime::from(1))
|
||||||
]
|
]
|
||||||
|
@ -671,7 +670,7 @@ mod tests {
|
||||||
|
|
||||||
let main2_statements: Vec<Statement<FieldPrime>> = vec![
|
let main2_statements: Vec<Statement<FieldPrime>> = vec![
|
||||||
Statement::Return(
|
Statement::Return(
|
||||||
ExpressionList {
|
ExpressionList {
|
||||||
expressions: vec![
|
expressions: vec![
|
||||||
Expression::Number(FieldPrime::from(1))
|
Expression::Number(FieldPrime::from(1))
|
||||||
]
|
]
|
||||||
|
@ -700,6 +699,6 @@ mod tests {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut checker = Checker::new();
|
let mut checker = Checker::new();
|
||||||
assert_eq!(checker.check_program(prog), Err(("Only one main function allowed, found 2".to_string())));
|
assert_eq!(checker.check_program(prog), Err("Only one main function allowed, found 2".to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue