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

merge develop

This commit is contained in:
dark64 2020-10-05 13:50:04 +02:00
commit 4cfedfb79d
26 changed files with 830 additions and 571 deletions

View file

@ -26,10 +26,11 @@ let jsonContractSource = JSON.stringify({
});
let jsonInterface = JSON.parse(solc.compile(jsonContractSource));
console.log(jsonInterface);
(async () => {
const accounts = await web3.eth.getAccounts();
let abi = jsonInterface.contracts[contractPath]["Verifier"].abi
let bytecode = jsonInterface.contracts[contractPath]["Verifier"].evm.bytecode
let abi = jsonInterface.contracts[contractPath]["Verifier"].abi;
let bytecode = jsonInterface.contracts[contractPath]["Verifier"].evm.bytecode;
//There is a solc issue, that for unknown reasons wont link the BN256G2 Library automatically for gm17 v1 and v2 contracts. I dont know why this is happening,
//the contracts compile and deploy without any issue on remix. To fix this, the the BN256G2 Library must be compiled and deployed by itself, after that,
@ -37,7 +38,7 @@ let jsonInterface = JSON.parse(solc.compile(jsonContractSource));
if (format == "gm17") {
let library = await deployLibrary();
//replace lib placeholder with lib address in bytecode
bytecode.object = bytecode.object.replace(/\_\_\$[a-f0-9]{34}\$\_\_/g, library["_address"].replace("0x", ""))
bytecode.object = bytecode.object.replace(/\_\_\$[a-f0-9]{34}\$\_\_/g, library["_address"].replace("0x", ""));
}
let contract = new web3.eth.Contract(abi)
@ -50,38 +51,38 @@ let jsonInterface = JSON.parse(solc.compile(jsonContractSource));
})
.on('receipt', (tx) => {
if (tx.status == true) {
console.log("Contract Deployed! Gas used: " + tx.gasUsed)
console.log("Contract Deployed! Gas used: " + tx.gasUsed);
}
})
.then(newContractInstance => {
contract = newContractInstance;
Promise.all([makeTransaction(accounts[0], true), makeTransaction(accounts[0], false)])
Promise.all([makeTransaction(accounts[0], true), makeTransaction(accounts[0], false)]);
})
.catch(err => {
console.log(err);
process.exit(1);
})
});
function makeTransaction(account, correct) {
let proof = getProof(correct);
function handleReceipt(tx) {
if (tx.status == true && !correct) {
console.log("Verification has been successful with invalid proof data! THIS IS A BUG")
process.exit(1)
console.log("Verification has been successful with invalid proof data! THIS IS A BUG");
process.exit(1);
}
if (tx.status == true) {
console.log("Correct proof works! Gas used: " + tx.gasUsed)
console.log("Correct proof works! Gas used: " + tx.gasUsed);
}
}
function handleError(err, correct) {
if (!correct) {
console.log("False proof not verified! Success")
console.log("False proof not verified! Success");
} else {
console.log(err);
process.exit(1)
process.exit(1);
}
}
@ -90,46 +91,40 @@ let jsonInterface = JSON.parse(solc.compile(jsonContractSource));
.catch(handleError)
:
verifyTx_ABIV2(proof, account, correct).on('receipt', handleReceipt)
.catch(handleError)
.catch(handleError);
}
function verifyTx_ABIV2(proof, account, correct) {
var args = proof[0];
args = proof[1].length > 0 ? [args, proof[1]] : [args];
var arguments = proof[0]
arguments = proof[1].length > 0 ? [arguments[0], proof[1]] : arguments
contract.methods.verifyTx(...arguments).send({
return contract.methods.verifyTx(...args).send({
from: account,
gas: 5000000
})
});
}
function verifyTx_ABIV1(proof, account, correct) {
var arguments = proof[0]
arguments = proof[1].length > 0 ? [...arguments, proof[1]] : arguments
var args = proof[0];
args = proof[1].length > 0 ? [...args, proof[1]] : args;
return contract.methods.verifyTx(
...arguments
...args
).send({
from: account,
gas: 5000000
})
});
}
function getProof(correct) {
let json = JSON.parse(fs.readFileSync(proofPath));
let inputs = json["inputs"];
let proof = json["proof"]
let proof = json["proof"];
//falsifies proof to check if verification fails
if (!correct) {
proof["a"][0] = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
}
if (abiVersion == "v1") {
return [Object.values(proof), Object.values(inputs)];
} else if (abiVersion == "v2") {
return [proof, inputs]
}
return [Object.values(proof), Object.values(inputs)];
}
//function used for deploying BN256G2 Library, used for gm17 only
@ -150,8 +145,8 @@ let jsonInterface = JSON.parse(solc.compile(jsonContractSource));
},
});
let jsonInterfaceBin = JSON.parse(solc.compile(jsonContractSourceBin));
let abiLib = jsonInterfaceBin.contracts["BN256G2"]["BN256G2"].abi
let bytecodeLib = jsonInterfaceBin.contracts["BN256G2"]['BN256G2'].evm.bytecode
let abiLib = jsonInterfaceBin.contracts["BN256G2"]["BN256G2"].abi;
let bytecodeLib = jsonInterfaceBin.contracts["BN256G2"]['BN256G2'].evm.bytecode;
return new web3.eth.Contract(abiLib)
.deploy({
data: '0x' + bytecodeLib.object
@ -165,6 +160,6 @@ let jsonInterface = JSON.parse(solc.compile(jsonContractSource));
console.log("Library couldn't be deployed");
process.exit(1);
}
})
});
}
})();

View file

@ -297,19 +297,39 @@ mod integration {
.succeeds()
.unwrap();
// TEST VERIFIER
if backend != "zexe" {
assert_cli::Assert::command(&[
"node",
"test.js",
verification_contract_path.to_str().unwrap(),
proof_path.to_str().unwrap(),
scheme,
"v1",
])
.current_dir(concat!(env!("OUT_DIR"), "/contract"))
.succeeds()
.unwrap();
for abi_version in &["v1", "v2"] {
// EXPORT-VERIFIER
assert_cli::Assert::command(&[
"../target/release/zokrates",
"export-verifier",
"-i",
verification_key_path.to_str().unwrap(),
"-o",
verification_contract_path.to_str().unwrap(),
"--backend",
backend,
"--proving-scheme",
scheme,
"-a",
abi_version,
])
.succeeds()
.unwrap();
// TEST VERIFIER
assert_cli::Assert::command(&[
"node",
"test.js",
verification_contract_path.to_str().unwrap(),
proof_path.to_str().unwrap(),
scheme,
abi_version,
])
.current_dir(concat!(env!("OUT_DIR"), "/contract"))
.succeeds()
.unwrap();
}
}
}
}

View file

@ -1,10 +1,12 @@
use absy;
use imports;
use zokrates_field::Field;
use num::ToPrimitive;
use num_bigint::BigUint;
use zokrates_pest_ast as pest;
impl<'ast, T: Field> From<pest::File<'ast>> for absy::Module<'ast, T> {
fn from(prog: pest::File<'ast>) -> absy::Module<T> {
impl<'ast> From<pest::File<'ast>> for absy::Module<'ast> {
fn from(prog: pest::File<'ast>) -> absy::Module<'ast> {
absy::Module::with_symbols(
prog.structs
.into_iter()
@ -20,7 +22,7 @@ impl<'ast, T: Field> From<pest::File<'ast>> for absy::Module<'ast, T> {
}
impl<'ast> From<pest::ImportDirective<'ast>> for absy::ImportNode<'ast> {
fn from(import: pest::ImportDirective<'ast>) -> absy::ImportNode {
fn from(import: pest::ImportDirective<'ast>) -> absy::ImportNode<'ast> {
use absy::NodeValue;
match import {
@ -44,8 +46,8 @@ impl<'ast> From<pest::ImportDirective<'ast>> for absy::ImportNode<'ast> {
}
}
impl<'ast, T: Field> From<pest::StructDefinition<'ast>> for absy::SymbolDeclarationNode<'ast, T> {
fn from(definition: pest::StructDefinition<'ast>) -> absy::SymbolDeclarationNode<'ast, T> {
impl<'ast> From<pest::StructDefinition<'ast>> for absy::SymbolDeclarationNode<'ast> {
fn from(definition: pest::StructDefinition<'ast>) -> absy::SymbolDeclarationNode<'ast> {
use absy::NodeValue;
let span = definition.span;
@ -83,8 +85,8 @@ impl<'ast> From<pest::StructField<'ast>> for absy::StructDefinitionFieldNode<'as
}
}
impl<'ast, T: Field> From<pest::Function<'ast>> for absy::SymbolDeclarationNode<'ast, T> {
fn from(function: pest::Function<'ast>) -> absy::SymbolDeclarationNode<T> {
impl<'ast> From<pest::Function<'ast>> for absy::SymbolDeclarationNode<'ast> {
fn from(function: pest::Function<'ast>) -> absy::SymbolDeclarationNode<'ast> {
use absy::NodeValue;
let span = function.span;
@ -109,7 +111,7 @@ impl<'ast, T: Field> From<pest::Function<'ast>> for absy::SymbolDeclarationNode<
let id = function.id.span.as_str();
let function = absy::Function::<T> {
let function = absy::Function {
arguments: function
.parameters
.into_iter()
@ -133,7 +135,7 @@ impl<'ast, T: Field> From<pest::Function<'ast>> for absy::SymbolDeclarationNode<
}
impl<'ast> From<pest::Parameter<'ast>> for absy::ParameterNode<'ast> {
fn from(param: pest::Parameter<'ast>) -> absy::ParameterNode {
fn from(param: pest::Parameter<'ast>) -> absy::ParameterNode<'ast> {
use absy::NodeValue;
let private = param
@ -154,9 +156,7 @@ impl<'ast> From<pest::Parameter<'ast>> for absy::ParameterNode<'ast> {
}
}
fn statements_from_statement<'ast, T: Field>(
statement: pest::Statement<'ast>,
) -> Vec<absy::StatementNode<T>> {
fn statements_from_statement(statement: pest::Statement) -> Vec<absy::StatementNode> {
match statement {
pest::Statement::Definition(s) => statements_from_definition(s),
pest::Statement::Iteration(s) => vec![absy::StatementNode::from(s)],
@ -165,9 +165,7 @@ fn statements_from_statement<'ast, T: Field>(
}
}
fn statements_from_definition<'ast, T: Field>(
definition: pest::DefinitionStatement<'ast>,
) -> Vec<absy::StatementNode<T>> {
fn statements_from_definition(definition: pest::DefinitionStatement) -> Vec<absy::StatementNode> {
use absy::NodeValue;
let lhs = definition.lhs;
@ -177,7 +175,7 @@ fn statements_from_definition<'ast, T: Field>(
// Definition or assignment
let a = lhs[0].clone();
let e: absy::ExpressionNode<T> = absy::ExpressionNode::from(definition.expression);
let e: absy::ExpressionNode = absy::ExpressionNode::from(definition.expression);
let s = match e.value {
absy::Expression::FunctionCall(..) => absy::Statement::MultipleDefinition(
@ -240,8 +238,8 @@ fn statements_from_definition<'ast, T: Field>(
}
}
impl<'ast, T: Field> From<pest::ReturnStatement<'ast>> for absy::StatementNode<'ast, T> {
fn from(statement: pest::ReturnStatement<'ast>) -> absy::StatementNode<T> {
impl<'ast> From<pest::ReturnStatement<'ast>> for absy::StatementNode<'ast> {
fn from(statement: pest::ReturnStatement<'ast>) -> absy::StatementNode<'ast> {
use absy::NodeValue;
absy::Statement::Return(
@ -258,8 +256,8 @@ impl<'ast, T: Field> From<pest::ReturnStatement<'ast>> for absy::StatementNode<'
}
}
impl<'ast, T: Field> From<pest::AssertionStatement<'ast>> for absy::StatementNode<'ast, T> {
fn from(statement: pest::AssertionStatement<'ast>) -> absy::StatementNode<T> {
impl<'ast> From<pest::AssertionStatement<'ast>> for absy::StatementNode<'ast> {
fn from(statement: pest::AssertionStatement<'ast>) -> absy::StatementNode<'ast> {
use absy::NodeValue;
absy::Statement::Assertion(absy::ExpressionNode::from(statement.expression))
@ -267,14 +265,14 @@ impl<'ast, T: Field> From<pest::AssertionStatement<'ast>> for absy::StatementNod
}
}
impl<'ast, T: Field> From<pest::IterationStatement<'ast>> for absy::StatementNode<'ast, T> {
fn from(statement: pest::IterationStatement<'ast>) -> absy::StatementNode<T> {
impl<'ast> From<pest::IterationStatement<'ast>> for absy::StatementNode<'ast> {
fn from(statement: pest::IterationStatement<'ast>) -> absy::StatementNode<'ast> {
use absy::NodeValue;
let from = absy::ExpressionNode::from(statement.from);
let to = absy::ExpressionNode::from(statement.to);
let index = statement.index.span.as_str();
let ty = absy::UnresolvedTypeNode::from(statement.ty);
let statements: Vec<absy::StatementNode<T>> = statement
let statements: Vec<absy::StatementNode<'ast>> = statement
.statements
.into_iter()
.flat_map(|s| statements_from_statement(s))
@ -286,8 +284,8 @@ impl<'ast, T: Field> From<pest::IterationStatement<'ast>> for absy::StatementNod
}
}
impl<'ast, T: Field> From<pest::Expression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::Expression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::Expression<'ast>> for absy::ExpressionNode<'ast> {
fn from(expression: pest::Expression<'ast>) -> absy::ExpressionNode<'ast> {
match expression {
pest::Expression::Binary(e) => absy::ExpressionNode::from(e),
pest::Expression::Ternary(e) => absy::ExpressionNode::from(e),
@ -302,8 +300,8 @@ impl<'ast, T: Field> From<pest::Expression<'ast>> for absy::ExpressionNode<'ast,
}
}
impl<'ast, T: Field> From<pest::BinaryExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::BinaryExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::BinaryExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(expression: pest::BinaryExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
match expression.op {
pest::BinaryOperator::Add => absy::Expression::Add(
@ -387,8 +385,8 @@ impl<'ast, T: Field> From<pest::BinaryExpression<'ast>> for absy::ExpressionNode
}
}
impl<'ast, T: Field> From<pest::TernaryExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::TernaryExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::TernaryExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(expression: pest::TernaryExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
absy::Expression::IfElse(
box absy::ExpressionNode::from(*expression.first),
@ -399,8 +397,8 @@ impl<'ast, T: Field> From<pest::TernaryExpression<'ast>> for absy::ExpressionNod
}
}
impl<'ast, T: Field> From<pest::Spread<'ast>> for absy::SpreadNode<'ast, T> {
fn from(spread: pest::Spread<'ast>) -> absy::SpreadNode<'ast, T> {
impl<'ast> From<pest::Spread<'ast>> for absy::SpreadNode<'ast> {
fn from(spread: pest::Spread<'ast>) -> absy::SpreadNode<'ast> {
use absy::NodeValue;
absy::Spread {
expression: absy::ExpressionNode::from(spread.expression),
@ -409,8 +407,8 @@ impl<'ast, T: Field> From<pest::Spread<'ast>> for absy::SpreadNode<'ast, T> {
}
}
impl<'ast, T: Field> From<pest::Range<'ast>> for absy::RangeNode<'ast, T> {
fn from(range: pest::Range<'ast>) -> absy::RangeNode<'ast, T> {
impl<'ast> From<pest::Range<'ast>> for absy::RangeNode<'ast> {
fn from(range: pest::Range<'ast>) -> absy::RangeNode<'ast> {
use absy::NodeValue;
let from = range.from.map(|e| absy::ExpressionNode::from(e.0));
@ -421,10 +419,8 @@ impl<'ast, T: Field> From<pest::Range<'ast>> for absy::RangeNode<'ast, T> {
}
}
impl<'ast, T: Field> From<pest::RangeOrExpression<'ast>> for absy::RangeOrExpression<'ast, T> {
fn from(
range_or_expression: pest::RangeOrExpression<'ast>,
) -> absy::RangeOrExpression<'ast, T> {
impl<'ast> From<pest::RangeOrExpression<'ast>> for absy::RangeOrExpression<'ast> {
fn from(range_or_expression: pest::RangeOrExpression<'ast>) -> absy::RangeOrExpression<'ast> {
match range_or_expression {
pest::RangeOrExpression::Expression(e) => {
absy::RangeOrExpression::Expression(absy::ExpressionNode::from(e))
@ -436,10 +432,10 @@ impl<'ast, T: Field> From<pest::RangeOrExpression<'ast>> for absy::RangeOrExpres
}
}
impl<'ast, T: Field> From<pest::SpreadOrExpression<'ast>> for absy::SpreadOrExpression<'ast, T> {
impl<'ast> From<pest::SpreadOrExpression<'ast>> for absy::SpreadOrExpression<'ast> {
fn from(
spread_or_expression: pest::SpreadOrExpression<'ast>,
) -> absy::SpreadOrExpression<'ast, T> {
) -> absy::SpreadOrExpression<'ast> {
match spread_or_expression {
pest::SpreadOrExpression::Expression(e) => {
absy::SpreadOrExpression::Expression(absy::ExpressionNode::from(e))
@ -451,8 +447,8 @@ impl<'ast, T: Field> From<pest::SpreadOrExpression<'ast>> for absy::SpreadOrExpr
}
}
impl<'ast, T: Field> From<pest::InlineArrayExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(array: pest::InlineArrayExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::InlineArrayExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(array: pest::InlineArrayExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
absy::Expression::InlineArray(
array
@ -465,8 +461,8 @@ impl<'ast, T: Field> From<pest::InlineArrayExpression<'ast>> for absy::Expressio
}
}
impl<'ast, T: Field> From<pest::InlineStructExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(s: pest::InlineStructExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::InlineStructExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(s: pest::InlineStructExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
absy::Expression::InlineStruct(
s.ty.span.as_str().to_string(),
@ -484,16 +480,14 @@ impl<'ast, T: Field> From<pest::InlineStructExpression<'ast>> for absy::Expressi
}
}
impl<'ast, T: Field> From<pest::ArrayInitializerExpression<'ast>>
for absy::ExpressionNode<'ast, T>
{
fn from(initializer: pest::ArrayInitializerExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::ArrayInitializerExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(initializer: pest::ArrayInitializerExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
let value = absy::ExpressionNode::from(*initializer.value);
let count: absy::ExpressionNode<T> = absy::ExpressionNode::from(initializer.count);
let count: absy::ExpressionNode<'ast> = absy::ExpressionNode::from(initializer.count);
let count = match count.value {
absy::Expression::FieldConstant(v) => v.to_dec_string().parse::<usize>().unwrap(),
absy::Expression::FieldConstant(v) => v.to_usize().unwrap(),
_ => unreachable!(),
};
absy::Expression::InlineArray(vec![absy::SpreadOrExpression::Expression(value); count])
@ -501,8 +495,8 @@ impl<'ast, T: Field> From<pest::ArrayInitializerExpression<'ast>>
}
}
impl<'ast, T: Field> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(unary: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(unary: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
match unary.op {
@ -514,8 +508,8 @@ impl<'ast, T: Field> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<
}
}
impl<'ast, T: Field> From<pest::PostfixExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::PostfixExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::PostfixExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(expression: pest::PostfixExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
let id_str = expression.id.span.as_str();
@ -548,16 +542,17 @@ impl<'ast, T: Field> From<pest::PostfixExpression<'ast>> for absy::ExpressionNod
}
}
impl<'ast, T: Field> From<pest::ConstantExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::ConstantExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::ConstantExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(expression: pest::ConstantExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
match expression {
pest::ConstantExpression::BooleanLiteral(c) => {
absy::Expression::BooleanConstant(c.value.parse().unwrap()).span(c.span)
}
pest::ConstantExpression::DecimalNumber(n) => {
absy::Expression::FieldConstant(T::try_from_dec_str(&n.value).unwrap()).span(n.span)
}
pest::ConstantExpression::DecimalNumber(n) => absy::Expression::FieldConstant(
BigUint::parse_bytes(&n.value.as_bytes(), 10).unwrap(),
)
.span(n.span),
pest::ConstantExpression::U8(n) => absy::Expression::U8Constant(
u8::from_str_radix(&n.value.trim_start_matches("0x"), 16).unwrap(),
)
@ -574,23 +569,23 @@ impl<'ast, T: Field> From<pest::ConstantExpression<'ast>> for absy::ExpressionNo
}
}
impl<'ast, T: Field> From<pest::IdentifierExpression<'ast>> for absy::ExpressionNode<'ast, T> {
fn from(expression: pest::IdentifierExpression<'ast>) -> absy::ExpressionNode<'ast, T> {
impl<'ast> From<pest::IdentifierExpression<'ast>> for absy::ExpressionNode<'ast> {
fn from(expression: pest::IdentifierExpression<'ast>) -> absy::ExpressionNode<'ast> {
use absy::NodeValue;
absy::Expression::Identifier(expression.span.as_str()).span(expression.span)
}
}
impl<'ast, T: Field> From<pest::IdentifierExpression<'ast>> for absy::AssigneeNode<'ast, T> {
fn from(expression: pest::IdentifierExpression<'ast>) -> absy::AssigneeNode<T> {
impl<'ast> From<pest::IdentifierExpression<'ast>> for absy::AssigneeNode<'ast> {
fn from(expression: pest::IdentifierExpression<'ast>) -> absy::AssigneeNode<'ast> {
use absy::NodeValue;
absy::Assignee::Identifier(expression.span.as_str()).span(expression.span)
}
}
impl<'ast, T: Field> From<pest::Assignee<'ast>> for absy::AssigneeNode<'ast, T> {
fn from(assignee: pest::Assignee<'ast>) -> absy::AssigneeNode<T> {
impl<'ast> From<pest::Assignee<'ast>> for absy::AssigneeNode<'ast> {
fn from(assignee: pest::Assignee<'ast>) -> absy::AssigneeNode<'ast> {
use absy::NodeValue;
let a = absy::AssigneeNode::from(assignee.id);
@ -612,29 +607,28 @@ impl<'ast, T: Field> From<pest::Assignee<'ast>> for absy::AssigneeNode<'ast, T>
impl<'ast> From<pest::Type<'ast>> for absy::UnresolvedTypeNode {
fn from(t: pest::Type<'ast>) -> absy::UnresolvedTypeNode {
use absy::types::UnresolvedType;
use absy::NodeValue;
match t {
pest::Type::Basic(t) => match t {
pest::BasicType::Field(t) => absy::UnresolvedType::FieldElement.span(t.span),
pest::BasicType::Boolean(t) => absy::UnresolvedType::Boolean.span(t.span),
pest::BasicType::U8(t) => absy::UnresolvedType::Uint(8).span(t.span),
pest::BasicType::U16(t) => absy::UnresolvedType::Uint(16).span(t.span),
pest::BasicType::U32(t) => absy::UnresolvedType::Uint(32).span(t.span),
pest::BasicType::Field(t) => UnresolvedType::FieldElement.span(t.span),
pest::BasicType::Boolean(t) => UnresolvedType::Boolean.span(t.span),
pest::BasicType::U8(t) => UnresolvedType::Uint(8).span(t.span),
pest::BasicType::U16(t) => UnresolvedType::Uint(16).span(t.span),
pest::BasicType::U32(t) => UnresolvedType::Uint(32).span(t.span),
},
pest::Type::Array(t) => {
let inner_type = match t.ty {
pest::BasicOrStructType::Basic(t) => match t {
pest::BasicType::Field(t) => {
absy::UnresolvedType::FieldElement.span(t.span)
}
pest::BasicType::Boolean(t) => absy::UnresolvedType::Boolean.span(t.span),
pest::BasicType::U8(t) => absy::UnresolvedType::Uint(8).span(t.span),
pest::BasicType::U16(t) => absy::UnresolvedType::Uint(16).span(t.span),
pest::BasicType::U32(t) => absy::UnresolvedType::Uint(32).span(t.span),
pest::BasicType::Field(t) => UnresolvedType::FieldElement.span(t.span),
pest::BasicType::Boolean(t) => UnresolvedType::Boolean.span(t.span),
pest::BasicType::U8(t) => UnresolvedType::Uint(8).span(t.span),
pest::BasicType::U16(t) => UnresolvedType::Uint(16).span(t.span),
pest::BasicType::U32(t) => UnresolvedType::Uint(32).span(t.span),
},
pest::BasicOrStructType::Struct(t) => {
absy::UnresolvedType::User(t.span.as_str().to_string()).span(t.span)
UnresolvedType::User(t.span.as_str().to_string()).span(t.span)
}
};
@ -659,14 +653,14 @@ impl<'ast> From<pest::Type<'ast>> for absy::UnresolvedTypeNode {
})
.rev()
.fold(None, |acc, s| match acc {
None => Some(absy::UnresolvedType::array(inner_type.clone(), s)),
Some(acc) => Some(absy::UnresolvedType::array(acc.span(span.clone()), s)),
None => Some(UnresolvedType::array(inner_type.clone(), s)),
Some(acc) => Some(UnresolvedType::array(acc.span(span.clone()), s)),
})
.unwrap()
.span(span.clone())
}
pest::Type::Struct(s) => {
absy::UnresolvedType::User(s.id.span.as_str().to_string()).span(s.span)
UnresolvedType::User(s.id.span.as_str().to_string()).span(s.span)
}
}
}
@ -675,14 +669,14 @@ impl<'ast> From<pest::Type<'ast>> for absy::UnresolvedTypeNode {
#[cfg(test)]
mod tests {
use super::*;
use absy::types::{UnresolvedSignature, UnresolvedType};
use absy::NodeValue;
use zokrates_field::Bn128Field;
#[test]
fn return_forty_two() {
let source = "def main() -> field: return 42";
let ast = pest::generate_ast(&source).unwrap();
let expected: absy::Module<Bn128Field> = absy::Module {
let expected: absy::Module = absy::Module {
symbols: vec![absy::SymbolDeclaration {
id: &source[4..8],
symbol: absy::Symbol::HereFunction(
@ -690,17 +684,17 @@ mod tests {
arguments: vec![],
statements: vec![absy::Statement::Return(
absy::ExpressionList {
expressions: vec![absy::Expression::FieldConstant(
Bn128Field::from(42),
)
expressions: vec![absy::Expression::FieldConstant(BigUint::from(
42u32,
))
.into()],
}
.into(),
)
.into()],
signature: absy::UnresolvedSignature::new()
signature: UnresolvedSignature::new()
.inputs(vec![])
.outputs(vec![absy::UnresolvedType::FieldElement.mock()]),
.outputs(vec![UnresolvedType::FieldElement.mock()]),
}
.into(),
),
@ -708,14 +702,14 @@ mod tests {
.into()],
imports: vec![],
};
assert_eq!(absy::Module::<Bn128Field>::from(ast), expected);
assert_eq!(absy::Module::from(ast), expected);
}
#[test]
fn return_true() {
let source = "def main() -> bool: return true";
let ast = pest::generate_ast(&source).unwrap();
let expected: absy::Module<Bn128Field> = absy::Module {
let expected: absy::Module = absy::Module {
symbols: vec![absy::SymbolDeclaration {
id: &source[4..8],
symbol: absy::Symbol::HereFunction(
@ -728,9 +722,9 @@ mod tests {
.into(),
)
.into()],
signature: absy::UnresolvedSignature::new()
signature: UnresolvedSignature::new()
.inputs(vec![])
.outputs(vec![absy::UnresolvedType::Boolean.mock()]),
.outputs(vec![UnresolvedType::Boolean.mock()]),
}
.into(),
),
@ -738,7 +732,7 @@ mod tests {
.into()],
imports: vec![],
};
assert_eq!(absy::Module::<Bn128Field>::from(ast), expected);
assert_eq!(absy::Module::from(ast), expected);
}
#[test]
@ -746,7 +740,7 @@ mod tests {
let source = "def main(private field a, bool b) -> field: return 42";
let ast = pest::generate_ast(&source).unwrap();
let expected: absy::Module<Bn128Field> = absy::Module {
let expected: absy::Module = absy::Module {
symbols: vec![absy::SymbolDeclaration {
id: &source[4..8],
symbol: absy::Symbol::HereFunction(
@ -755,7 +749,7 @@ mod tests {
absy::Parameter::private(
absy::Variable::new(
&source[23..24],
absy::UnresolvedType::FieldElement.mock(),
UnresolvedType::FieldElement.mock(),
)
.into(),
)
@ -763,7 +757,7 @@ mod tests {
absy::Parameter::public(
absy::Variable::new(
&source[31..32],
absy::UnresolvedType::Boolean.mock(),
UnresolvedType::Boolean.mock(),
)
.into(),
)
@ -771,20 +765,20 @@ mod tests {
],
statements: vec![absy::Statement::Return(
absy::ExpressionList {
expressions: vec![absy::Expression::FieldConstant(
Bn128Field::from(42),
)
expressions: vec![absy::Expression::FieldConstant(BigUint::from(
42u32,
))
.into()],
}
.into(),
)
.into()],
signature: absy::UnresolvedSignature::new()
signature: UnresolvedSignature::new()
.inputs(vec![
absy::UnresolvedType::FieldElement.mock(),
absy::UnresolvedType::Boolean.mock(),
UnresolvedType::FieldElement.mock(),
UnresolvedType::Boolean.mock(),
])
.outputs(vec![absy::UnresolvedType::FieldElement.mock()]),
.outputs(vec![UnresolvedType::FieldElement.mock()]),
}
.into(),
),
@ -793,14 +787,14 @@ mod tests {
imports: vec![],
};
assert_eq!(absy::Module::<Bn128Field>::from(ast), expected);
assert_eq!(absy::Module::from(ast), expected);
}
mod types {
use super::*;
/// Helper method to generate the ast for `def main(private {ty} a): return` which we use to check ty
fn wrap(ty: absy::UnresolvedType) -> absy::Module<'static, Bn128Field> {
fn wrap(ty: UnresolvedType) -> absy::Module<'static> {
absy::Module {
symbols: vec![absy::SymbolDeclaration {
id: "main",
@ -817,7 +811,7 @@ mod tests {
.into(),
)
.into()],
signature: absy::UnresolvedSignature::new().inputs(vec![ty.mock()]),
signature: UnresolvedSignature::new().inputs(vec![ty.mock()]),
}
.into(),
),
@ -830,31 +824,24 @@ mod tests {
#[test]
fn array() {
let vectors = vec![
("field", absy::UnresolvedType::FieldElement),
("bool", absy::UnresolvedType::Boolean),
("field", UnresolvedType::FieldElement),
("bool", UnresolvedType::Boolean),
(
"field[2]",
absy::UnresolvedType::Array(box absy::UnresolvedType::FieldElement.mock(), 2),
UnresolvedType::Array(box UnresolvedType::FieldElement.mock(), 2),
),
(
"field[2][3]",
absy::UnresolvedType::Array(
box absy::UnresolvedType::Array(
box absy::UnresolvedType::FieldElement.mock(),
3,
)
.mock(),
UnresolvedType::Array(
box UnresolvedType::Array(box UnresolvedType::FieldElement.mock(), 3)
.mock(),
2,
),
),
(
"bool[2][3]",
absy::UnresolvedType::Array(
box absy::UnresolvedType::Array(
box absy::UnresolvedType::Boolean.mock(),
3,
)
.mock(),
UnresolvedType::Array(
box UnresolvedType::Array(box UnresolvedType::Boolean.mock(), 3).mock(),
2,
),
),
@ -864,14 +851,14 @@ mod tests {
let source = format!("def main(private {} a): return", ty);
let expected = wrap(expected);
let ast = pest::generate_ast(&source).unwrap();
assert_eq!(absy::Module::<Bn128Field>::from(ast), expected);
assert_eq!(absy::Module::from(ast), expected);
}
}
}
mod postfix {
use super::*;
fn wrap(expression: absy::Expression<'static, Bn128Field>) -> absy::Module<Bn128Field> {
fn wrap(expression: absy::Expression<'static>) -> absy::Module {
absy::Module {
symbols: vec![absy::SymbolDeclaration {
id: "main",
@ -885,7 +872,7 @@ mod tests {
.into(),
)
.into()],
signature: absy::UnresolvedSignature::new(),
signature: UnresolvedSignature::new(),
}
.into(),
),
@ -906,7 +893,7 @@ mod tests {
absy::Expression::Select(
box absy::Expression::Identifier("a").into(),
box absy::RangeOrExpression::Expression(
absy::Expression::FieldConstant(Bn128Field::from(3)).into(),
absy::Expression::FieldConstant(BigUint::from(3u32)).into(),
)
.into(),
),
@ -917,13 +904,13 @@ mod tests {
box absy::Expression::Select(
box absy::Expression::Identifier("a").into(),
box absy::RangeOrExpression::Expression(
absy::Expression::FieldConstant(Bn128Field::from(3)).into(),
absy::Expression::FieldConstant(BigUint::from(3u32)).into(),
)
.into(),
)
.into(),
box absy::RangeOrExpression::Expression(
absy::Expression::FieldConstant(Bn128Field::from(4)).into(),
absy::Expression::FieldConstant(BigUint::from(4u32)).into(),
)
.into(),
),
@ -933,11 +920,11 @@ mod tests {
absy::Expression::Select(
box absy::Expression::FunctionCall(
"a",
vec![absy::Expression::FieldConstant(Bn128Field::from(3)).into()],
vec![absy::Expression::FieldConstant(BigUint::from(3u32)).into()],
)
.into(),
box absy::RangeOrExpression::Expression(
absy::Expression::FieldConstant(Bn128Field::from(4)).into(),
absy::Expression::FieldConstant(BigUint::from(4u32)).into(),
)
.into(),
),
@ -948,17 +935,17 @@ mod tests {
box absy::Expression::Select(
box absy::Expression::FunctionCall(
"a",
vec![absy::Expression::FieldConstant(Bn128Field::from(3)).into()],
vec![absy::Expression::FieldConstant(BigUint::from(3u32)).into()],
)
.into(),
box absy::RangeOrExpression::Expression(
absy::Expression::FieldConstant(Bn128Field::from(4)).into(),
absy::Expression::FieldConstant(BigUint::from(4u32)).into(),
)
.into(),
)
.into(),
box absy::RangeOrExpression::Expression(
absy::Expression::FieldConstant(Bn128Field::from(5)).into(),
absy::Expression::FieldConstant(BigUint::from(5u32)).into(),
)
.into(),
),
@ -969,7 +956,7 @@ mod tests {
let source = format!("def main(): return {}", source);
let expected = wrap(expected);
let ast = pest::generate_ast(&source).unwrap();
assert_eq!(absy::Module::<Bn128Field>::from(ast), expected);
assert_eq!(absy::Module::from(ast), expected);
}
}
@ -979,7 +966,7 @@ mod tests {
// a call after an array access should be rejected
let source = "def main(): return a[2](3)";
let ast = pest::generate_ast(&source).unwrap();
absy::Module::<Bn128Field>::from(ast);
absy::Module::from(ast);
}
#[test]
@ -988,7 +975,7 @@ mod tests {
// a call after a call should be rejected
let source = "def main(): return a(2)(3)";
let ast = pest::generate_ast(&source).unwrap();
absy::Module::<Bn128Field>::from(ast);
absy::Module::from(ast);
}
}
#[test]
@ -1024,8 +1011,7 @@ mod tests {
span: span.clone(),
};
let statements: Vec<absy::StatementNode<Bn128Field>> =
statements_from_definition(definition);
let statements: Vec<absy::StatementNode> = statements_from_definition(definition);
assert_eq!(statements.len(), 1);
match &statements[0].value {
@ -1065,8 +1051,7 @@ mod tests {
span: span.clone(),
};
let statements: Vec<absy::StatementNode<Bn128Field>> =
statements_from_definition(definition);
let statements: Vec<absy::StatementNode> = statements_from_definition(definition);
assert_eq!(statements.len(), 1);
match &statements[0].value {
@ -1123,8 +1108,7 @@ mod tests {
span: span.clone(),
};
let statements: Vec<absy::StatementNode<Bn128Field>> =
statements_from_definition(definition);
let statements: Vec<absy::StatementNode> = statements_from_definition(definition);
assert_eq!(statements.len(), 2);
match &statements[1].value {

View file

@ -20,8 +20,8 @@ use std::path::PathBuf;
use crate::imports::ImportNode;
use std::fmt;
use zokrates_field::Field;
use num_bigint::BigUint;
use std::collections::HashMap;
/// An identifier of a function or a variable
@ -31,33 +31,33 @@ pub type Identifier<'ast> = &'ast str;
pub type ModuleId = PathBuf;
/// A collection of `Module`s
pub type Modules<'ast, T> = HashMap<ModuleId, Module<'ast, T>>;
pub type Modules<'ast> = HashMap<ModuleId, Module<'ast>>;
/// A collection of `SymbolDeclaration`. Duplicates are allowed here as they are fine syntactically.
pub type Declarations<'ast, T> = Vec<SymbolDeclarationNode<'ast, T>>;
pub type Declarations<'ast> = Vec<SymbolDeclarationNode<'ast>>;
/// A `Program` is a collection of `Module`s and an id of the main `Module`
pub struct Program<'ast, T> {
pub modules: HashMap<ModuleId, Module<'ast, T>>,
pub struct Program<'ast> {
pub modules: HashMap<ModuleId, Module<'ast>>,
pub main: ModuleId,
}
/// A declaration of a `FunctionSymbol`, be it from an import or a function definition
#[derive(PartialEq, Clone, Debug)]
pub struct SymbolDeclaration<'ast, T> {
pub struct SymbolDeclaration<'ast> {
pub id: Identifier<'ast>,
pub symbol: Symbol<'ast, T>,
pub symbol: Symbol<'ast>,
}
#[derive(PartialEq, Clone)]
pub enum Symbol<'ast, T> {
pub enum Symbol<'ast> {
HereType(StructDefinitionNode<'ast>),
HereFunction(FunctionNode<'ast, T>),
HereFunction(FunctionNode<'ast>),
There(SymbolImportNode<'ast>),
Flat(FlatEmbed),
}
impl<'ast, T: fmt::Debug> fmt::Debug for Symbol<'ast, T> {
impl<'ast> fmt::Debug for Symbol<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Symbol::HereType(t) => write!(f, "HereType({:?})", t),
@ -68,7 +68,7 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Symbol<'ast, T> {
}
}
impl<'ast, T: fmt::Display> fmt::Display for SymbolDeclaration<'ast, T> {
impl<'ast> fmt::Display for SymbolDeclaration<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.symbol {
Symbol::HereType(ref t) => write!(f, "struct {} {}", self.id, t),
@ -81,18 +81,18 @@ impl<'ast, T: fmt::Display> fmt::Display for SymbolDeclaration<'ast, T> {
}
}
pub type SymbolDeclarationNode<'ast, T> = Node<SymbolDeclaration<'ast, T>>;
pub type SymbolDeclarationNode<'ast> = Node<SymbolDeclaration<'ast>>;
/// A module as a collection of `FunctionDeclaration`s
#[derive(Clone, PartialEq)]
pub struct Module<'ast, T> {
pub struct Module<'ast> {
/// Symbols of the module
pub symbols: Declarations<'ast, T>,
pub symbols: Declarations<'ast>,
pub imports: Vec<ImportNode<'ast>>, // we still use `imports` as they are not directly converted into `FunctionDeclaration`s after the importer is done, `imports` is empty
}
impl<'ast, T: Field> Module<'ast, T> {
pub fn with_symbols<I: IntoIterator<Item = SymbolDeclarationNode<'ast, T>>>(i: I) -> Self {
impl<'ast> Module<'ast> {
pub fn with_symbols<I: IntoIterator<Item = SymbolDeclarationNode<'ast>>>(i: I) -> Self {
Module {
symbols: i.into_iter().collect(),
imports: vec![],
@ -178,7 +178,7 @@ impl<'ast> fmt::Display for SymbolImport<'ast> {
}
}
impl<'ast, T: Field> fmt::Display for Module<'ast, T> {
impl<'ast> fmt::Display for Module<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut res = vec![];
res.extend(
@ -197,7 +197,7 @@ impl<'ast, T: Field> fmt::Display for Module<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for Module<'ast, T> {
impl<'ast> fmt::Debug for Module<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -218,18 +218,18 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Module<'ast, T> {
/// A function defined locally
#[derive(Clone, PartialEq)]
pub struct Function<'ast, T> {
pub struct Function<'ast> {
/// Arguments of the function
pub arguments: Vec<ParameterNode<'ast>>,
/// Vector of statements that are executed when running the function
pub statements: Vec<StatementNode<'ast, T>>,
pub statements: Vec<StatementNode<'ast>>,
/// function signature
pub signature: UnresolvedSignature,
}
pub type FunctionNode<'ast, T> = Node<Function<'ast, T>>;
pub type FunctionNode<'ast> = Node<Function<'ast>>;
impl<'ast, T: fmt::Display> fmt::Display for Function<'ast, T> {
impl<'ast> fmt::Display for Function<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -248,7 +248,7 @@ impl<'ast, T: fmt::Display> fmt::Display for Function<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for Function<'ast, T> {
impl<'ast> fmt::Debug for Function<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -265,15 +265,15 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Function<'ast, T> {
/// Something that we can assign to
#[derive(Clone, PartialEq)]
pub enum Assignee<'ast, T> {
pub enum Assignee<'ast> {
Identifier(Identifier<'ast>),
Select(Box<AssigneeNode<'ast, T>>, Box<RangeOrExpression<'ast, T>>),
Member(Box<AssigneeNode<'ast, T>>, Box<Identifier<'ast>>),
Select(Box<AssigneeNode<'ast>>, Box<RangeOrExpression<'ast>>),
Member(Box<AssigneeNode<'ast>>, Box<Identifier<'ast>>),
}
pub type AssigneeNode<'ast, T> = Node<Assignee<'ast, T>>;
pub type AssigneeNode<'ast> = Node<Assignee<'ast>>;
impl<'ast, T: fmt::Debug> fmt::Debug for Assignee<'ast, T> {
impl<'ast> fmt::Debug for Assignee<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Assignee::Identifier(ref s) => write!(f, "Identifier({:?})", s),
@ -283,7 +283,7 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Assignee<'ast, T> {
}
}
impl<'ast, T: fmt::Display> fmt::Display for Assignee<'ast, T> {
impl<'ast> fmt::Display for Assignee<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Assignee::Identifier(ref s) => write!(f, "{}", s),
@ -295,23 +295,23 @@ impl<'ast, T: fmt::Display> fmt::Display for Assignee<'ast, T> {
/// A statement in a `Function`
#[derive(Clone, PartialEq)]
pub enum Statement<'ast, T> {
Return(ExpressionListNode<'ast, T>),
pub enum Statement<'ast> {
Return(ExpressionListNode<'ast>),
Declaration(VariableNode<'ast>),
Definition(AssigneeNode<'ast, T>, ExpressionNode<'ast, T>),
Assertion(ExpressionNode<'ast, T>),
Definition(AssigneeNode<'ast>, ExpressionNode<'ast>),
Assertion(ExpressionNode<'ast>),
For(
VariableNode<'ast>,
ExpressionNode<'ast, T>,
ExpressionNode<'ast, T>,
Vec<StatementNode<'ast, T>>,
ExpressionNode<'ast>,
ExpressionNode<'ast>,
Vec<StatementNode<'ast>>,
),
MultipleDefinition(Vec<AssigneeNode<'ast, T>>, ExpressionNode<'ast, T>),
MultipleDefinition(Vec<AssigneeNode<'ast>>, ExpressionNode<'ast>),
}
pub type StatementNode<'ast, T> = Node<Statement<'ast, T>>;
pub type StatementNode<'ast> = Node<Statement<'ast>>;
impl<'ast, T: fmt::Display> fmt::Display for Statement<'ast, T> {
impl<'ast> fmt::Display for Statement<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Return(ref expr) => write!(f, "return {}", expr),
@ -338,7 +338,7 @@ impl<'ast, T: fmt::Display> fmt::Display for Statement<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for Statement<'ast, T> {
impl<'ast> fmt::Debug for Statement<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Statement::Return(ref expr) => write!(f, "Return({:?})", expr),
@ -363,18 +363,18 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Statement<'ast, T> {
/// An element of an inline array, can be a spread `...a` or an expression `a`
#[derive(Clone, PartialEq)]
pub enum SpreadOrExpression<'ast, T> {
Spread(SpreadNode<'ast, T>),
Expression(ExpressionNode<'ast, T>),
pub enum SpreadOrExpression<'ast> {
Spread(SpreadNode<'ast>),
Expression(ExpressionNode<'ast>),
}
impl<'ast, T: Field> From<ExpressionNode<'ast, T>> for SpreadOrExpression<'ast, T> {
fn from(e: ExpressionNode<'ast, T>) -> SpreadOrExpression<'ast, T> {
impl<'ast> From<ExpressionNode<'ast>> for SpreadOrExpression<'ast> {
fn from(e: ExpressionNode<'ast>) -> SpreadOrExpression<'ast> {
SpreadOrExpression::Expression(e)
}
}
impl<'ast, T: fmt::Display> fmt::Display for SpreadOrExpression<'ast, T> {
impl<'ast> fmt::Display for SpreadOrExpression<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
SpreadOrExpression::Spread(ref s) => write!(f, "{}", s),
@ -383,7 +383,7 @@ impl<'ast, T: fmt::Display> fmt::Display for SpreadOrExpression<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for SpreadOrExpression<'ast, T> {
impl<'ast> fmt::Debug for SpreadOrExpression<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
SpreadOrExpression::Spread(ref s) => write!(f, "{:?}", s),
@ -394,12 +394,12 @@ impl<'ast, T: fmt::Debug> fmt::Debug for SpreadOrExpression<'ast, T> {
/// The index in an array selector. Can be a range or an expression.
#[derive(Clone, PartialEq)]
pub enum RangeOrExpression<'ast, T> {
Range(RangeNode<'ast, T>),
Expression(ExpressionNode<'ast, T>),
pub enum RangeOrExpression<'ast> {
Range(RangeNode<'ast>),
Expression(ExpressionNode<'ast>),
}
impl<'ast, T: fmt::Display> fmt::Display for RangeOrExpression<'ast, T> {
impl<'ast> fmt::Display for RangeOrExpression<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
RangeOrExpression::Range(ref s) => write!(f, "{}", s),
@ -408,7 +408,7 @@ impl<'ast, T: fmt::Display> fmt::Display for RangeOrExpression<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for RangeOrExpression<'ast, T> {
impl<'ast> fmt::Debug for RangeOrExpression<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
RangeOrExpression::Range(ref s) => write!(f, "{:?}", s),
@ -417,15 +417,15 @@ impl<'ast, T: fmt::Debug> fmt::Debug for RangeOrExpression<'ast, T> {
}
}
pub type SpreadNode<'ast, T> = Node<Spread<'ast, T>>;
pub type SpreadNode<'ast> = Node<Spread<'ast>>;
impl<'ast, T: fmt::Display> fmt::Display for Spread<'ast, T> {
impl<'ast> fmt::Display for Spread<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "...{}", self.expression)
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for Spread<'ast, T> {
impl<'ast> fmt::Debug for Spread<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Spread({:?})", self.expression)
}
@ -433,20 +433,20 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Spread<'ast, T> {
/// A spread
#[derive(Clone, PartialEq)]
pub struct Spread<'ast, T> {
pub expression: ExpressionNode<'ast, T>,
pub struct Spread<'ast> {
pub expression: ExpressionNode<'ast>,
}
/// A range
#[derive(Clone, PartialEq)]
pub struct Range<'ast, T> {
pub from: Option<ExpressionNode<'ast, T>>,
pub to: Option<ExpressionNode<'ast, T>>,
pub struct Range<'ast> {
pub from: Option<ExpressionNode<'ast>>,
pub to: Option<ExpressionNode<'ast>>,
}
pub type RangeNode<'ast, T> = Node<Range<'ast, T>>;
pub type RangeNode<'ast> = Node<Range<'ast>>;
impl<'ast, T: fmt::Display> fmt::Display for Range<'ast, T> {
impl<'ast> fmt::Display for Range<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
@ -463,7 +463,7 @@ impl<'ast, T: fmt::Display> fmt::Display for Range<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for Range<'ast, T> {
impl<'ast> fmt::Debug for Range<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Range({:?}, {:?})", self.from, self.to)
}
@ -471,52 +471,49 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Range<'ast, T> {
/// An expression
#[derive(Clone, PartialEq)]
pub enum Expression<'ast, T> {
FieldConstant(T),
pub enum Expression<'ast> {
FieldConstant(BigUint),
BooleanConstant(bool),
U8Constant(u8),
U16Constant(u16),
U32Constant(u32),
Identifier(Identifier<'ast>),
Add(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Sub(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Mult(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Div(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Pow(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Add(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Sub(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Mult(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Div(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Pow(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
IfElse(
Box<ExpressionNode<'ast, T>>,
Box<ExpressionNode<'ast, T>>,
Box<ExpressionNode<'ast, T>>,
Box<ExpressionNode<'ast>>,
Box<ExpressionNode<'ast>>,
Box<ExpressionNode<'ast>>,
),
FunctionCall(FunctionIdentifier<'ast>, Vec<ExpressionNode<'ast, T>>),
Lt(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Le(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Eq(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Ge(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Gt(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
And(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
Not(Box<ExpressionNode<'ast, T>>),
InlineArray(Vec<SpreadOrExpression<'ast, T>>),
InlineStruct(UserTypeId, Vec<(Identifier<'ast>, ExpressionNode<'ast, T>)>),
Select(
Box<ExpressionNode<'ast, T>>,
Box<RangeOrExpression<'ast, T>>,
),
Member(Box<ExpressionNode<'ast, T>>, Box<Identifier<'ast>>),
Or(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
BitXor(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
BitAnd(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
BitOr(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
LeftShift(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
RightShift(Box<ExpressionNode<'ast, T>>, Box<ExpressionNode<'ast, T>>),
FunctionCall(FunctionIdentifier<'ast>, Vec<ExpressionNode<'ast>>),
Lt(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Le(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Eq(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Ge(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Gt(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
And(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
Not(Box<ExpressionNode<'ast>>),
InlineArray(Vec<SpreadOrExpression<'ast>>),
InlineStruct(UserTypeId, Vec<(Identifier<'ast>, ExpressionNode<'ast>)>),
Select(Box<ExpressionNode<'ast>>, Box<RangeOrExpression<'ast>>),
Member(Box<ExpressionNode<'ast>>, Box<Identifier<'ast>>),
Or(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
BitXor(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
BitAnd(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
BitOr(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
LeftShift(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
RightShift(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
}
pub type ExpressionNode<'ast, T> = Node<Expression<'ast, T>>;
pub type ExpressionNode<'ast> = Node<Expression<'ast>>;
impl<'ast, T: fmt::Display> fmt::Display for Expression<'ast, T> {
impl<'ast> fmt::Display for Expression<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expression::FieldConstant(ref i) => write!(f, "{}", i),
Expression::FieldConstant(ref i) => write!(f, "{}", i.to_str_radix(10)),
Expression::U8Constant(ref i) => write!(f, "{}", i),
Expression::U16Constant(ref i) => write!(f, "{}", i),
Expression::U32Constant(ref i) => write!(f, "{}", i),
@ -581,7 +578,7 @@ impl<'ast, T: fmt::Display> fmt::Display for Expression<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for Expression<'ast, T> {
impl<'ast> fmt::Debug for Expression<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expression::U8Constant(ref i) => write!(f, "{:x}", i),
@ -640,21 +637,21 @@ impl<'ast, T: fmt::Debug> fmt::Debug for Expression<'ast, T> {
/// A list of expressions, used in return statements
#[derive(Clone, PartialEq)]
pub struct ExpressionList<'ast, T> {
pub expressions: Vec<ExpressionNode<'ast, T>>,
pub struct ExpressionList<'ast> {
pub expressions: Vec<ExpressionNode<'ast>>,
}
pub type ExpressionListNode<'ast, T> = Node<ExpressionList<'ast, T>>;
pub type ExpressionListNode<'ast> = Node<ExpressionList<'ast>>;
impl<'ast, T> ExpressionList<'ast, T> {
pub fn new() -> ExpressionList<'ast, T> {
impl<'ast> ExpressionList<'ast> {
pub fn new() -> ExpressionList<'ast> {
ExpressionList {
expressions: vec![],
}
}
}
impl<'ast, T: fmt::Display> fmt::Display for ExpressionList<'ast, T> {
impl<'ast> fmt::Display for ExpressionList<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, param) in self.expressions.iter().enumerate() {
write!(f, "{}", param)?;
@ -666,7 +663,7 @@ impl<'ast, T: fmt::Display> fmt::Display for ExpressionList<'ast, T> {
}
}
impl<'ast, T: fmt::Debug> fmt::Debug for ExpressionList<'ast, T> {
impl<'ast> fmt::Debug for ExpressionList<'ast> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ExpressionList({:?})", self.expressions)
}

View file

@ -74,24 +74,24 @@ impl<V: NodeValue> From<V> for Node<V> {
use crate::absy::*;
use crate::imports::*;
use zokrates_field::Field;
use absy::types::UnresolvedType;
impl<'ast, T: fmt::Display + fmt::Debug + PartialEq> NodeValue for Expression<'ast, T> {}
impl<'ast, T: fmt::Display + fmt::Debug + PartialEq> NodeValue for ExpressionList<'ast, T> {}
impl<'ast, T: fmt::Display + fmt::Debug + PartialEq> NodeValue for Assignee<'ast, T> {}
impl<'ast, T: fmt::Display + fmt::Debug + PartialEq> NodeValue for Statement<'ast, T> {}
impl<'ast, T: Field> NodeValue for SymbolDeclaration<'ast, T> {}
impl<'ast> NodeValue for Expression<'ast> {}
impl<'ast> NodeValue for ExpressionList<'ast> {}
impl<'ast> NodeValue for Assignee<'ast> {}
impl<'ast> NodeValue for Statement<'ast> {}
impl<'ast> NodeValue for SymbolDeclaration<'ast> {}
impl NodeValue for UnresolvedType {}
impl<'ast> NodeValue for StructDefinition<'ast> {}
impl<'ast> NodeValue for StructDefinitionField<'ast> {}
impl<'ast, T: fmt::Display + fmt::Debug + PartialEq> NodeValue for Function<'ast, T> {}
impl<'ast, T: Field> NodeValue for Module<'ast, T> {}
impl<'ast> NodeValue for Function<'ast> {}
impl<'ast> NodeValue for Module<'ast> {}
impl<'ast> NodeValue for SymbolImport<'ast> {}
impl<'ast> NodeValue for Variable<'ast> {}
impl<'ast> NodeValue for Parameter<'ast> {}
impl<'ast> NodeValue for Import<'ast> {}
impl<'ast, T: fmt::Display + fmt::Debug + PartialEq> NodeValue for Spread<'ast, T> {}
impl<'ast, T: fmt::Display + fmt::Debug + PartialEq> NodeValue for Range<'ast, T> {}
impl<'ast> NodeValue for Spread<'ast> {}
impl<'ast> NodeValue for Range<'ast> {}
impl<T: PartialEq> PartialEq for Node<T> {
fn eq(&self, other: &Node<T>) -> bool {

View file

@ -189,7 +189,7 @@ fn check_with_arena<'ast, T: Field, E: Into<imports::Error>>(
arena: &'ast Arena<String>,
) -> Result<(ZirProgram<'ast, T>, Abi), CompileErrors> {
let source = arena.alloc(source);
let compiled = compile_program(source, location.clone(), resolver, &arena)?;
let compiled = compile_program::<T, E>(source, location.clone(), resolver, &arena)?;
// check semantics
let typed_ast = Checker::check(compiled).map_err(|errors| {
@ -209,10 +209,10 @@ pub fn compile_program<'ast, T: Field, E: Into<imports::Error>>(
location: FilePath,
resolver: Option<&dyn Resolver<E>>,
arena: &'ast Arena<String>,
) -> Result<Program<'ast, T>, CompileErrors> {
) -> Result<Program<'ast>, CompileErrors> {
let mut modules = HashMap::new();
let main = compile_module(&source, location.clone(), resolver, &mut modules, &arena)?;
let main = compile_module::<T, E>(&source, location.clone(), resolver, &mut modules, &arena)?;
modules.insert(location.clone(), main);
@ -226,18 +226,18 @@ pub fn compile_module<'ast, T: Field, E: Into<imports::Error>>(
source: &'ast str,
location: FilePath,
resolver: Option<&dyn Resolver<E>>,
modules: &mut HashMap<ModuleId, Module<'ast, T>>,
modules: &mut HashMap<ModuleId, Module<'ast>>,
arena: &'ast Arena<String>,
) -> Result<Module<'ast, T>, CompileErrors> {
) -> Result<Module<'ast>, CompileErrors> {
let ast = pest::generate_ast(&source)
.map_err(|e| CompileErrors::from(CompileErrorInner::from(e).in_file(&location)))?;
let ast = process_macros::<T>(ast)
.map_err(|e| CompileErrors::from(CompileErrorInner::from(e).in_file(&location)))?;
let module_without_imports: Module<T> = Module::from(ast);
let module_without_imports: Module = Module::from(ast);
Importer::new().apply_imports(
Importer::new().apply_imports::<T, E>(
module_without_imports,
location.clone(),
resolver,

View file

@ -134,12 +134,12 @@ impl Importer {
pub fn apply_imports<'ast, T: Field, E: Into<Error>>(
&self,
destination: Module<'ast, T>,
destination: Module<'ast>,
location: PathBuf,
resolver: Option<&dyn Resolver<E>>,
modules: &mut HashMap<ModuleId, Module<'ast, T>>,
modules: &mut HashMap<ModuleId, Module<'ast>>,
arena: &'ast Arena<String>,
) -> Result<Module<'ast, T>, CompileErrors> {
) -> Result<Module<'ast>, CompileErrors> {
let mut symbols: Vec<_> = vec![];
for import in destination.imports {
@ -259,7 +259,7 @@ impl Importer {
None => {
let source = arena.alloc(source);
let compiled = compile_module(
let compiled = compile_module::<T, E>(
source,
new_location.clone(),
resolver,

View file

@ -13,7 +13,8 @@ impl SolidityAbi {
}
}
pub const SOLIDITY_G2_ADDITION_LIB: &str = r#"// This file is LGPL3 Licensed
pub const SOLIDITY_G2_ADDITION_LIB: &str = r#"// SPDX-License-Identifier: LGPL-3.0-only
// This file is LGPL3 Licensed
pragma solidity ^0.6.1;
/**
@ -450,7 +451,7 @@ library Pairing {
return G1Point(p.X, q - (p.Y % q));
}
/// @return r the sum of two points of G1
function addition(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) {
function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {
uint[4] memory input;
input[0] = p1.X;
input[1] = p1.Y;
@ -458,14 +459,14 @@ library Pairing {
input[3] = p2.Y;
bool success;
assembly {
success := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60)
success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
require(success);
}
/// @return r the sum of two points of G2
function addition(G2Point memory p1, G2Point memory p2) internal returns (G2Point memory r) {
function addition(G2Point memory p1, G2Point memory p2) internal view returns (G2Point memory r) {
(r.X[1], r.X[0], r.Y[1], r.Y[0]) = BN256G2.ECTwistAdd(p1.X[1],p1.X[0],p1.Y[1],p1.Y[0],p2.X[1],p2.X[0],p2.Y[1],p2.Y[0]);
}
/// @return r the product of a point on G1 and a scalar, i.e.
@ -477,7 +478,7 @@ library Pairing {
input[2] = s;
bool success;
assembly {
success := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60)
success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
@ -487,7 +488,7 @@ library Pairing {
/// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1
/// For example pairing([P1(), P1().negate()], [P2(), P2()]) should
/// return true.
function pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) {
function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) {
require(p1.length == p2.length);
uint elements = p1.length;
uint inputSize = elements * 6;
@ -504,7 +505,7 @@ library Pairing {
uint[1] memory out;
bool success;
assembly {
success := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
@ -512,7 +513,7 @@ library Pairing {
return out[0] != 0;
}
/// Convenience method for a pairing check for two pairs.
function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal returns (bool) {
function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](2);
G2Point[] memory p2 = new G2Point[](2);
p1[0] = a1;
@ -526,7 +527,7 @@ library Pairing {
G1Point memory a1, G2Point memory a2,
G1Point memory b1, G2Point memory b2,
G1Point memory c1, G2Point memory c2
) internal returns (bool) {
) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](3);
G2Point[] memory p2 = new G2Point[](3);
p1[0] = a1;
@ -543,7 +544,7 @@ library Pairing {
G1Point memory b1, G2Point memory b2,
G1Point memory c1, G2Point memory c2,
G1Point memory d1, G2Point memory d2
) internal returns (bool) {
) internal view returns (bool) {
G1Point[] memory p1 = new G1Point[](4);
G2Point[] memory p2 = new G2Point[](4);
p1[0] = a1;

View file

@ -48,7 +48,7 @@ type TypeMap = HashMap<ModuleId, HashMap<UserTypeId, Type>>;
#[derive(Debug)]
struct State<'ast, T: Field> {
/// The modules yet to be checked, which we consume as we explore the dependency tree
modules: Modules<'ast, T>,
modules: Modules<'ast>,
/// The already checked modules, which we're returning at the end
typed_modules: TypedModules<'ast, T>,
/// The user-defined types, which we keep track at this phase only. In later phases, we rely only on basic types and combinations thereof
@ -104,7 +104,7 @@ impl SymbolUnifier {
}
impl<'ast, T: Field> State<'ast, T> {
fn new(modules: Modules<'ast, T>) -> Self {
fn new(modules: Modules<'ast>) -> Self {
State {
modules,
typed_modules: HashMap::new(),
@ -242,13 +242,13 @@ impl<'ast> Checker<'ast> {
/// # Arguments
///
/// * `prog` - The `Program` to be checked
pub fn check<T: Field>(prog: Program<'ast, T>) -> Result<TypedProgram<'ast, T>, Vec<Error>> {
pub fn check<T: Field>(prog: Program<'ast>) -> Result<TypedProgram<'ast, T>, Vec<Error>> {
Checker::new().check_program(prog)
}
fn check_program<T: Field>(
&mut self,
program: Program<'ast, T>,
program: Program<'ast>,
) -> Result<TypedProgram<'ast, T>, Vec<Error>> {
let mut state = State::new(program.modules);
@ -330,7 +330,7 @@ impl<'ast> Checker<'ast> {
fn check_symbol_declaration<T: Field>(
&mut self,
declaration: SymbolDeclarationNode<'ast, T>,
declaration: SymbolDeclarationNode<'ast>,
module_id: &ModuleId,
state: &mut State<'ast, T>,
functions: &mut HashMap<FunctionKey<'ast>, TypedFunctionSymbol<'ast, T>>,
@ -642,7 +642,7 @@ impl<'ast> Checker<'ast> {
fn check_function<T: Field>(
&mut self,
funct_node: FunctionNode<'ast, T>,
funct_node: FunctionNode<'ast>,
module_id: &ModuleId,
types: &TypeMap,
) -> Result<TypedFunction<'ast, T>, Vec<ErrorInner>> {
@ -826,7 +826,7 @@ impl<'ast> Checker<'ast> {
fn check_statement<T: Field>(
&mut self,
stat: StatementNode<'ast, T>,
stat: StatementNode<'ast>,
module_id: &ModuleId,
types: &TypeMap,
) -> Result<TypedStatement<'ast, T>, Vec<ErrorInner>> {
@ -964,7 +964,7 @@ impl<'ast> Checker<'ast> {
Expression::FunctionCall(fun_id, arguments) => {
// check lhs assignees are defined
let (assignees, errors): (Vec<_>, Vec<_>) = assignees.into_iter().map(|a| self.check_assignee(a, module_id, types)).partition(|r| r.is_ok());
let (assignees, errors): (Vec<_>, Vec<_>) = assignees.into_iter().map(|a| self.check_assignee::<T>(a, module_id, types)).partition(|r| r.is_ok());
if errors.len() > 0 {
return Err(errors.into_iter().map(|e| e.unwrap_err()).collect());
@ -1024,7 +1024,7 @@ impl<'ast> Checker<'ast> {
fn check_assignee<T: Field>(
&mut self,
assignee: AssigneeNode<'ast, T>,
assignee: AssigneeNode<'ast>,
module_id: &ModuleId,
types: &TypeMap,
) -> Result<TypedAssignee<'ast, T>, ErrorInner> {
@ -1112,7 +1112,7 @@ impl<'ast> Checker<'ast> {
fn check_spread_or_expression<T: Field>(
&mut self,
spread_or_expression: SpreadOrExpression<'ast, T>,
spread_or_expression: SpreadOrExpression<'ast>,
module_id: &ModuleId,
types: &TypeMap,
) -> Result<Vec<TypedExpression<'ast, T>>, ErrorInner> {
@ -1190,7 +1190,7 @@ impl<'ast> Checker<'ast> {
fn check_expression<T: Field>(
&mut self,
expr: ExpressionNode<'ast, T>,
expr: ExpressionNode<'ast>,
module_id: &ModuleId,
types: &TypeMap,
) -> Result<TypedExpression<'ast, T>, ErrorInner> {
@ -1411,7 +1411,17 @@ impl<'ast> Checker<'ast> {
}),
}
}
Expression::FieldConstant(n) => Ok(FieldElementExpression::Number(n).into()),
Expression::FieldConstant(n) => Ok(FieldElementExpression::Number(
T::try_from(n).map_err(|_| ErrorInner {
pos: Some(pos),
message: format!(
"Field constant not in the representable range [{}, {}]",
T::min_value(),
T::max_value()
),
})?,
)
.into()),
Expression::U8Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(8).into()),
Expression::U16Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(16).into()),
Expression::U32Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(32).into()),
@ -2320,13 +2330,47 @@ impl<'ast> Checker<'ast> {
mod tests {
use super::*;
use absy;
use num_bigint::BigUint;
use typed_absy;
use zokrates_field::Bn128Field;
const MODULE_ID: &str = "";
mod constants {
use super::*;
use num_bigint::BigUint;
use std::ops::Add;
#[test]
fn field_in_range() {
let types = HashMap::new();
let module_id = "".into();
let expr =
Expression::FieldConstant(BigUint::from(Bn128Field::max_value().to_biguint()))
.mock();
assert!(Checker::new()
.check_expression::<Bn128Field>(expr, &module_id, &types)
.is_ok());
}
#[test]
fn field_overflow() {
let types = HashMap::new();
let module_id = "".into();
let value = Bn128Field::max_value().to_biguint().add(1u32);
let expr = Expression::FieldConstant(BigUint::from(value)).mock();
assert!(Checker::new()
.check_expression::<Bn128Field>(expr, &module_id, &types)
.is_err());
}
}
mod array {
use super::*;
use num_bigint::BigUint;
#[test]
fn element_type_mismatch() {
@ -2334,36 +2378,36 @@ mod tests {
let module_id = "".into();
// [3, true]
let a = Expression::InlineArray(vec![
Expression::FieldConstant(Bn128Field::from(3)).mock().into(),
Expression::FieldConstant(BigUint::from(3u32)).mock().into(),
Expression::BooleanConstant(true).mock().into(),
])
.mock();
assert!(Checker::new()
.check_expression(a, &module_id, &types)
.check_expression::<Bn128Field>(a, &module_id, &types)
.is_err());
// [[0], [0, 0]]
let a = Expression::InlineArray(vec![
Expression::InlineArray(vec![Expression::FieldConstant(Bn128Field::from(0))
Expression::InlineArray(vec![Expression::FieldConstant(BigUint::from(0u32))
.mock()
.into()])
.mock()
.into(),
Expression::InlineArray(vec![
Expression::FieldConstant(Bn128Field::from(0)).mock().into(),
Expression::FieldConstant(Bn128Field::from(0)).mock().into(),
Expression::FieldConstant(BigUint::from(0u32)).mock().into(),
Expression::FieldConstant(BigUint::from(0u32)).mock().into(),
])
.mock()
.into(),
])
.mock();
assert!(Checker::new()
.check_expression(a, &module_id, &types)
.check_expression::<Bn128Field>(a, &module_id, &types)
.is_err());
// [[0], true]
let a = Expression::InlineArray(vec![
Expression::InlineArray(vec![Expression::FieldConstant(Bn128Field::from(0))
Expression::InlineArray(vec![Expression::FieldConstant(BigUint::from(0u32))
.mock()
.into()])
.mock()
@ -2374,7 +2418,7 @@ mod tests {
])
.mock();
assert!(Checker::new()
.check_expression(a, &module_id, &types)
.check_expression::<Bn128Field>(a, &module_id, &types)
.is_err());
}
}
@ -2383,8 +2427,8 @@ mod tests {
use super::*;
/// Helper function to create ((): return)
fn function0() -> FunctionNode<'static, Bn128Field> {
let statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
fn function0() -> FunctionNode<'static> {
let statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![],
}
@ -2405,8 +2449,8 @@ mod tests {
}
/// Helper function to create ((private field a): return)
fn function1() -> FunctionNode<'static, Bn128Field> {
let statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
fn function1() -> FunctionNode<'static> {
let statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![],
}
@ -2474,7 +2518,7 @@ mod tests {
// after semantic check, `bar` should import a checked function
let foo: Module<Bn128Field> = Module {
let foo: Module = Module {
symbols: vec![SymbolDeclaration {
id: "main",
symbol: Symbol::HereFunction(function0()),
@ -2483,7 +2527,7 @@ mod tests {
imports: vec![],
};
let bar: Module<Bn128Field> = Module {
let bar: Module = Module {
symbols: vec![SymbolDeclaration {
id: "main",
symbol: Symbol::There(SymbolImport::with_id_in_module("main", "foo").mock()),
@ -2492,7 +2536,7 @@ mod tests {
imports: vec![],
};
let mut state = State::new(
let mut state = State::<Bn128Field>::new(
vec![("foo".into(), foo), ("bar".into(), bar)]
.into_iter()
.collect(),
@ -2542,7 +2586,7 @@ mod tests {
imports: vec![],
};
let mut state = State::new(
let mut state = State::<Bn128Field>::new(
vec![(PathBuf::from(MODULE_ID).into(), module)]
.into_iter()
.collect(),
@ -2584,7 +2628,7 @@ mod tests {
imports: vec![],
};
let mut state = State::new(
let mut state = State::<Bn128Field>::new(
vec![(PathBuf::from(MODULE_ID), module)]
.into_iter()
.collect(),
@ -2619,7 +2663,7 @@ mod tests {
//
// should fail
let module: Module<Bn128Field> = Module {
let module: Module = Module {
symbols: vec![
SymbolDeclaration {
id: "foo",
@ -2635,7 +2679,8 @@ mod tests {
imports: vec![],
};
let mut state = State::new(vec![("main".into(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![("main".into(), module)].into_iter().collect());
let mut checker = Checker::new();
assert_eq!(
@ -2672,7 +2717,8 @@ mod tests {
imports: vec![],
};
let mut state = State::new(vec![("main".into(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![("main".into(), module)].into_iter().collect());
let mut checker = Checker::new();
assert_eq!(
@ -2722,7 +2768,7 @@ mod tests {
imports: vec![],
};
let mut state = State::new(
let mut state = State::<Bn128Field>::new(
vec![(PathBuf::from(MODULE_ID), main), ("bar".into(), bar)]
.into_iter()
.collect(),
@ -2773,7 +2819,7 @@ mod tests {
imports: vec![],
};
let mut state = State::new(
let mut state = State::<Bn128Field>::new(
vec![(PathBuf::from(MODULE_ID), main), ("bar".into(), bar)]
.into_iter()
.collect(),
@ -2797,9 +2843,9 @@ mod tests {
functions: HashSet<FunctionKey<'ast>>,
) -> Checker<'ast> {
Checker {
scope: scope,
functions: functions,
level: level,
scope,
functions,
level,
}
}
@ -2807,7 +2853,7 @@ mod tests {
fn undefined_variable_in_statement() {
// a = b
// b undefined
let statement: StatementNode<Bn128Field> = Statement::Definition(
let statement: StatementNode = Statement::Definition(
Assignee::Identifier("a").mock(),
Expression::Identifier("b").mock(),
)
@ -2818,7 +2864,7 @@ mod tests {
let mut checker = Checker::new();
assert_eq!(
checker.check_statement(statement, &module_id, &types),
checker.check_statement::<Bn128Field>(statement, &module_id, &types),
Err(vec![ErrorInner {
pos: Some((Position::mock(), Position::mock())),
message: "Identifier \"b\" is undefined".into()
@ -2830,7 +2876,7 @@ mod tests {
fn defined_variable_in_statement() {
// a = b
// b defined
let statement: StatementNode<Bn128Field> = Statement::Definition(
let statement: StatementNode = Statement::Definition(
Assignee::Identifier("a").mock(),
Expression::Identifier("b").mock(),
)
@ -2850,7 +2896,7 @@ mod tests {
});
let mut checker = new_with_args(scope, 1, HashSet::new());
assert_eq!(
checker.check_statement(statement, &module_id, &types),
checker.check_statement::<Bn128Field>(statement, &module_id, &types),
Ok(TypedStatement::Definition(
TypedAssignee::Identifier(typed_absy::Variable::field_element("a")),
FieldElementExpression::Identifier("b".into()).into()
@ -2873,7 +2919,7 @@ mod tests {
.mock(),
Statement::Definition(
Assignee::Identifier("a").mock(),
Expression::FieldConstant(Bn128Field::from(1)).mock(),
Expression::FieldConstant(BigUint::from(1u32)).mock(),
)
.mock(),
];
@ -2923,7 +2969,8 @@ mod tests {
imports: vec![],
};
let mut state = State::new(vec![("main".into(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![("main".into(), module)].into_iter().collect());
let mut checker = Checker::new();
assert_eq!(
@ -2956,7 +3003,7 @@ mod tests {
.mock(),
Statement::Definition(
Assignee::Identifier("a").mock(),
Expression::FieldConstant(Bn128Field::from(1)).mock(),
Expression::FieldConstant(BigUint::from(1u32)).mock(),
)
.mock(),
];
@ -2979,7 +3026,7 @@ mod tests {
.mock(),
Statement::Definition(
Assignee::Identifier("a").mock(),
Expression::FieldConstant(Bn128Field::from(2)).mock(),
Expression::FieldConstant(BigUint::from(2u32)).mock(),
)
.mock(),
Statement::Return(
@ -3003,7 +3050,7 @@ mod tests {
let main_args = vec![];
let main_statements = vec![Statement::Return(
ExpressionList {
expressions: vec![Expression::FieldConstant(Bn128Field::from(1)).mock()],
expressions: vec![Expression::FieldConstant(BigUint::from(1u32)).mock()],
}
.mock(),
)
@ -3041,7 +3088,8 @@ mod tests {
imports: vec![],
};
let mut state = State::new(vec![("main".into(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![("main".into(), module)].into_iter().collect());
let mut checker = Checker::new();
assert!(checker.check_module(&"main".into(), &mut state).is_ok());
@ -3057,8 +3105,8 @@ mod tests {
let foo_statements = vec![
Statement::For(
absy::Variable::new("i", UnresolvedType::FieldElement.mock()).mock(),
Expression::FieldConstant(Bn128Field::from(0)).mock(),
Expression::FieldConstant(Bn128Field::from(10)).mock(),
Expression::FieldConstant(BigUint::from(0u32)).mock(),
Expression::FieldConstant(BigUint::from(10u32)).mock(),
vec![],
)
.mock(),
@ -3085,7 +3133,7 @@ mod tests {
let mut checker = Checker::new();
assert_eq!(
checker.check_function(foo, &module_id, &types),
checker.check_function::<Bn128Field>(foo, &module_id, &types),
Err(vec![ErrorInner {
pos: Some((Position::mock(), Position::mock())),
message: "Identifier \"i\" is undefined".into()
@ -3115,8 +3163,8 @@ mod tests {
let foo_statements = vec![Statement::For(
absy::Variable::new("i", UnresolvedType::FieldElement.mock()).mock(),
Expression::FieldConstant(Bn128Field::from(0)).mock(),
Expression::FieldConstant(Bn128Field::from(10)).mock(),
Expression::FieldConstant(BigUint::from(0u32)).mock(),
Expression::FieldConstant(BigUint::from(10u32)).mock(),
for_statements,
)
.mock()];
@ -3131,8 +3179,8 @@ mod tests {
let foo_statements_checked = vec![TypedStatement::For(
typed_absy::Variable::field_element("i"),
FieldElementExpression::Number(Bn128Field::from(0)),
FieldElementExpression::Number(Bn128Field::from(10)),
FieldElementExpression::Number(Bn128Field::from(0u32)),
FieldElementExpression::Number(Bn128Field::from(10u32)),
for_statements_checked,
)];
@ -3160,7 +3208,7 @@ mod tests {
let mut checker = Checker::new();
assert_eq!(
checker.check_function(foo, &module_id, &types),
checker.check_function::<Bn128Field>(foo, &module_id, &types),
Ok(foo_checked)
);
}
@ -3172,7 +3220,7 @@ mod tests {
// def bar():
// field a = foo()
// should fail
let bar_statements: Vec<StatementNode<Bn128Field>> = vec![
let bar_statements: Vec<StatementNode> = vec![
Statement::Declaration(
absy::Variable::new("a", UnresolvedType::FieldElement.mock()).mock(),
)
@ -3209,7 +3257,7 @@ mod tests {
let mut checker = new_with_args(HashSet::new(), 0, functions);
assert_eq!(
checker.check_function(bar, &module_id, &types),
checker.check_function::<Bn128Field>(bar, &module_id, &types),
Err(vec![ErrorInner {
pos: Some((Position::mock(), Position::mock())),
message:
@ -3226,9 +3274,9 @@ mod tests {
// def bar():
// 2 == foo()
// should fail
let bar_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Assertion(
let bar_statements: Vec<StatementNode> = vec![Statement::Assertion(
Expression::Eq(
box Expression::FieldConstant(Bn128Field::from(2)).mock(),
box Expression::FieldConstant(BigUint::from(2u32)).mock(),
box Expression::FunctionCall("foo", vec![]).mock(),
)
.mock(),
@ -3260,7 +3308,7 @@ mod tests {
let mut checker = new_with_args(HashSet::new(), 0, functions);
assert_eq!(
checker.check_function(bar, &module_id, &types),
checker.check_function::<Bn128Field>(bar, &module_id, &types),
Err(vec![ErrorInner {
pos: Some((Position::mock(), Position::mock())),
message: "Function definition for function foo with signature () -> _ not found."
@ -3274,7 +3322,7 @@ mod tests {
// def bar():
// field a = foo()
// should fail
let bar_statements: Vec<StatementNode<Bn128Field>> = vec![
let bar_statements: Vec<StatementNode> = vec![
Statement::Declaration(
absy::Variable::new("a", UnresolvedType::FieldElement.mock()).mock(),
)
@ -3301,7 +3349,7 @@ mod tests {
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
assert_eq!(
checker.check_function(bar, &module_id, &types),
checker.check_function::<Bn128Field>(bar, &module_id, &types),
Err(vec![ErrorInner {
pos: Some((Position::mock(), Position::mock())),
@ -3321,11 +3369,11 @@ mod tests {
// return 1
// should fail
let foo_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
let foo_statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![
Expression::FieldConstant(Bn128Field::from(1)).mock(),
Expression::FieldConstant(Bn128Field::from(2)).mock(),
Expression::FieldConstant(BigUint::from(1u32)).mock(),
Expression::FieldConstant(BigUint::from(2u32)).mock(),
],
}
.mock(),
@ -3349,7 +3397,7 @@ mod tests {
}
.mock();
let main_statements: Vec<StatementNode<Bn128Field>> = vec![
let main_statements: Vec<StatementNode> = vec![
Statement::Declaration(
absy::Variable::new("a", UnresolvedType::FieldElement.mock()).mock(),
)
@ -3368,7 +3416,7 @@ mod tests {
.mock(),
Statement::Return(
ExpressionList {
expressions: vec![Expression::FieldConstant(Bn128Field::from(1)).mock()],
expressions: vec![Expression::FieldConstant(BigUint::from(1u32)).mock()],
}
.mock(),
)
@ -3401,7 +3449,8 @@ mod tests {
imports: vec![],
};
let mut state = State::new(vec![("main".into(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![("main".into(), module)].into_iter().collect());
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
assert_eq!(
@ -3425,11 +3474,11 @@ mod tests {
// return 1
// should fail
let foo_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
let foo_statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![
Expression::FieldConstant(Bn128Field::from(1)).mock(),
Expression::FieldConstant(Bn128Field::from(2)).mock(),
Expression::FieldConstant(BigUint::from(1u32)).mock(),
Expression::FieldConstant(BigUint::from(2u32)).mock(),
],
}
.mock(),
@ -3449,7 +3498,7 @@ mod tests {
}
.mock();
let main_statements: Vec<StatementNode<Bn128Field>> = vec![
let main_statements: Vec<StatementNode> = vec![
Statement::MultipleDefinition(
vec![
Assignee::Identifier("a").mock(),
@ -3493,7 +3542,8 @@ mod tests {
imports: vec![],
};
let mut state = State::new(vec![("main".into(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![("main".into(), module)].into_iter().collect());
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
assert_eq!(
@ -3527,9 +3577,9 @@ mod tests {
// return
// should fail
let foo_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
let foo_statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![Expression::FieldConstant(Bn128Field::from(1)).mock()],
expressions: vec![Expression::FieldConstant(BigUint::from(1u32)).mock()],
}
.mock(),
)
@ -3545,7 +3595,7 @@ mod tests {
}
.mock();
let main_statements: Vec<StatementNode<Bn128Field>> = vec![
let main_statements: Vec<StatementNode> = vec![
Statement::Declaration(
absy::Variable::new(
"a",
@ -3557,7 +3607,7 @@ mod tests {
Statement::Definition(
Assignee::Identifier("a".into()).mock(),
Expression::InlineArray(vec![absy::SpreadOrExpression::Expression(
Expression::FieldConstant(Bn128Field::from(0)).mock(),
Expression::FieldConstant(BigUint::from(0u32)).mock(),
)])
.mock(),
)
@ -3566,7 +3616,7 @@ mod tests {
vec![Assignee::Select(
box Assignee::Identifier("a").mock(),
box RangeOrExpression::Expression(
absy::Expression::FieldConstant(Bn128Field::from(0)).mock(),
absy::Expression::FieldConstant(BigUint::from(0u32)).mock(),
),
)
.mock()],
@ -3608,7 +3658,8 @@ mod tests {
imports: vec![],
};
let mut state = State::new(vec![("main".into(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![("main".into(), module)].into_iter().collect());
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
assert_eq!(
@ -3628,9 +3679,9 @@ mod tests {
// def bar():
// 1 == foo()
// should fail
let bar_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Assertion(
let bar_statements: Vec<StatementNode> = vec![Statement::Assertion(
Expression::Eq(
box Expression::FieldConstant(Bn128Field::from(1)).mock(),
box Expression::FieldConstant(BigUint::from(1u32)).mock(),
box Expression::FunctionCall("foo", vec![]).mock(),
)
.mock(),
@ -3652,7 +3703,7 @@ mod tests {
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
assert_eq!(
checker.check_function(bar, &module_id, &types),
checker.check_function::<Bn128Field>(bar, &module_id, &types),
Err(vec![ErrorInner {
pos: Some((Position::mock(), Position::mock())),
@ -3667,7 +3718,7 @@ mod tests {
// def bar():
// return a, b
// should fail
let bar_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
let bar_statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![
Expression::Identifier("a").mock(),
@ -3696,7 +3747,7 @@ mod tests {
let mut checker = new_with_args(HashSet::new(), 0, HashSet::new());
assert_eq!(
checker.check_function(bar, &module_id, &types),
checker.check_function::<Bn128Field>(bar, &module_id, &types),
Err(vec![ErrorInner {
pos: Some((Position::mock(), Position::mock())),
message: "Identifier \"a\" is undefined".into()
@ -3713,7 +3764,7 @@ mod tests {
// return a + b
//
// should pass
let bar_statements: Vec<StatementNode<Bn128Field>> = vec![
let bar_statements: Vec<StatementNode> = vec![
Statement::Declaration(
absy::Variable::new("a", UnresolvedType::FieldElement.mock()).mock(),
)
@ -3814,9 +3865,9 @@ mod tests {
// return 1
//
// should fail
let main1_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
let main1_statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![Expression::FieldConstant(Bn128Field::from(1)).mock()],
expressions: vec![Expression::FieldConstant(BigUint::from(1u32)).mock()],
}
.mock(),
)
@ -3828,9 +3879,9 @@ mod tests {
}
.mock()];
let main2_statements: Vec<StatementNode<Bn128Field>> = vec![Statement::Return(
let main2_statements: Vec<StatementNode> = vec![Statement::Return(
ExpressionList {
expressions: vec![Expression::FieldConstant(Bn128Field::from(1)).mock()],
expressions: vec![Expression::FieldConstant(BigUint::from(1u32)).mock()],
}
.mock(),
)
@ -3883,7 +3934,7 @@ mod tests {
let mut checker = Checker::new();
assert_eq!(
checker.check_program(program),
checker.check_program::<Bn128Field>(program),
Err(vec![Error {
inner: ErrorInner {
pos: None,
@ -3976,7 +4027,7 @@ mod tests {
) -> (Checker<'static>, State<'static, Bn128Field>) {
let module_id: PathBuf = "".into();
let module: Module<Bn128Field> = Module {
let module: Module = Module {
imports: vec![],
symbols: vec![SymbolDeclaration {
id: "Foo",
@ -3985,7 +4036,8 @@ mod tests {
.mock()],
};
let mut state = State::new(vec![(module_id.clone(), module)].into_iter().collect());
let mut state =
State::<Bn128Field>::new(vec![(module_id.clone(), module)].into_iter().collect());
let mut checker = Checker::new();
@ -4158,7 +4210,7 @@ mod tests {
let module_id: PathBuf = "".into();
let module: Module<Bn128Field> = Module {
let module: Module = Module {
imports: vec![],
symbols: vec![
SymbolDeclaration {
@ -4192,7 +4244,9 @@ mod tests {
],
};
let mut state = State::new(vec![(module_id.clone(), module)].into_iter().collect());
let mut state = State::<Bn128Field>::new(
vec![(module_id.clone(), module)].into_iter().collect(),
);
assert!(Checker::new().check_module(&module_id, &mut state).is_ok());
assert_eq!(
@ -4225,7 +4279,7 @@ mod tests {
let module_id: PathBuf = "".into();
let module: Module<Bn128Field> = Module {
let module: Module = Module {
imports: vec![],
symbols: vec![SymbolDeclaration {
id: "Bar",
@ -4243,7 +4297,9 @@ mod tests {
.mock()],
};
let mut state = State::new(vec![(module_id.clone(), module)].into_iter().collect());
let mut state = State::<Bn128Field>::new(
vec![(module_id.clone(), module)].into_iter().collect(),
);
assert!(Checker::new().check_module(&module_id, &mut state).is_err());
}
@ -4256,7 +4312,7 @@ mod tests {
let module_id: PathBuf = "".into();
let module: Module<Bn128Field> = Module {
let module: Module = Module {
imports: vec![],
symbols: vec![SymbolDeclaration {
id: "Foo",
@ -4274,7 +4330,9 @@ mod tests {
.mock()],
};
let mut state = State::new(vec![(module_id.clone(), module)].into_iter().collect());
let mut state = State::<Bn128Field>::new(
vec![(module_id.clone(), module)].into_iter().collect(),
);
assert!(Checker::new().check_module(&module_id, &mut state).is_err());
}
@ -4288,7 +4346,7 @@ mod tests {
let module_id: PathBuf = "".into();
let module: Module<Bn128Field> = Module {
let module: Module = Module {
imports: vec![],
symbols: vec![
SymbolDeclaration {
@ -4322,7 +4380,9 @@ mod tests {
],
};
let mut state = State::new(vec![(module_id.clone(), module)].into_iter().collect());
let mut state = State::<Bn128Field>::new(
vec![(module_id.clone(), module)].into_iter().collect(),
);
assert!(Checker::new().check_module(&module_id, &mut state).is_err());
}
@ -4511,13 +4571,13 @@ mod tests {
});
assert_eq!(
checker.check_expression(
checker.check_expression::<Bn128Field>(
Expression::Member(
box Expression::InlineStruct(
"Foo".into(),
vec![(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
)]
)
.mock(),
@ -4529,7 +4589,7 @@ mod tests {
),
Ok(FieldElementExpression::Member(
box StructExpressionInner::Value(vec![FieldElementExpression::Number(
Bn128Field::from(42)
Bn128Field::from(42u32)
)
.into()])
.annotate(StructType::new(
@ -4560,13 +4620,13 @@ mod tests {
assert_eq!(
checker
.check_expression(
.check_expression::<Bn128Field>(
Expression::Member(
box Expression::InlineStruct(
"Foo".into(),
vec![(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
)]
)
.mock(),
@ -4601,12 +4661,12 @@ mod tests {
assert_eq!(
checker
.check_expression(
.check_expression::<Bn128Field>(
Expression::InlineStruct(
"Bar".into(),
vec![(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
)]
)
.mock(),
@ -4642,13 +4702,13 @@ mod tests {
});
assert_eq!(
checker.check_expression(
checker.check_expression::<Bn128Field>(
Expression::InlineStruct(
"Foo".into(),
vec![
(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
),
("bar", Expression::BooleanConstant(true).mock())
]
@ -4658,7 +4718,7 @@ mod tests {
&state.types
),
Ok(StructExpressionInner::Value(vec![
FieldElementExpression::Number(Bn128Field::from(42)).into(),
FieldElementExpression::Number(Bn128Field::from(42u32)).into(),
BooleanExpression::Value(true).into()
])
.annotate(StructType::new(
@ -4696,14 +4756,14 @@ mod tests {
});
assert_eq!(
checker.check_expression(
checker.check_expression::<Bn128Field>(
Expression::InlineStruct(
"Foo".into(),
vec![
("bar", Expression::BooleanConstant(true).mock()),
(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
)
]
)
@ -4712,7 +4772,7 @@ mod tests {
&state.types
),
Ok(StructExpressionInner::Value(vec![
FieldElementExpression::Number(Bn128Field::from(42)).into(),
FieldElementExpression::Number(Bn128Field::from(42u32)).into(),
BooleanExpression::Value(true).into()
])
.annotate(StructType::new(
@ -4751,12 +4811,12 @@ mod tests {
assert_eq!(
checker
.check_expression(
.check_expression::<Bn128Field>(
Expression::InlineStruct(
"Foo".into(),
vec![(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
)]
)
.mock(),
@ -4795,7 +4855,7 @@ mod tests {
assert_eq!(
checker
.check_expression(
.check_expression::<Bn128Field>(
Expression::InlineStruct(
"Foo".into(),
vec![(
@ -4803,7 +4863,7 @@ mod tests {
Expression::BooleanConstant(true).mock()
),(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
)]
)
.mock(),
@ -4816,17 +4876,17 @@ mod tests {
assert_eq!(
checker
.check_expression(
.check_expression::<Bn128Field>(
Expression::InlineStruct(
"Foo".into(),
vec![
(
"bar",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
),
(
"foo",
Expression::FieldConstant(Bn128Field::from(42)).mock()
Expression::FieldConstant(BigUint::from(42u32)).mock()
)
]
)
@ -4844,11 +4904,12 @@ mod tests {
mod assignee {
use super::*;
use num_bigint::BigUint;
#[test]
fn identifier() {
// a = 42
let a = Assignee::Identifier::<Bn128Field>("a").mock();
let a = Assignee::Identifier("a").mock();
let types = HashMap::new();
let module_id = "".into();
@ -4865,7 +4926,7 @@ mod tests {
.unwrap();
assert_eq!(
checker.check_assignee(a, &module_id, &types),
checker.check_assignee::<Bn128Field>(a, &module_id, &types),
Ok(TypedAssignee::Identifier(
typed_absy::Variable::field_element("a")
))
@ -4879,7 +4940,7 @@ mod tests {
let a = Assignee::Select(
box Assignee::Identifier("a").mock(),
box RangeOrExpression::Expression(
Expression::FieldConstant(Bn128Field::from(2)).mock(),
Expression::FieldConstant(BigUint::from(2u32)).mock(),
),
)
.mock();
@ -4904,10 +4965,10 @@ mod tests {
.unwrap();
assert_eq!(
checker.check_assignee(a, &module_id, &types),
checker.check_assignee::<Bn128Field>(a, &module_id, &types),
Ok(TypedAssignee::Select(
box TypedAssignee::Identifier(typed_absy::Variable::field_array("a", 33)),
box FieldElementExpression::Number(Bn128Field::from(2)).into()
box FieldElementExpression::Number(Bn128Field::from(2u32)).into()
))
);
}
@ -4920,12 +4981,12 @@ mod tests {
box Assignee::Select(
box Assignee::Identifier("a").mock(),
box RangeOrExpression::Expression(
Expression::FieldConstant(Bn128Field::from(1)).mock(),
Expression::FieldConstant(BigUint::from(1u32)).mock(),
),
)
.mock(),
box RangeOrExpression::Expression(
Expression::FieldConstant(Bn128Field::from(2)).mock(),
Expression::FieldConstant(BigUint::from(2u32)).mock(),
),
)
.mock();
@ -4954,7 +5015,7 @@ mod tests {
.unwrap();
assert_eq!(
checker.check_assignee(a, &module_id, &types),
checker.check_assignee::<Bn128Field>(a, &module_id, &types),
Ok(TypedAssignee::Select(
box TypedAssignee::Select(
box TypedAssignee::Identifier(typed_absy::Variable::array(
@ -4962,9 +5023,9 @@ mod tests {
Type::array(Type::FieldElement, 33),
42
)),
box FieldElementExpression::Number(Bn128Field::from(1)).into()
box FieldElementExpression::Number(Bn128Field::from(1u32)).into()
),
box FieldElementExpression::Number(Bn128Field::from(2)).into()
box FieldElementExpression::Number(Bn128Field::from(2u32)).into()
))
);
}

View file

@ -234,15 +234,7 @@ impl<'ast, T: Field> Inliner<'ast, T> {
Ok(res)
}
// if the function is a flat symbol, replace the call with a call to the local function we provide so it can be inlined in flattening
TypedFunctionSymbol::Flat(embed) => {
// increase the number of calls for this function by one
let _ = self
.call_count
.entry((self.module_id().clone(), embed.key::<T>().clone()))
.and_modify(|i| *i += 1)
.or_insert(1);
Err((embed.key::<T>(), expressions.clone()))
}
TypedFunctionSymbol::Flat(embed) => Err((embed.key::<T>(), expressions.clone())),
};
res.map(|exprs| {
@ -348,21 +340,38 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
TypedExpression::FieldElement(e) => e,
_ => unreachable!(),
},
Err((key, expressions)) => {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
.push(TypedStatement::MultipleDefinition(
vec![Variable::with_id_and_type(id.clone(), tys[0].clone())],
TypedExpressionList::FunctionCall(key, expressions, tys),
TypedExpressionList::FunctionCall(
key.clone(),
expressions.clone(),
tys,
),
));
self.call_cache_mut()
.entry(key.clone())
.or_insert_with(|| HashMap::new())
.insert(
expressions,
vec![FieldElementExpression::Identifier(id.clone()).into()],
);
FieldElementExpression::Identifier(id)
}
}
@ -385,14 +394,18 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
TypedExpression::Boolean(e) => e,
_ => unreachable!(),
},
Err((key, expressions)) => {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
@ -440,11 +453,15 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), embed_key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
@ -490,22 +507,38 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
TypedExpression::Struct(e) => e.into_inner(),
_ => unreachable!(),
},
Err((key, expressions)) => {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
.push(TypedStatement::MultipleDefinition(
vec![Variable::with_id_and_type(id.clone(), tys[0].clone())],
TypedExpressionList::FunctionCall(key, expressions, tys),
TypedExpressionList::FunctionCall(
key.clone(),
expressions.clone(),
tys,
),
));
StructExpressionInner::Identifier(id)
let out = StructExpressionInner::Identifier(id);
self.call_cache_mut()
.entry(key.clone())
.or_insert_with(|| HashMap::new())
.insert(expressions, vec![out.clone().annotate(ty.clone()).into()]);
out
}
}
}
@ -531,11 +564,15 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), embed_key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer

View file

@ -39,6 +39,7 @@ impl<'ast, T: Field> TypedProgram<'ast, T> {
pub fn analyse(self) -> ZirProgram<'ast, T> {
// propagated unrolling
let r = PropagatedUnroller::unroll(self).unwrap_or_else(|e| panic!(e));
// return binding
let r = ReturnBinder::bind(r);

View file

@ -319,7 +319,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
force_no_reduce(consequence),
force_no_reduce(alternative),
)
.with_max(max)
.with_max(T::try_from(max).unwrap())
}
};

View file

@ -32,7 +32,8 @@ mod tests {
use std::collections::HashMap;
use typed_absy::types::{ArrayType, FunctionKey, StructMember, StructType};
use typed_absy::{
Parameter, Type, TypedFunction, TypedFunctionSymbol, TypedModule, TypedProgram, Variable,
Parameter, Type, TypedFunction, TypedFunctionSymbol, TypedModule, TypedProgram, UBitwidth,
Variable,
};
use zokrates_field::Bn128Field;
@ -95,7 +96,9 @@ mod tests {
};
let json = serde_json::to_string(&abi).unwrap();
assert_eq!(&json, r#"{"inputs":[],"outputs":[]}"#)
assert_eq!(&json, r#"{"inputs":[],"outputs":[]}"#);
let de_abi: Abi = serde_json::from_str(json.as_ref()).unwrap();
assert_eq!(de_abi, abi);
}
#[test]
@ -138,7 +141,62 @@ mod tests {
}
]
}"#
)
);
let de_abi: Abi = serde_json::from_str(json.as_ref()).unwrap();
assert_eq!(de_abi, abi);
}
#[test]
fn serialize_uints() {
let abi: Abi = Abi {
inputs: vec![
AbiInput {
name: String::from("a"),
public: true,
ty: Type::Uint(UBitwidth::B8),
},
AbiInput {
name: String::from("b"),
public: true,
ty: Type::Uint(UBitwidth::B16),
},
AbiInput {
name: String::from("c"),
public: true,
ty: Type::Uint(UBitwidth::B32),
},
],
outputs: vec![],
};
let json = serde_json::to_string_pretty(&abi).unwrap();
assert_eq!(
&json,
r#"{
"inputs": [
{
"name": "a",
"public": true,
"type": "u8"
},
{
"name": "b",
"public": true,
"type": "u16"
},
{
"name": "c",
"public": true,
"type": "u32"
}
],
"outputs": []
}"#
);
let de_abi: Abi = serde_json::from_str(json.as_ref()).unwrap();
assert_eq!(de_abi, abi);
}
#[test]
@ -209,7 +267,10 @@ mod tests {
}
]
}"#
)
);
let de_abi: Abi = serde_json::from_str(json.as_ref()).unwrap();
assert_eq!(de_abi, abi);
}
#[test]
@ -272,7 +333,10 @@ mod tests {
],
"outputs": []
}"#
)
);
let de_abi: Abi = serde_json::from_str(json.as_ref()).unwrap();
assert_eq!(de_abi, abi);
}
#[test]
@ -330,7 +394,10 @@ mod tests {
}
]
}"#
)
);
let de_abi: Abi = serde_json::from_str(json.as_ref()).unwrap();
assert_eq!(de_abi, abi);
}
#[test]
@ -372,6 +439,9 @@ mod tests {
}
]
}"#
)
);
let de_abi: Abi = serde_json::from_str(json.as_ref()).unwrap();
assert_eq!(de_abi, abi);
}
}

View file

@ -6,7 +6,7 @@ use typed_absy::TypedModuleId;
pub enum CoreIdentifier<'ast> {
Source(&'ast str),
Internal(&'static str, usize),
Call(FunctionKey<'ast>),
Call(FunctionKey<'ast>, usize),
}
impl<'ast> fmt::Display for CoreIdentifier<'ast> {
@ -14,7 +14,7 @@ impl<'ast> fmt::Display for CoreIdentifier<'ast> {
match self {
CoreIdentifier::Source(s) => write!(f, "{}", s),
CoreIdentifier::Internal(s, i) => write!(f, "#INTERNAL#_{}_{}", s, i),
CoreIdentifier::Call(k) => write!(f, "{}", k.to_slug()),
CoreIdentifier::Call(k, i) => write!(f, "{}_{}", k.to_slug(), i),
}
}
}

View file

@ -5,7 +5,7 @@ pub type Identifier<'ast> = &'ast str;
pub type MemberId = String;
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct StructMember {
#[serde(rename = "name")]
pub id: MemberId,
@ -13,14 +13,14 @@ pub struct StructMember {
pub ty: Box<Type>,
}
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct ArrayType {
pub size: usize,
#[serde(flatten)]
pub ty: Box<Type>,
}
#[derive(Clone, Hash, Serialize, Deserialize, PartialOrd, Ord)]
#[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct StructType {
#[serde(skip)]
pub module: PathBuf,
@ -96,21 +96,112 @@ impl fmt::Display for UBitwidth {
}
}
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
#[serde(tag = "type", content = "components")]
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Type {
#[serde(rename = "field")]
FieldElement,
#[serde(rename = "bool")]
Boolean,
#[serde(rename = "array")]
Array(ArrayType),
#[serde(rename = "struct")]
Struct(StructType),
#[serde(rename = "u")]
Uint(UBitwidth),
}
impl Serialize for Type {
fn serialize<S>(&self, s: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer,
{
match self {
Type::FieldElement => s.serialize_newtype_variant("Type", 0, "type", "field"),
Type::Boolean => s.serialize_newtype_variant("Type", 1, "type", "bool"),
Type::Array(array_type) => {
let mut map = s.serialize_map(Some(2))?;
map.serialize_entry("type", "array")?;
map.serialize_entry("components", array_type)?;
map.end()
}
Type::Struct(struct_type) => {
let mut map = s.serialize_map(Some(2))?;
map.serialize_entry("type", "struct")?;
map.serialize_entry("components", struct_type)?;
map.end()
}
Type::Uint(width) => s.serialize_newtype_variant(
"Type",
4,
"type",
format!("u{}", width.to_usize()).as_str(),
),
}
}
}
impl<'de> Deserialize<'de> for Type {
fn deserialize<D>(d: D) -> Result<Self, <D as Deserializer<'de>>::Error>
where
D: Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum Components {
Array(ArrayType),
Struct(StructType),
}
#[derive(Debug, Deserialize)]
struct Mapping {
#[serde(rename = "type")]
ty: String,
components: Option<Components>,
}
let strict_type = |m: Mapping, ty: Type| -> Result<Self, <D as Deserializer<'de>>::Error> {
match m.components {
Some(_) => Err(D::Error::custom(format!(
"unexpected `components` field for type `{}`",
ty
))),
None => Ok(ty),
}
};
let mapping = Mapping::deserialize(d)?;
match mapping.ty.as_str() {
"field" => strict_type(mapping, Type::FieldElement),
"bool" => strict_type(mapping, Type::Boolean),
"array" => {
let components = mapping.components.ok_or(D::Error::custom(format_args!(
"missing `components` field for type `{}'",
mapping.ty
)))?;
match components {
Components::Array(array_type) => Ok(Type::Array(array_type)),
_ => Err(D::Error::custom(format!(
"invalid `components` variant for type `{}`",
mapping.ty
))),
}
}
"struct" => {
let components = mapping.components.ok_or(D::Error::custom(format_args!(
"missing `components` field for type `{}'",
mapping.ty
)))?;
match components {
Components::Struct(struct_type) => Ok(Type::Struct(struct_type)),
_ => Err(D::Error::custom(format!(
"invalid `components` variant for type `{}`",
mapping.ty
))),
}
}
"u8" => strict_type(mapping, Type::Uint(UBitwidth::B8)),
"u16" => strict_type(mapping, Type::Uint(UBitwidth::B16)),
"u32" => strict_type(mapping, Type::Uint(UBitwidth::B32)),
_ => Err(D::Error::custom(format!("invalid type `{}`", mapping.ty))),
}
}
}
impl ArrayType {
pub fn new(ty: Type, size: usize) -> Self {
ArrayType {
@ -250,6 +341,9 @@ impl<'ast> FunctionKey<'ast> {
}
pub use self::signature::Signature;
use serde::de::Error;
use serde::ser::SerializeMap;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub mod signature {
use super::*;

View file

@ -6,10 +6,12 @@ extern crate zokrates_field;
use wasm_bindgen_test::*;
use zokrates_core::flat_absy::FlatVariable;
use zokrates_core::ir::{Function, Interpreter, Prog, Statement};
use zokrates_core::proof_system::ProofSystem;
use zokrates_core::proof_system::{Backend, ProofSystem};
use zokrates_field::Bn128Field;
use zokrates_core::proof_system::bellman::groth16::G16;
use zokrates_core::proof_system::bellman::Bellman;
use zokrates_core::proof_system::scheme::groth16::G16;
#[wasm_bindgen_test]
fn generate_proof() {
@ -27,11 +29,11 @@ fn generate_proof() {
};
let interpreter = Interpreter::default();
let witness = interpreter
.execute(&program, &vec![Bn128Field::from(42)])
.unwrap();
let keys = G16::setup(program.clone());
let _proof = G16::generate_proof(program, witness, keys.pk);
let keypair = <Bellman as Backend<Bn128Field, G16>>::setup(program.clone());
let _proof =
<Bellman as Backend<Bn128Field, G16>>::generate_proof(program, witness, keypair.pk);
}

View file

@ -1,4 +1,4 @@
use algebra::bls12_377::{Bls12_377};
use algebra::bls12_377::Bls12_377;
prime_field!(
b"8444461749428370424248824938781546531375899335154063827935233455917409239041",

View file

@ -1,4 +1,4 @@
use algebra::bn254::{Bn254};
use algebra::bn254::Bn254;
use bellman_ce::pairing::bn256::{Bn256, Fq2};
prime_field!(

View file

@ -11,7 +11,7 @@ use bellman_ce::pairing::Engine;
use num_bigint::BigUint;
use num_traits::{One, Zero};
use serde::{Deserialize, Serialize};
use std::convert::From;
use std::convert::{From, TryFrom};
use std::fmt::{Debug, Display};
use std::hash::Hash;
use std::ops::{Add, Div, Mul, Sub};
@ -43,7 +43,7 @@ pub trait Field:
+ From<u32>
+ From<usize>
+ From<u128>
+ From<BigUint>
+ TryFrom<BigUint, Error = ()>
+ Zero
+ One
+ Clone
@ -131,6 +131,7 @@ mod prime_field {
use num_traits::{One, Zero};
use serde_derive::{Deserialize, Serialize};
use std::convert::From;
use std::convert::TryFrom;
use std::fmt;
use std::fmt::{Debug, Display};
use std::ops::{Add, Div, Mul, Sub};
@ -290,11 +291,16 @@ mod prime_field {
}
}
impl From<BigUint> for FieldPrime {
fn from(num: BigUint) -> Self {
let x = ToBigInt::to_bigint(&num).unwrap();
FieldPrime {
value: &x - x.div_floor(&*P) * &*P,
impl TryFrom<BigUint> for FieldPrime {
type Error = ();
fn try_from(value: BigUint) -> Result<Self, ()> {
match value <= Self::max_value().to_biguint() {
true => {
let x = ToBigInt::to_bigint(&value).unwrap();
Ok(FieldPrime { value: x })
}
false => Err(()),
}
}
}

View file

@ -4,7 +4,7 @@
// Note: parameters will be updated soon to be more compatible with zCash's implementation
struct BabyJubJubParams {
field JUBJUBE
// field JUBJUBE
field JUBJUBC
field JUBJUBA
field JUBJUBD
@ -18,7 +18,7 @@ struct BabyJubJubParams {
def main() -> BabyJubJubParams:
// Order of the curve E
field JUBJUBE = 21888242871839275222246405745257275088614511777268538073601725287587578984328
// field JUBJUBE = 21888242871839275222246405745257275088614511777268538073601725287587578984328
field JUBJUBC = 8 // Cofactor
field JUBJUBA = 168700 // Coefficient A
field JUBJUBD = 168696 // Coefficient D
@ -40,7 +40,7 @@ return BabyJubJubParams {
INFINITY: INFINITY,
Gu: Gu,
Gv: Gv,
JUBJUBE: JUBJUBE,
// JUBJUBE: JUBJUBE,
JUBJUBC: JUBJUBC,
MONTA: MONTA,
MONTB: MONTB

View file

@ -1,3 +1,4 @@
import "utils/multiplexer/lookup3bitSigned" as sel3s
import "utils/multiplexer/lookup2bit" as sel2
import "ecc/babyjubjubParams" as context
@ -15,35 +16,38 @@ import "EMBED/u32_from_bits" as from_bits
// #%%
// entropy = np.random.bytes(64)
// hasher = PedersenHasher("test")
// hasher.hash_bytes(entropy)
// print(hasher.dsl_code)
// 512bit to 256bit Pedersen hash using compression of the field elements
def main(u32[16] input) -> u32[8]:
bool[512] e = [ \
...to_bits(input[0]),
...to_bits(input[1]),
...to_bits(input[2]),
...to_bits(input[3]),
...to_bits(input[4]),
...to_bits(input[5]),
...to_bits(input[6]),
...to_bits(input[7]),
...to_bits(input[8]),
...to_bits(input[9]),
...to_bits(input[10]),
...to_bits(input[11]),
...to_bits(input[12]),
...to_bits(input[13]),
...to_bits(input[14]),
...to_bits(input[15])
def main(u32[16] inputs) -> u32[8]:
bool[513] e = [\
...to_bits(inputs[0]),
...to_bits(inputs[1]),
...to_bits(inputs[2]),
...to_bits(inputs[3]),
...to_bits(inputs[4]),
...to_bits(inputs[5]),
...to_bits(inputs[6]),
...to_bits(inputs[7]),
...to_bits(inputs[8]),
...to_bits(inputs[9]),
...to_bits(inputs[10]),
...to_bits(inputs[11]),
...to_bits(inputs[12]),
...to_bits(inputs[13]),
...to_bits(inputs[14]),
...to_bits(inputs[15]),
false
]
BabyJubJubParams context = context()
field[2] a = context.INFINITY //Infinity
field cx = 0
field cy = 0
//Round 0
field cx = sel3s([e[0], e[1], e[2]], [13418723823902222986275588345615650707197303761863176429873001977640541977977 , 8366451672790208592553809639953117385619257483837439526516290319251622927412, 1785026334726838136757054176272745265857971873904476677125553010508875025629, 15763987975760561753692294837740043971877392788040801334205375164715487005236])
field cy = sel2([e[0], e[1]], [15255921313433251341520743036334816584226787412845488772781699434149539664639 , 10916775373885716961512013142444429405184550001421868906213743991404593770484, 18533662942827602783563125901366807026309605479742251601915445402562880550265, 12754584346112149619040942896930712185968371085994381911052593922432846916845])
cx = sel3s([e[0], e[1], e[2]], [13418723823902222986275588345615650707197303761863176429873001977640541977977 , 8366451672790208592553809639953117385619257483837439526516290319251622927412, 1785026334726838136757054176272745265857971873904476677125553010508875025629, 15763987975760561753692294837740043971877392788040801334205375164715487005236])
cy = sel2([e[0], e[1]], [15255921313433251341520743036334816584226787412845488772781699434149539664639 , 10916775373885716961512013142444429405184550001421868906213743991404593770484, 18533662942827602783563125901366807026309605479742251601915445402562880550265, 12754584346112149619040942896930712185968371085994381911052593922432846916845])
a = add(a, [cx, cy], context)
//Round 1
cx = sel3s([e[3], e[4], e[5]], [10096735692467598736728394557736034054031417419721869067082824451240861468728 , 6979151010236415881632946866847657030447196774231162748523315765559549846746, 12137947022495312670974525048647679757468392619153927921382150023166867027471, 10624360821702266736197468438435445939719745367234393212061381062942588576905])
@ -722,19 +726,19 @@ def main(u32[16] input) -> u32[8]:
cy = sel2([e[507], e[508]], [18191174947339798787646910619446409943766046946921136035021645191602921923040 , 16559060177998758852323304784771936179434931576336411584121379336820727372618, 13858115732979799183025726471151602712224733686530960054365665740611187232029, 9933192519609817862698304326029579651414877338671776883175639003837130283966])
a = add(a, [cx, cy], context)
//Round 170
cx = sel3s([e[510], e[511], false], [3342564788366736273905106071612128667477972061160313630133110787799686301495 , 13766193863701503939885263345152684798552605679140222504700163745347162493183, 18523279471468319520962369406962457727155204375043681943707151819380964978377, 8094164074569624021939357073285075790695279643883973800173037824312344195506])
cx = sel3s([e[510], e[511], e[512]], [3342564788366736273905106071612128667477972061160313630133110787799686301495 , 13766193863701503939885263345152684798552605679140222504700163745347162493183, 18523279471468319520962369406962457727155204375043681943707151819380964978377, 8094164074569624021939357073285075790695279643883973800173037824312344195506])
cy = sel2([e[510], e[511]], [2329094643034533408459502544740928833981119919633412709248656884170940780093 , 3216329736050668550647765981020076413548845117352735257893224753954595290363, 18710403072495673647060422294369054840513840567808020912157404388689648711093, 9785201456176703812798077455183487364035650707229293534561747881523562553649])
a = add(a, [cx, cy], context)
bool[256] aC = edwardsCompress(a)
return [\
from_bits(aC[0..32]),
from_bits(aC[32..64]),
from_bits(aC[64..96]),
from_bits(aC[96..128]),
from_bits(aC[128..160]),
from_bits(aC[160..192]),
from_bits(aC[192..224]),
from_bits(aC[0..32]),
from_bits(aC[32..64]),
from_bits(aC[64..96]),
from_bits(aC[96..128]),
from_bits(aC[128..160]),
from_bits(aC[160..192]),
from_bits(aC[192..224]),
from_bits(aC[224..256])
]

View file

@ -3,7 +3,4 @@ import "hashes/mimc7/mimc7R10"
def main():
assert(mimc7R10(0, 0) == 6004544488495356385698286530147974336054653445122716140990101827963729149289)
assert(mimc7R10(100, 0) == 2977550761518141183167168643824354554080911485709001361112529600968315693145)
assert(mimc7R10(100, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 2977550761518141183167168643824354554080911485709001361112529600968315693145)
assert(mimc7R10(21888242871839275222246405745257275088548364400416034343698204186575808495618, 1) == 11476724043755138071320043459606423473319855817296339514744600646762741571430)
assert(mimc7R10(21888242871839275222246405745257275088548364400416034343698204186575808495617, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 6004544488495356385698286530147974336054653445122716140990101827963729149289)
return

View file

@ -3,7 +3,4 @@ import "hashes/mimc7/mimc7R20"
def main():
assert(mimc7R20(0, 0) == 19139739902058628561064841933381604453445216873412991992755775746150759284829)
assert(mimc7R20(100, 0) == 8623418512398828792274158979964869393034224267928014534933203776818702139758)
assert(mimc7R20(100, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 8623418512398828792274158979964869393034224267928014534933203776818702139758)
assert(mimc7R20(21888242871839275222246405745257275088548364400416034343698204186575808495618, 1) == 15315177265066649795408805007175121550344555424263995530745989936206840798041)
assert(mimc7R20(21888242871839275222246405745257275088548364400416034343698204186575808495617, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 19139739902058628561064841933381604453445216873412991992755775746150759284829)
return

View file

@ -3,7 +3,4 @@ import "hashes/mimc7/mimc7R50"
def main():
assert(mimc7R50(0, 0) == 3049953358280347916081509186284461274525472221619157672645224540758481713173)
assert(mimc7R50(100, 0) == 18511388995652647480418174218630545482006454713617579894396683237092568946789)
assert(mimc7R50(100, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 18511388995652647480418174218630545482006454713617579894396683237092568946789)
assert(mimc7R50(21888242871839275222246405745257275088548364400416034343698204186575808495618, 1) == 9149577627043020462780389988155990926223727917856424056384664564191878439702)
assert(mimc7R50(21888242871839275222246405745257275088548364400416034343698204186575808495617, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 3049953358280347916081509186284461274525472221619157672645224540758481713173)
return

View file

@ -3,7 +3,4 @@ import "hashes/mimc7/mimc7R90"
def main():
assert(mimc7R90(0, 0) == 20281265111705407344053532742843085357648991805359414661661476832595822221514)
assert(mimc7R90(100, 0) == 1010054095264022068840870550831559811104631937745987065544478027572003292636)
assert(mimc7R90(100, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 1010054095264022068840870550831559811104631937745987065544478027572003292636)
assert(mimc7R90(21888242871839275222246405745257275088548364400416034343698204186575808495618, 1) == 8189519586469873426687580455476035992041353456517724932462363814215190642760)
assert(mimc7R90(21888242871839275222246405745257275088548364400416034343698204186575808495617, 21888242871839275222246405745257275088548364400416034343698204186575808495617) == 20281265111705407344053532742843085357648991805359414661661476832595822221514)
return

View file

@ -1,7 +1,6 @@
import "hashes/mimcSponge/mimcSponge" as mimcSponge
def main():
assert(mimcSponge([1,2], 3) == [20225509322021146255705869525264566735642015554514977326536820959638320229084,13871743498877225461925335509899475799121918157213219438898506786048812913771,21633608428713573518356618235457250173701815120501233429160399974209848779097])
assert(mimcSponge([0,0], 0) == [20636625426020718969131298365984859231982649550971729229988535915544421356929,6046202021237334713296073963481784771443313518730771623154467767602059802325,16227963524034219233279650312501310147918176407385833422019760797222680144279])
assert(mimcSponge([21888242871839275222246405745257275088548364400416034343698204186575808495617, 0], 0) == [20636625426020718969131298365984859231982649550971729229988535915544421356929,6046202021237334713296073963481784771443313518730771623154467767602059802325,16227963524034219233279650312501310147918176407385833422019760797222680144279])
assert(mimcSponge([1,2], 3) == [20225509322021146255705869525264566735642015554514977326536820959638320229084, 13871743498877225461925335509899475799121918157213219438898506786048812913771, 21633608428713573518356618235457250173701815120501233429160399974209848779097])
assert(mimcSponge([0,0], 0) == [20636625426020718969131298365984859231982649550971729229988535915544421356929, 6046202021237334713296073963481784771443313518730771623154467767602059802325, 16227963524034219233279650312501310147918176407385833422019760797222680144279])
return