mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-13 06:43:01 +03:00
Merge pull request #51 from AleoHQ/feature/tooling
Adds build infrastructure and tooling
This commit is contained in:
commit
72016a5608
5
.codecov.yml
Normal file
5
.codecov.yml
Normal file
@ -0,0 +1,5 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
threshold: 2%
|
15
.rustfmt.toml
Normal file
15
.rustfmt.toml
Normal file
@ -0,0 +1,15 @@
|
||||
# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md
|
||||
|
||||
# Stable configurations
|
||||
edition = "2018"
|
||||
max_width = 120
|
||||
merge_derives = true
|
||||
use_field_init_shorthand = true
|
||||
use_try_shorthand = true
|
||||
|
||||
# Nightly configurations
|
||||
imports_layout = "HorizontalVertical"
|
||||
merge_imports = true
|
||||
overflow_delimited_expr = true
|
||||
reorder_impl_items = true
|
||||
version = "Two"
|
5
.rusty-hook.toml
Normal file
5
.rusty-hook.toml
Normal file
@ -0,0 +1,5 @@
|
||||
[hooks]
|
||||
pre-commit = "cargo +nightly fmt --all -- --check"
|
||||
|
||||
[logging]
|
||||
verbose = false
|
70
.travis.yml
Normal file
70
.travis.yml
Normal file
@ -0,0 +1,70 @@
|
||||
language: rust
|
||||
|
||||
before_install:
|
||||
- set -e
|
||||
- export SCCACHE_CACHE_SIZE=200M
|
||||
- export SCCACHE_DIR="$TRAVIS_HOME/.cache/sccache"
|
||||
- mkdir "$TRAVIS_HOME/.bin"
|
||||
- wget https://github.com/mozilla/sccache/releases/download/0.2.13/sccache-0.2.13-x86_64-unknown-linux-musl.tar.gz
|
||||
- tar -C "$TRAVIS_HOME/.bin" -xvf sccache-0.2.13-x86_64-unknown-linux-musl.tar.gz
|
||||
- mv $TRAVIS_HOME/.bin/sccache-0.2.13-x86_64-unknown-linux-musl/sccache $TRAVIS_HOME/.bin/sccache
|
||||
- export PATH="$PATH:$TRAVIS_HOME/.bin"
|
||||
- export RUSTC_WRAPPER="sccache"
|
||||
- |
|
||||
declare -r SSH_FILE="$(mktemp -u $HOME/.ssh/XXXXX)"
|
||||
openssl aes-256-cbc -K $encrypted_beefc4a47cdc_key -iv $encrypted_beefc4a47cdc_iv -in .travis/travis-snarkos.enc -out $SSH_FILE -d
|
||||
chmod 600 "$SSH_FILE" \
|
||||
&& printf "%s\n" \
|
||||
"Host github.com" \
|
||||
" IdentityFile $SSH_FILE" \
|
||||
" LogLevel ERROR" >> ~/.ssh/config
|
||||
- git clone --progress --verbose git@github.com:AleoHQ/snarkOS.git
|
||||
- mv snarkOS ..
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_HOME/.cache/sccache
|
||||
- $TRAVIS_HOME/.cargo
|
||||
|
||||
# See https://levans.fr/rust_travis_cache.html
|
||||
before_cache:
|
||||
- rm -rf "$TRAVIS_HOME/.cargo/registry"
|
||||
|
||||
after_script:
|
||||
- (sccache -s||true)
|
||||
- set +e
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- rust: stable
|
||||
env: TEST_COVERAGE=1
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev
|
||||
- libelf-dev
|
||||
- libdw-dev
|
||||
- cmake
|
||||
- gcc
|
||||
- binutils-dev
|
||||
- libiberty-dev
|
||||
script:
|
||||
- cargo test --all
|
||||
after_success:
|
||||
- wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz
|
||||
- tar xzf master.tar.gz && cd kcov-master
|
||||
- mkdir build && cd build && cmake .. && make && sudo make install
|
||||
- cd ../.. && rm -rf kcov-master
|
||||
- for file in target/debug/deps/*-*; do if [[ "$file" != *\.* ]]; then mkdir -p "target/cov/$(basename $file)"; kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$(basename $file)" "$file"; fi done
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- echo "Uploaded code coverage"
|
||||
- rust: nightly-2020-03-18
|
||||
install:
|
||||
- rustup component add rustfmt
|
||||
script:
|
||||
- cargo fmt -- --check
|
||||
- cargo test --all
|
||||
|
||||
script:
|
||||
- echo "leo"
|
BIN
.travis/travis-snarkos.enc
Normal file
BIN
.travis/travis-snarkos.enc
Normal file
Binary file not shown.
71
Cargo.lock
generated
71
Cargo.lock
generated
@ -69,9 +69,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.53.2"
|
||||
version = "0.53.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bb26d6a69a335b8cb0e7c7e9775cd5666611dc50a37177c3f2cedcfc040e8c8"
|
||||
checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
@ -166,6 +166,15 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "ci_info"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19c5f9baeac8a1176ca7fc58a0cc1abadd84d360365a93d1dd31e926f3f502b"
|
||||
dependencies = [
|
||||
"envmnt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "0.29.3"
|
||||
@ -329,6 +338,16 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "envmnt"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fba7e7d8c007e12db7b3bd6f04b8e47e206c9173d9c75413a042ccc941723c8"
|
||||
dependencies = [
|
||||
"fsio",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "failure"
|
||||
version = "0.1.7"
|
||||
@ -367,6 +386,12 @@ dependencies = [
|
||||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsio"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2131cb03096f67334dfba2f0bc46afc5564b08a919d042c6e217e2665741fc54"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.29"
|
||||
@ -382,6 +407,15 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
@ -423,6 +457,15 @@ dependencies = [
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.7.11"
|
||||
@ -475,6 +518,7 @@ dependencies = [
|
||||
"log",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"rusty-hook",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"snarkos-algorithms",
|
||||
@ -510,7 +554,6 @@ dependencies = [
|
||||
"log",
|
||||
"rand",
|
||||
"sha2",
|
||||
"snarkos-algorithms",
|
||||
"snarkos-curves",
|
||||
"snarkos-errors",
|
||||
"snarkos-gadgets",
|
||||
@ -605,6 +648,12 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nias"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.1"
|
||||
@ -886,6 +935,18 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rusty-hook"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27138b73a8ce63ae918707a5e3b57f9b0c0842a57b82f0e43474cf4e3aaf0ff4"
|
||||
dependencies = [
|
||||
"ci_info",
|
||||
"getopts",
|
||||
"nias",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.2"
|
||||
@ -1219,9 +1280,9 @@ checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.1"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
|
24
Cargo.toml
24
Cargo.toml
@ -36,3 +36,27 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0" }
|
||||
toml = { version = "0.5" }
|
||||
thiserror = { version = "1.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
rusty-hook = { version = "0.11.1" }
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
lto = "thin"
|
||||
incremental = true
|
||||
|
||||
[profile.bench]
|
||||
opt-level = 3
|
||||
debug = false
|
||||
rpath = false
|
||||
lto = "thin"
|
||||
incremental = true
|
||||
debug-assertions = false
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
|
||||
[profile.test]
|
||||
opt-level = 0
|
||||
debug-assertions = true
|
||||
debug = true
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::{access::{ArrayAccess, MemberAccess}, ast::Rule};
|
||||
use crate::{
|
||||
access::{ArrayAccess, MemberAccess},
|
||||
ast::Rule,
|
||||
};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
|
@ -2,18 +2,15 @@
|
||||
use crate::{
|
||||
common::Identifier,
|
||||
expressions::{
|
||||
ArrayInlineExpression,
|
||||
ArrayInitializerExpression,
|
||||
ArrayInlineExpression,
|
||||
CircuitInlineExpression,
|
||||
Expression,
|
||||
TernaryExpression,
|
||||
NotExpression,
|
||||
PostfixExpression
|
||||
},
|
||||
operations::{
|
||||
BinaryOperation,
|
||||
NotOperation,
|
||||
PostfixExpression,
|
||||
TernaryExpression,
|
||||
},
|
||||
operations::{BinaryOperation, NotOperation},
|
||||
values::Value,
|
||||
};
|
||||
|
||||
@ -22,7 +19,8 @@ use pest::{
|
||||
error::Error,
|
||||
iterators::{Pair, Pairs},
|
||||
prec_climber::{Assoc, Operator, PrecClimber},
|
||||
Parser, Span,
|
||||
Parser,
|
||||
Span,
|
||||
};
|
||||
|
||||
#[derive(Parser)]
|
||||
@ -47,16 +45,13 @@ fn precedence_climber() -> PrecClimber<Rule> {
|
||||
PrecClimber::new(vec![
|
||||
Operator::new(Rule::operation_or, Assoc::Left),
|
||||
Operator::new(Rule::operation_and, Assoc::Left),
|
||||
Operator::new(Rule::operation_eq, Assoc::Left)
|
||||
| Operator::new(Rule::operation_ne, Assoc::Left),
|
||||
Operator::new(Rule::operation_eq, Assoc::Left) | Operator::new(Rule::operation_ne, Assoc::Left),
|
||||
Operator::new(Rule::operation_ge, Assoc::Left)
|
||||
| Operator::new(Rule::operation_gt, Assoc::Left)
|
||||
| Operator::new(Rule::operation_le, Assoc::Left)
|
||||
| Operator::new(Rule::operation_lt, Assoc::Left),
|
||||
Operator::new(Rule::operation_add, Assoc::Left)
|
||||
| Operator::new(Rule::operation_sub, Assoc::Left),
|
||||
Operator::new(Rule::operation_mul, Assoc::Left)
|
||||
| Operator::new(Rule::operation_div, Assoc::Left),
|
||||
Operator::new(Rule::operation_add, Assoc::Left) | Operator::new(Rule::operation_sub, Assoc::Left),
|
||||
Operator::new(Rule::operation_mul, Assoc::Left) | Operator::new(Rule::operation_div, Assoc::Left),
|
||||
Operator::new(Rule::operation_pow, Assoc::Left),
|
||||
])
|
||||
}
|
||||
@ -69,55 +64,55 @@ fn parse_term(pair: Pair<Rule>) -> Box<Expression> {
|
||||
match next.as_rule() {
|
||||
Rule::expression => Expression::from_pest(&mut pair.into_inner()).unwrap(), // Parenthesis case
|
||||
Rule::expression_array_inline => {
|
||||
Expression::ArrayInline(
|
||||
ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Expression::ArrayInline(ArrayInlineExpression::from_pest(&mut pair.into_inner()).unwrap())
|
||||
}
|
||||
Rule::expression_array_initializer => {
|
||||
Expression::ArrayInitializer(
|
||||
ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Expression::ArrayInitializer(ArrayInitializerExpression::from_pest(&mut pair.into_inner()).unwrap())
|
||||
}
|
||||
Rule::expression_circuit_inline => {
|
||||
Expression::CircuitInline(
|
||||
CircuitInlineExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Expression::CircuitInline(CircuitInlineExpression::from_pest(&mut pair.into_inner()).unwrap())
|
||||
}
|
||||
Rule::expression_conditional => {
|
||||
Expression::Ternary(
|
||||
TernaryExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
},
|
||||
Expression::Ternary(TernaryExpression::from_pest(&mut pair.into_inner()).unwrap())
|
||||
}
|
||||
Rule::expression_not => {
|
||||
let span = next.as_span();
|
||||
let mut inner = next.into_inner();
|
||||
let operation = match inner.next().unwrap().as_rule() {
|
||||
Rule::operation_not => NotOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule)
|
||||
Rule::operation_not => {
|
||||
NotOperation::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
|
||||
}
|
||||
rule => unreachable!("`expression_not` should yield `operation_pre_not`, found {:#?}", rule),
|
||||
};
|
||||
let expression = parse_term(inner.next().unwrap());
|
||||
Expression::Not(NotExpression { operation, expression, span })
|
||||
},
|
||||
Expression::Not(NotExpression {
|
||||
operation,
|
||||
expression,
|
||||
span,
|
||||
})
|
||||
}
|
||||
Rule::expression_postfix => {
|
||||
Expression::Postfix(
|
||||
PostfixExpression::from_pest(&mut pair.into_inner()).unwrap(),
|
||||
)
|
||||
Expression::Postfix(PostfixExpression::from_pest(&mut pair.into_inner()).unwrap())
|
||||
}
|
||||
Rule::expression_primitive => {
|
||||
let next = next.into_inner().next().unwrap();
|
||||
match next.as_rule() {
|
||||
Rule::value => {
|
||||
Expression::Value(
|
||||
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap()
|
||||
)
|
||||
},
|
||||
Rule::value => Expression::Value(
|
||||
Value::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
),
|
||||
Rule::identifier => Expression::Identifier(
|
||||
Identifier::from_pest(&mut pair.into_inner().next().unwrap().into_inner()).unwrap(),
|
||||
),
|
||||
rule => unreachable!("`expression_primitive` should contain one of [`value`, `identifier`], found {:#?}", rule)
|
||||
rule => unreachable!(
|
||||
"`expression_primitive` should contain one of [`value`, `identifier`], found {:#?}",
|
||||
rule
|
||||
),
|
||||
}
|
||||
},
|
||||
rule => unreachable!("`term` should contain one of ['value', 'identifier', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}", rule)
|
||||
}
|
||||
rule => unreachable!(
|
||||
"`term` should contain one of ['value', 'identifier', 'expression', 'expression_not', 'expression_increment', 'expression_decrement'], found {:#?}",
|
||||
rule
|
||||
),
|
||||
}
|
||||
}
|
||||
rule => unreachable!(
|
||||
@ -155,8 +150,8 @@ fn binary_expression<'ast>(
|
||||
}
|
||||
|
||||
impl<'ast> FromPest<'ast> for Expression<'ast> {
|
||||
type Rule = Rule;
|
||||
type FatalError = Void;
|
||||
type Rule = Rule;
|
||||
|
||||
fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result<Self, ConversionError<Void>> {
|
||||
let mut clone = pest.clone();
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::{ast::Rule, circuits::{CircuitFunction, CircuitFieldDefinition}};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
circuits::{CircuitFieldDefinition, CircuitFunction},
|
||||
};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
|
@ -17,16 +17,8 @@ impl<'ast> fmt::Display for RangeOrExpression<'ast> {
|
||||
RangeOrExpression::Range(ref range) => write!(
|
||||
f,
|
||||
"{}..{}",
|
||||
range
|
||||
.from
|
||||
.as_ref()
|
||||
.map(|e| e.0.to_string())
|
||||
.unwrap_or("".to_string()),
|
||||
range
|
||||
.to
|
||||
.as_ref()
|
||||
.map(|e| e.0.to_string())
|
||||
.unwrap_or("".to_string())
|
||||
range.from.as_ref().map(|e| e.0.to_string()).unwrap_or("".to_string()),
|
||||
range.to.as_ref().map(|e| e.0.to_string()).unwrap_or("".to_string())
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{ast::Rule, common::{Identifier, Mutable}, types::Type};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{Identifier, Mutable},
|
||||
types::Type,
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{ast::Rule, circuits::CircuitField, common::Identifier,};
|
||||
use crate::{ast::Rule, circuits::CircuitField, common::Identifier};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{common::Identifier, expressions::*, operations::BinaryOperation, values::Value,};
|
||||
use crate::{common::Identifier, expressions::*, operations::BinaryOperation, values::Value};
|
||||
|
||||
use pest::Span;
|
||||
use std::fmt;
|
||||
@ -66,9 +66,7 @@ impl<'ast> fmt::Display for Expression<'ast> {
|
||||
Expression::Value(ref expression) => write!(f, "{}", expression),
|
||||
Expression::Identifier(ref expression) => write!(f, "{}", expression),
|
||||
Expression::Not(ref expression) => write!(f, "!{}", expression.expression),
|
||||
Expression::Binary(ref expression) => {
|
||||
write!(f, "{} == {}", expression.left, expression.right)
|
||||
}
|
||||
Expression::Binary(ref expression) => write!(f, "{} == {}", expression.left, expression.right),
|
||||
Expression::Ternary(ref expression) => write!(
|
||||
f,
|
||||
"if {} ? {} : {}",
|
||||
@ -86,14 +84,10 @@ impl<'ast> fmt::Display for Expression<'ast> {
|
||||
Expression::ArrayInitializer(ref expression) => {
|
||||
write!(f, "[{} ; {}]", expression.expression, expression.count)
|
||||
}
|
||||
Expression::CircuitInline(ref expression) => write!(
|
||||
f,
|
||||
"inline circuit display not impl {}",
|
||||
expression.identifier
|
||||
),
|
||||
Expression::Postfix(ref expression) => {
|
||||
write!(f, "Postfix display not impl {}", expression.identifier)
|
||||
Expression::CircuitInline(ref expression) => {
|
||||
write!(f, "inline circuit display not impl {}", expression.identifier)
|
||||
}
|
||||
Expression::Postfix(ref expression) => write!(f, "Postfix display not impl {}", expression.identifier),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,10 @@
|
||||
use crate::{ast::Rule, common::EOI, functions::{Function, TestFunction}, imports::Import, circuits::Circuit};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
circuits::Circuit,
|
||||
common::EOI,
|
||||
functions::{Function, TestFunction},
|
||||
imports::Import,
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{ast::Rule, common::{Identifier, Visibility, Mutable}, types::Type};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{Identifier, Mutable, Visibility},
|
||||
types::Type,
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{ast::Rule, common::LineEnd, imports::{ImportSource, ImportSymbol}};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::LineEnd,
|
||||
imports::{ImportSource, ImportSymbol},
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::ast::{Rule, span_into_string};
|
||||
use crate::ast::{span_into_string, Rule};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -18,11 +18,11 @@ pub mod functions;
|
||||
pub mod imports;
|
||||
pub mod operations;
|
||||
pub mod statements;
|
||||
pub mod values;
|
||||
pub mod types;
|
||||
pub mod values;
|
||||
|
||||
use from_pest::FromPest;
|
||||
use std::{path::PathBuf, fs};
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
pub struct LeoParser;
|
||||
|
||||
@ -35,9 +35,8 @@ impl LeoParser {
|
||||
/// Parses the input file and constructs a syntax tree.
|
||||
pub fn parse_file<'a>(file_path: &'a PathBuf, input_file: &'a str) -> Result<files::File<'a>, ParserError> {
|
||||
// Parse the file using leo.pest
|
||||
let mut file = ast::parse(input_file).map_err(|error| {
|
||||
ParserError::from(error.with_path(file_path.to_str().unwrap()))
|
||||
})?;
|
||||
let mut file =
|
||||
ast::parse(input_file).map_err(|error| ParserError::from(error.with_path(file_path.to_str().unwrap())))?;
|
||||
|
||||
// Build the abstract syntax tree
|
||||
let syntax_tree = files::File::from_pest(&mut file).map_err(|_| ParserError::SyntaxTreeError)?;
|
||||
|
@ -13,9 +13,7 @@ pub enum AssertStatement<'ast> {
|
||||
impl<'ast> fmt::Display for AssertStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
AssertStatement::AssertEq(ref assert) => {
|
||||
write!(f, "assert_eq({}, {});", assert.left, assert.right)
|
||||
}
|
||||
AssertStatement::AssertEq(ref assert) => write!(f, "assert_eq({}, {});", assert.left, assert.right),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,9 @@
|
||||
use crate::{ast::Rule, common::{Assignee, LineEnd}, expressions::Expression, operations::AssignOperation};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{Assignee, LineEnd},
|
||||
expressions::Expression,
|
||||
operations::AssignOperation,
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::{ast::Rule, statements::{ConditionalStatement, Statement}};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
statements::{ConditionalStatement, Statement},
|
||||
};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
use std::fmt;
|
||||
@ -14,9 +17,7 @@ impl<'ast> fmt::Display for ConditionalNestedOrEndStatement<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConditionalNestedOrEndStatement::Nested(ref nested) => write!(f, "else {}", nested),
|
||||
ConditionalNestedOrEndStatement::End(ref statements) => {
|
||||
write!(f, "else {{\n \t{:#?}\n }}", statements)
|
||||
}
|
||||
ConditionalNestedOrEndStatement::End(ref statements) => write!(f, "else {{\n \t{:#?}\n }}", statements),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{ast::Rule, expressions::Expression, statements::{ConditionalNestedOrEndStatement, Statement}};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
expressions::Expression,
|
||||
statements::{ConditionalNestedOrEndStatement, Statement},
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{ast::Rule, common::{LineEnd, Variable}, expressions::Expression};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{LineEnd, Variable},
|
||||
expressions::Expression,
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{ast::Rule, expressions::{Expression}, statements::Statement, common::Identifier};
|
||||
use crate::{ast::Rule, common::Identifier, expressions::Expression, statements::Statement};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,8 @@
|
||||
use crate::{ast::Rule, common::{Identifier, LineEnd, Variable}, expressions::{Expression}};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
common::{Identifier, LineEnd, Variable},
|
||||
expressions::Expression,
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -9,4 +9,4 @@ pub struct CircuitType<'ast> {
|
||||
pub identifier: Identifier<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::{ast::Rule, types::{IntegerType, FieldType, GroupType, BooleanType}};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
types::{BooleanType, FieldType, GroupType, IntegerType},
|
||||
};
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
@ -9,4 +12,4 @@ pub enum DataType {
|
||||
Field(FieldType),
|
||||
Group(GroupType),
|
||||
Boolean(BooleanType),
|
||||
}
|
||||
}
|
||||
|
@ -4,4 +4,4 @@ use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::type_field))]
|
||||
pub struct FieldType {}
|
||||
pub struct FieldType {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::ast::{Rule, span_into_string};
|
||||
use crate::ast::{span_into_string, Rule};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{ast::Rule, types::FieldType, values::NumberValue,};
|
||||
use crate::{ast::Rule, types::FieldType, values::NumberValue};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{ast::Rule, types::GroupType, values::NumberValue,};
|
||||
use crate::{ast::Rule, types::GroupType, values::NumberValue};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::ast::{Rule, span_into_string};
|
||||
use crate::ast::{span_into_string, Rule};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
@ -17,4 +17,4 @@ impl<'ast> fmt::Display for NumberValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::{ast::Rule, values::{BooleanValue, IntegerValue, FieldValue, GroupValue, NumberImplicitValue}};
|
||||
use crate::{
|
||||
ast::Rule,
|
||||
values::{BooleanValue, FieldValue, GroupValue, IntegerValue, NumberImplicitValue},
|
||||
};
|
||||
|
||||
use pest::Span;
|
||||
use pest_ast::FromPest;
|
||||
|
@ -8,15 +8,16 @@ edition = "2018"
|
||||
leo-ast = { path = "../ast", version = "0.1.0" }
|
||||
leo-types = { path = "../types", version = "0.1.0" }
|
||||
|
||||
snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" }
|
||||
snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" }
|
||||
snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0" }
|
||||
snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" }
|
||||
snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" }
|
||||
snarkos-utilities = { path = "../../snarkOS/utilities", version = "0.8.0" }
|
||||
|
||||
hex = { version = "0.4.2" }
|
||||
log = { version = "0.4" }
|
||||
rand = { version = "0.7" }
|
||||
sha2 = { version = "0.8" }
|
||||
thiserror = { version = "1.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
snarkos-utilities = { path = "../../snarkOS/utilities", version = "0.8.0" }
|
||||
|
@ -28,6 +28,17 @@ pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
package_name: "".to_string(),
|
||||
main_file_path: PathBuf::new(),
|
||||
program: Program::new(),
|
||||
program_inputs: vec![],
|
||||
output: None,
|
||||
_engine: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
|
||||
let mut program = Self {
|
||||
package_name,
|
||||
@ -39,7 +50,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
};
|
||||
|
||||
// Generate the abstract syntax tree and assemble the program
|
||||
program.parse_program()?;
|
||||
let program_string = program.load_program()?;
|
||||
program.parse_program(&program_string)?;
|
||||
|
||||
Ok(program)
|
||||
}
|
||||
@ -68,18 +80,19 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
generate_constraints(cs, self.program, self.program_inputs)
|
||||
}
|
||||
|
||||
pub fn compile_test_constraints(
|
||||
self,
|
||||
cs: &mut TestConstraintSystem<F>,
|
||||
) -> Result<(), CompilerError> {
|
||||
pub fn compile_test_constraints(self, cs: &mut TestConstraintSystem<F>) -> Result<(), CompilerError> {
|
||||
generate_test_constraints::<F, G>(cs, self.program)
|
||||
}
|
||||
|
||||
fn parse_program(&mut self) -> Result<(), CompilerError> {
|
||||
// Build the program syntax tree
|
||||
fn load_program(&mut self) -> Result<String, CompilerError> {
|
||||
// Load the program syntax tree from the file path
|
||||
let file_path = &self.main_file_path;
|
||||
let input_file = &LeoParser::load_file(file_path)?;
|
||||
let syntax_tree = LeoParser::parse_file(file_path, input_file)?;
|
||||
Ok(LeoParser::load_file(file_path)?)
|
||||
}
|
||||
|
||||
pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> {
|
||||
// Parse the program syntax tree
|
||||
let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?;
|
||||
|
||||
// Build program from syntax tree
|
||||
let package_name = self.package_name.clone();
|
||||
@ -94,12 +107,8 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _result =
|
||||
generate_constraints::<_, G, _>(cs, self.program, self.program_inputs).unwrap();
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
|
||||
let _result = generate_constraints::<_, G, _>(cs, self.program, self.program_inputs).unwrap();
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
|
@ -38,13 +38,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
|
||||
// Check visibility of input
|
||||
let number = if private {
|
||||
Boolean::alloc(cs.ns(|| name), || {
|
||||
bool_value.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
Boolean::alloc(cs.ns(|| name), || bool_value.ok_or(SynthesisError::AssignmentMissing))?
|
||||
} else {
|
||||
Boolean::alloc_input(cs.ns(|| name), || {
|
||||
bool_value.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
Boolean::alloc_input(cs.ns(|| name), || bool_value.ok_or(SynthesisError::AssignmentMissing))?
|
||||
};
|
||||
|
||||
Ok(ConstrainedValue::Boolean(number))
|
||||
@ -54,9 +50,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
ConstrainedValue::Boolean(bool)
|
||||
}
|
||||
|
||||
pub(crate) fn evaluate_not(
|
||||
value: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
pub(crate) fn evaluate_not(value: ConstrainedValue<F, G>) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match value {
|
||||
ConstrainedValue::Boolean(boolean) => Ok(ConstrainedValue::Boolean(boolean.not())),
|
||||
value => Err(BooleanError::CannotEvaluate(format!("!{}", value))),
|
||||
@ -70,9 +64,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?),
|
||||
),
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::or(cs, &left_bool, &right_bool)?))
|
||||
}
|
||||
(left_value, right_value) => Err(BooleanError::CannotEnforce(format!(
|
||||
"{} || {}",
|
||||
left_value, right_value
|
||||
@ -87,9 +81,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
right: ConstrainedValue<F, G>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
match (left, right) {
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?),
|
||||
),
|
||||
(ConstrainedValue::Boolean(left_bool), ConstrainedValue::Boolean(right_bool)) => {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::and(cs, &left_bool, &right_bool)?))
|
||||
}
|
||||
(left_value, right_value) => Err(BooleanError::CannotEnforce(format!(
|
||||
"{} && {}",
|
||||
left_value, right_value
|
||||
|
@ -4,10 +4,20 @@ use crate::{
|
||||
constraints::{ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue},
|
||||
errors::ExpressionError,
|
||||
new_scope,
|
||||
FieldType, GroupType,
|
||||
FieldType,
|
||||
GroupType,
|
||||
};
|
||||
use leo_types::{
|
||||
CircuitFieldDefinition,
|
||||
CircuitMember,
|
||||
Expression,
|
||||
Identifier,
|
||||
Integer,
|
||||
IntegerType,
|
||||
RangeOrExpression,
|
||||
SpreadOrExpression,
|
||||
Type,
|
||||
};
|
||||
use leo_types::{CircuitFieldDefinition,CircuitMember, Expression, RangeOrExpression,
|
||||
SpreadOrExpression, Identifier, Integer, IntegerType, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -37,9 +47,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
// Check global scope (function and circuit names)
|
||||
value.clone()
|
||||
} else {
|
||||
return Err(ExpressionError::UndefinedIdentifier(
|
||||
unresolved_identifier.to_string(),
|
||||
));
|
||||
return Err(ExpressionError::UndefinedIdentifier(unresolved_identifier.to_string()));
|
||||
};
|
||||
|
||||
result_value.resolve_type(expected_types)?;
|
||||
@ -72,10 +80,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.enforce_add_expression(cs, val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} + {}",
|
||||
val_1, val_2,
|
||||
))),
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} + {}", val_1, val_2,))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,10 +108,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.enforce_sub_expression(cs, val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} - {}",
|
||||
val_1, val_2,
|
||||
))),
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} - {}", val_1, val_2,))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,12 +133,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.enforce_mul_expression(cs, val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} * {}",
|
||||
val_1, val_2,
|
||||
)))
|
||||
}
|
||||
(val_1, val_2) => return Err(ExpressionError::IncompatibleTypes(format!("{} * {}", val_1, val_2,))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,14 +158,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.enforce_div_expression(cs, val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} / {}",
|
||||
val_1, val_2,
|
||||
)))
|
||||
}
|
||||
(val_1, val_2) => return Err(ExpressionError::IncompatibleTypes(format!("{} / {}", val_1, val_2,))),
|
||||
}
|
||||
}
|
||||
|
||||
fn enforce_pow_expression(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
@ -187,10 +180,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.enforce_pow_expression(cs, val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} * {}",
|
||||
val_1, val_2,
|
||||
))),
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} * {}", val_1, val_2,))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,9 +194,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
|
||||
Ok(Self::boolean_eq(bool_1, bool_2))
|
||||
}
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => Ok(
|
||||
ConstrainedValue::Boolean(Boolean::Constant(num_1.eq(&num_2))),
|
||||
),
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(num_1.eq(&num_2))))
|
||||
}
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(fe_1.eq(&fe_2))))
|
||||
}
|
||||
@ -221,10 +211,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let val_2 = ConstrainedValue::from_other(string, &val_1)?;
|
||||
self.evaluate_eq_expression(val_1, val_2)
|
||||
}
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!(
|
||||
"{} == {}",
|
||||
val_1, val_2,
|
||||
))),
|
||||
(val_1, val_2) => Err(ExpressionError::IncompatibleTypes(format!("{} == {}", val_1, val_2,))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,15 +353,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
value => return Err(ExpressionError::IfElseConditional(value.to_string())),
|
||||
};
|
||||
|
||||
let resolved_second = self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
second,
|
||||
)?;
|
||||
let resolved_third =
|
||||
self.enforce_branch(cs, file_scope, function_scope, expected_types, third)?;
|
||||
let resolved_second =
|
||||
self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, second)?;
|
||||
let resolved_third = self.enforce_branch(cs, file_scope, function_scope, expected_types, third)?;
|
||||
|
||||
match (resolved_second, resolved_third) {
|
||||
(ConstrainedValue::Boolean(bool_2), ConstrainedValue::Boolean(bool_3)) => {
|
||||
@ -382,8 +363,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
Ok(ConstrainedValue::Boolean(result))
|
||||
}
|
||||
(ConstrainedValue::Integer(integer_2), ConstrainedValue::Integer(integer_3)) => {
|
||||
let result =
|
||||
Integer::conditionally_select(cs, &resolved_first, &integer_2, &integer_3)?;
|
||||
let result = Integer::conditionally_select(cs, &resolved_first, &integer_2, &integer_3)?;
|
||||
Ok(ConstrainedValue::Integer(result))
|
||||
}
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
|
||||
@ -394,9 +374,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let result = G::conditionally_select(cs, &resolved_first, &ge_1, &ge_2)?;
|
||||
Ok(ConstrainedValue::Group(result))
|
||||
}
|
||||
(_, _) => {
|
||||
unimplemented!("conditional select gadget not implemented between given types")
|
||||
}
|
||||
(_, _) => unimplemented!("conditional select gadget not implemented between given types"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,13 +451,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
index: Expression,
|
||||
) -> Result<usize, ExpressionError> {
|
||||
let expected_types = vec![Type::IntegerType(IntegerType::U32)];
|
||||
match self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&expected_types,
|
||||
index,
|
||||
)? {
|
||||
match self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), &expected_types, index)? {
|
||||
ConstrainedValue::Integer(number) => Ok(number.to_usize()),
|
||||
value => Err(ExpressionError::InvalidIndex(value.to_string())),
|
||||
}
|
||||
@ -494,13 +466,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
array: Box<Expression>,
|
||||
index: RangeOrExpression,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let array = match self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
*array,
|
||||
)? {
|
||||
let array = match self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, *array)? {
|
||||
ConstrainedValue::Array(array) => array,
|
||||
value => return Err(ExpressionError::InvalidArrayAccess(value.to_string())),
|
||||
};
|
||||
@ -515,9 +481,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
Some(to_index) => to_index.to_usize(),
|
||||
None => array.len(), // Array slice ends at array length
|
||||
};
|
||||
Ok(ConstrainedValue::Array(
|
||||
array[from_resolved..to_resolved].to_owned(),
|
||||
))
|
||||
Ok(ConstrainedValue::Array(array[from_resolved..to_resolved].to_owned()))
|
||||
}
|
||||
RangeOrExpression::Expression(index) => {
|
||||
let index_resolved = self.enforce_index(cs, file_scope, function_scope, index)?;
|
||||
@ -540,9 +504,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
program_identifier = file_scope.clone();
|
||||
}
|
||||
|
||||
if let Some(ConstrainedValue::CircuitDefinition(circuit_definition)) =
|
||||
self.get_mut(&program_identifier)
|
||||
{
|
||||
if let Some(ConstrainedValue::CircuitDefinition(circuit_definition)) = self.get_mut(&program_identifier) {
|
||||
let circuit_identifier = circuit_definition.identifier.clone();
|
||||
let mut resolved_members = vec![];
|
||||
for member in circuit_definition.members.clone().into_iter() {
|
||||
@ -563,14 +525,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
field.expression,
|
||||
)?;
|
||||
|
||||
resolved_members
|
||||
.push(ConstrainedCircuitMember(identifier, field_value))
|
||||
}
|
||||
None => {
|
||||
return Err(ExpressionError::ExpectedCircuitMember(
|
||||
identifier.to_string(),
|
||||
))
|
||||
resolved_members.push(ConstrainedCircuitMember(identifier, field_value))
|
||||
}
|
||||
None => return Err(ExpressionError::ExpectedCircuitMember(identifier.to_string())),
|
||||
}
|
||||
}
|
||||
CircuitMember::CircuitFunction(_static, function) => {
|
||||
@ -579,14 +536,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
ConstrainedValue::Function(Some(circuit_identifier.clone()), function);
|
||||
|
||||
if _static {
|
||||
constrained_function_value =
|
||||
ConstrainedValue::Static(Box::new(constrained_function_value));
|
||||
constrained_function_value = ConstrainedValue::Static(Box::new(constrained_function_value));
|
||||
}
|
||||
|
||||
resolved_members.push(ConstrainedCircuitMember(
|
||||
identifier,
|
||||
constrained_function_value,
|
||||
));
|
||||
resolved_members.push(ConstrainedCircuitMember(identifier, constrained_function_value));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -620,10 +573,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
value => return Err(ExpressionError::InvalidCircuitAccess(value.to_string())),
|
||||
};
|
||||
|
||||
let matched_member = members
|
||||
.clone()
|
||||
.into_iter()
|
||||
.find(|member| member.0 == circuit_member);
|
||||
let matched_member = members.clone().into_iter().find(|member| member.0 == circuit_member);
|
||||
|
||||
match matched_member {
|
||||
Some(member) => {
|
||||
@ -635,12 +585,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
ConstrainedValue::Function(_, _) => {}
|
||||
ConstrainedValue::Static(_) => {}
|
||||
_ => {
|
||||
let circuit_scope =
|
||||
new_scope(file_scope.clone(), circuit_name.to_string());
|
||||
let function_scope =
|
||||
new_scope(circuit_scope, member.0.to_string());
|
||||
let field =
|
||||
new_scope(function_scope, stored_member.0.to_string());
|
||||
let circuit_scope = new_scope(file_scope.clone(), circuit_name.to_string());
|
||||
let function_scope = new_scope(circuit_scope, member.0.to_string());
|
||||
let field = new_scope(function_scope, stored_member.0.to_string());
|
||||
|
||||
self.store(field, stored_member.1.clone());
|
||||
}
|
||||
@ -648,7 +595,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
}
|
||||
}
|
||||
ConstrainedValue::Static(value) => {
|
||||
return Err(ExpressionError::InvalidStaticAccess(value.to_string()))
|
||||
return Err(ExpressionError::InvalidStaticAccess(value.to_string()));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -684,9 +631,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
|
||||
// Find static circuit function
|
||||
let matched_function = circuit.members.into_iter().find(|member| match member {
|
||||
CircuitMember::CircuitFunction(_static, function) => {
|
||||
function.function_name == circuit_member
|
||||
}
|
||||
CircuitMember::CircuitFunction(_static, function) => function.function_name == circuit_member,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
@ -696,23 +641,18 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
if _static {
|
||||
function
|
||||
} else {
|
||||
return Err(ExpressionError::InvalidMemberAccess(
|
||||
function.function_name.to_string(),
|
||||
));
|
||||
return Err(ExpressionError::InvalidMemberAccess(function.function_name.to_string()));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(ExpressionError::UndefinedStaticAccess(
|
||||
circuit.identifier.to_string(),
|
||||
circuit_member.to_string(),
|
||||
))
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ConstrainedValue::Function(
|
||||
Some(circuit.identifier),
|
||||
function,
|
||||
))
|
||||
Ok(ConstrainedValue::Function(Some(circuit.identifier), function))
|
||||
}
|
||||
|
||||
fn enforce_function_call_expression(
|
||||
@ -780,8 +720,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
expected_types: &Vec<Type>,
|
||||
expression: Expression,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let mut branch =
|
||||
self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
|
||||
let mut branch = self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
|
||||
|
||||
branch.get_inner_mut();
|
||||
branch.resolve_type(expected_types)?;
|
||||
@ -798,20 +737,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
left: Expression,
|
||||
right: Expression,
|
||||
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> {
|
||||
let resolved_left = self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
left,
|
||||
)?;
|
||||
let resolved_right = self.enforce_branch(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
expected_types,
|
||||
right,
|
||||
)?;
|
||||
let resolved_left =
|
||||
self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, left)?;
|
||||
let resolved_right =
|
||||
self.enforce_branch(cs, file_scope.clone(), function_scope.clone(), expected_types, right)?;
|
||||
|
||||
Ok((resolved_left, resolved_right))
|
||||
}
|
||||
@ -826,19 +755,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match expression {
|
||||
// Variables
|
||||
Expression::Identifier(unresolved_variable) => self.evaluate_identifier(
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_types,
|
||||
unresolved_variable,
|
||||
),
|
||||
Expression::Identifier(unresolved_variable) => {
|
||||
self.evaluate_identifier(file_scope, function_scope, expected_types, unresolved_variable)
|
||||
}
|
||||
|
||||
// Values
|
||||
Expression::Integer(integer) => Ok(ConstrainedValue::Integer(integer)),
|
||||
Expression::Field(field) => Ok(ConstrainedValue::Field(FieldType::constant(field)?)),
|
||||
Expression::Group(group_affine) => {
|
||||
Ok(ConstrainedValue::Group(G::constant(group_affine)?))
|
||||
}
|
||||
Expression::Group(group_affine) => Ok(ConstrainedValue::Group(G::constant(group_affine)?)),
|
||||
Expression::Boolean(bool) => Ok(Self::get_boolean_constant(bool)),
|
||||
Expression::Implicit(value) => Self::enforce_number_implicit(expected_types, value),
|
||||
|
||||
@ -1012,23 +936,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
Expression::Array(array) => {
|
||||
self.enforce_array_expression(cs, file_scope, function_scope, expected_types, array)
|
||||
}
|
||||
Expression::ArrayAccess(array, index) => self.enforce_array_access_expression(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
expected_types,
|
||||
array,
|
||||
*index,
|
||||
),
|
||||
Expression::ArrayAccess(array, index) => {
|
||||
self.enforce_array_access_expression(cs, file_scope, function_scope, expected_types, array, *index)
|
||||
}
|
||||
|
||||
// Circuits
|
||||
Expression::Circuit(circuit_name, members) => self.enforce_circuit_expression(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
circuit_name,
|
||||
members,
|
||||
),
|
||||
Expression::Circuit(circuit_name, members) => {
|
||||
self.enforce_circuit_expression(cs, file_scope, function_scope, circuit_name, members)
|
||||
}
|
||||
Expression::CircuitMemberAccess(circuit_variable, circuit_member) => self
|
||||
.enforce_circuit_access_expression(
|
||||
cs,
|
||||
|
@ -1,8 +1,6 @@
|
||||
//! Methods to enforce constraints on field elements in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
constraints::ConstrainedValue, errors::FieldError, FieldType, GroupType,
|
||||
};
|
||||
use crate::{constraints::ConstrainedValue, errors::FieldError, FieldType, GroupType};
|
||||
use leo_types::InputValue;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
@ -31,13 +29,9 @@ pub(crate) fn field_from_input<F: Field + PrimeField, G: GroupType<F>, CS: Const
|
||||
|
||||
// Check visibility of parameter
|
||||
let field_value = if private {
|
||||
FieldType::alloc(cs.ns(|| name), || {
|
||||
field_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
FieldType::alloc(cs.ns(|| name), || field_option.ok_or(SynthesisError::AssignmentMissing))?
|
||||
} else {
|
||||
FieldType::alloc_input(cs.ns(|| name), || {
|
||||
field_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
FieldType::alloc_input(cs.ns(|| name), || field_option.ok_or(SynthesisError::AssignmentMissing))?
|
||||
};
|
||||
|
||||
Ok(ConstrainedValue::Field(field_value))
|
||||
|
@ -4,8 +4,10 @@
|
||||
use crate::{
|
||||
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
|
||||
errors::{FunctionError, ImportError},
|
||||
field_from_input, group_from_input,
|
||||
GroupType};
|
||||
field_from_input,
|
||||
group_from_input,
|
||||
GroupType,
|
||||
};
|
||||
use leo_types::{Expression, Function, Identifier, InputValue, Integer, Program, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -35,19 +37,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
// Evaluate the function input value as pass by value from the caller or
|
||||
// evaluate as an expression in the current function scope
|
||||
match input {
|
||||
Expression::Identifier(identifier) => Ok(self.evaluate_identifier(
|
||||
caller_scope,
|
||||
function_name,
|
||||
&expected_types,
|
||||
identifier,
|
||||
)?),
|
||||
expression => Ok(self.enforce_expression(
|
||||
cs,
|
||||
scope,
|
||||
function_name,
|
||||
&expected_types,
|
||||
expression,
|
||||
)?),
|
||||
Expression::Identifier(identifier) => {
|
||||
Ok(self.evaluate_identifier(caller_scope, function_name, &expected_types, identifier)?)
|
||||
}
|
||||
expression => Ok(self.enforce_expression(cs, scope, function_name, &expected_types, expression)?),
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,9 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
Self::check_arguments_length(function.inputs.len(), inputs.len())?;
|
||||
|
||||
// Store input values as new variables in resolved program
|
||||
for (input_model, input_expression) in
|
||||
function.inputs.clone().iter().zip(inputs.into_iter())
|
||||
{
|
||||
for (input_model, input_expression) in function.inputs.clone().iter().zip(inputs.into_iter()) {
|
||||
// First evaluate input expression
|
||||
let mut input_value = self.enforce_input(
|
||||
cs,
|
||||
@ -83,8 +74,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
}
|
||||
|
||||
// Store input as variable with {function_name}_{input_name}
|
||||
let input_program_identifier =
|
||||
new_scope(function_name.clone(), input_model.identifier.name.clone());
|
||||
let input_program_identifier = new_scope(function_name.clone(), input_model.identifier.name.clone());
|
||||
self.store(input_program_identifier, input_value);
|
||||
}
|
||||
|
||||
@ -149,18 +139,10 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let value_name = new_scope(name.clone(), i.to_string());
|
||||
let value_type = array_type.outer_dimension(&array_dimensions);
|
||||
|
||||
array_value.push(
|
||||
self.allocate_main_function_input(
|
||||
cs, value_type, value_name, private, None,
|
||||
)?,
|
||||
);
|
||||
array_value.push(self.allocate_main_function_input(cs, value_type, value_name, private, None)?);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidArray(
|
||||
input_value.unwrap().to_string(),
|
||||
))
|
||||
}
|
||||
_ => return Err(FunctionError::InvalidArray(input_value.unwrap().to_string())),
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::Array(array_value))
|
||||
@ -185,9 +167,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
Type::Field => Ok(field_from_input(cs, name, private, input_value)?),
|
||||
Type::Group => Ok(group_from_input(cs, name, private, input_value)?),
|
||||
Type::Boolean => Ok(self.bool_from_input(cs, name, private, input_value)?),
|
||||
Type::Array(_type, dimensions) => {
|
||||
self.allocate_array(cs, name, private, *_type, dimensions, input_value)
|
||||
}
|
||||
Type::Array(_type, dimensions) => self.allocate_array(cs, name, private, *_type, dimensions, input_value),
|
||||
_ => unimplemented!("main function input not implemented for type"),
|
||||
}
|
||||
}
|
||||
@ -206,9 +186,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
|
||||
// Iterate over main function inputs and allocate new passed-by variable values
|
||||
let mut input_variables = vec![];
|
||||
for (input_model, input_option) in
|
||||
function.inputs.clone().into_iter().zip(inputs.into_iter())
|
||||
{
|
||||
for (input_model, input_option) in function.inputs.clone().into_iter().zip(inputs.into_iter()) {
|
||||
let input_name = new_scope(function_name.clone(), input_model.identifier.name.clone());
|
||||
let input_value = self.allocate_main_function_input(
|
||||
cs,
|
||||
@ -229,11 +207,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
self.enforce_function(cs, scope, function_name, function, input_variables)
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_definitions(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
program: Program,
|
||||
) -> Result<(), ImportError> {
|
||||
pub(crate) fn resolve_definitions(&mut self, cs: &mut CS, program: Program) -> Result<(), ImportError> {
|
||||
let program_name = program.name.clone();
|
||||
|
||||
// evaluate and store all imports
|
||||
@ -244,30 +218,16 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
.collect::<Result<Vec<_>, ImportError>>()?;
|
||||
|
||||
// evaluate and store all circuit definitions
|
||||
program
|
||||
.circuits
|
||||
.into_iter()
|
||||
.for_each(|(identifier, circuit)| {
|
||||
let resolved_circuit_name =
|
||||
new_scope(program_name.to_string(), identifier.to_string());
|
||||
self.store(
|
||||
resolved_circuit_name,
|
||||
ConstrainedValue::CircuitDefinition(circuit),
|
||||
);
|
||||
});
|
||||
program.circuits.into_iter().for_each(|(identifier, circuit)| {
|
||||
let resolved_circuit_name = new_scope(program_name.to_string(), identifier.to_string());
|
||||
self.store(resolved_circuit_name, ConstrainedValue::CircuitDefinition(circuit));
|
||||
});
|
||||
|
||||
// evaluate and store all function definitions
|
||||
program
|
||||
.functions
|
||||
.into_iter()
|
||||
.for_each(|(function_name, function)| {
|
||||
let resolved_function_name =
|
||||
new_scope(program_name.to_string(), function_name.to_string());
|
||||
self.store(
|
||||
resolved_function_name,
|
||||
ConstrainedValue::Function(None, function),
|
||||
);
|
||||
});
|
||||
program.functions.into_iter().for_each(|(function_name, function)| {
|
||||
let resolved_function_name = new_scope(program_name.to_string(), function_name.to_string());
|
||||
self.store(resolved_function_name, ConstrainedValue::Function(None, function));
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -27,13 +27,9 @@ pub(crate) fn group_from_input<F: Field + PrimeField, G: GroupType<F>, CS: Const
|
||||
|
||||
// Check visibility of parameter
|
||||
let group_value = if private {
|
||||
G::alloc(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
G::alloc(cs.ns(|| name), || group_option.ok_or(SynthesisError::AssignmentMissing))?
|
||||
} else {
|
||||
G::alloc_input(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
G::alloc_input(cs.ns(|| name), || group_option.ok_or(SynthesisError::AssignmentMissing))?
|
||||
};
|
||||
|
||||
Ok(ConstrainedValue::Group(group_value))
|
||||
|
@ -14,12 +14,7 @@ use snarkos_models::{
|
||||
use std::env::current_dir;
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub fn enforce_import(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
import: Import,
|
||||
) -> Result<(), ImportError> {
|
||||
pub fn enforce_import(&mut self, cs: &mut CS, scope: String, import: Import) -> Result<(), ImportError> {
|
||||
let path = current_dir().map_err(|error| ImportError::DirectoryError(error))?;
|
||||
|
||||
// Sanitize the package path to the imports directory
|
||||
@ -64,19 +59,17 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
.find(|(circuit_name, _circuit_def)| symbol.symbol == *circuit_name);
|
||||
|
||||
let value = match matched_circuit {
|
||||
Some((_circuit_name, circuit_def)) => {
|
||||
ConstrainedValue::CircuitDefinition(circuit_def)
|
||||
}
|
||||
Some((_circuit_name, circuit_def)) => ConstrainedValue::CircuitDefinition(circuit_def),
|
||||
None => {
|
||||
// see if the imported symbol is a function
|
||||
let matched_function = program.functions.clone().into_iter().find(
|
||||
|(function_name, _function)| symbol.symbol.name == *function_name.name,
|
||||
);
|
||||
let matched_function = program
|
||||
.functions
|
||||
.clone()
|
||||
.into_iter()
|
||||
.find(|(function_name, _function)| symbol.symbol.name == *function_name.name);
|
||||
|
||||
match matched_function {
|
||||
Some((_function_name, function)) => {
|
||||
ConstrainedValue::Function(None, function)
|
||||
}
|
||||
Some((_function_name, function)) => ConstrainedValue::Function(None, function),
|
||||
None => unimplemented!(
|
||||
"cannot find imported symbol {} in imported file {}",
|
||||
symbol,
|
||||
@ -88,8 +81,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
|
||||
// take the alias if it is present
|
||||
let resolved_name = symbol.alias.unwrap_or(symbol.symbol);
|
||||
let resolved_circuit_name =
|
||||
new_scope(program_name.to_string(), resolved_name.to_string());
|
||||
let resolved_circuit_name = new_scope(program_name.to_string(), resolved_name.to_string());
|
||||
|
||||
// store imported circuit under resolved name
|
||||
self.store(resolved_circuit_name, value);
|
||||
@ -99,9 +91,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
program
|
||||
.imports
|
||||
.into_iter()
|
||||
.map(|nested_import| {
|
||||
self.enforce_import(cs, program_name.name.clone(), nested_import)
|
||||
})
|
||||
.map(|nested_import| self.enforce_import(cs, program_name.name.clone(), nested_import))
|
||||
.collect::<Result<Vec<_>, ImportError>>()?;
|
||||
|
||||
Ok(())
|
||||
|
@ -27,10 +27,7 @@ pub use value::*;
|
||||
pub mod statement;
|
||||
pub use statement::*;
|
||||
|
||||
use crate::{
|
||||
errors::CompilerError,
|
||||
GroupType,
|
||||
};
|
||||
use crate::{errors::CompilerError, GroupType};
|
||||
use leo_types::{InputValue, Program};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -55,8 +52,7 @@ pub fn generate_constraints<F: Field + PrimeField, G: GroupType<F>, CS: Constrai
|
||||
|
||||
match main.clone() {
|
||||
ConstrainedValue::Function(_circuit_identifier, function) => {
|
||||
let result =
|
||||
resolved_program.enforce_main_function(cs, program_name, function, parameters)?;
|
||||
let result = resolved_program.enforce_main_function(cs, program_name, function, parameters)?;
|
||||
log::debug!("{}", result);
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -6,7 +6,18 @@ use crate::{
|
||||
new_scope,
|
||||
GroupType,
|
||||
};
|
||||
use leo_types::{Assignee, ConditionalNestedOrEndStatement, ConditionalStatement, Statement, Expression, Identifier, Integer, RangeOrExpression, Type, Variable};
|
||||
use leo_types::{
|
||||
Assignee,
|
||||
ConditionalNestedOrEndStatement,
|
||||
ConditionalStatement,
|
||||
Expression,
|
||||
Identifier,
|
||||
Integer,
|
||||
RangeOrExpression,
|
||||
Statement,
|
||||
Type,
|
||||
Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
@ -21,16 +32,11 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
match assignee {
|
||||
Assignee::Identifier(name) => new_scope(scope, name.to_string()),
|
||||
Assignee::Array(array, _index) => self.resolve_assignee(scope, *array),
|
||||
Assignee::CircuitField(circuit_name, _member) => {
|
||||
self.resolve_assignee(scope, *circuit_name)
|
||||
}
|
||||
Assignee::CircuitField(circuit_name, _member) => self.resolve_assignee(scope, *circuit_name),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mutable_assignee(
|
||||
&mut self,
|
||||
name: String,
|
||||
) -> Result<&mut ConstrainedValue<F, G>, StatementError> {
|
||||
fn get_mutable_assignee(&mut self, name: String) -> Result<&mut ConstrainedValue<F, G>, StatementError> {
|
||||
// Check that assignee exists and is mutable
|
||||
Ok(match self.get_mut(&name) {
|
||||
Some(value) => match value {
|
||||
@ -53,8 +59,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
// Resolve index so we know if we are assigning to a single value or a range of values
|
||||
match range_or_expression {
|
||||
RangeOrExpression::Expression(index) => {
|
||||
let index =
|
||||
self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index)?;
|
||||
let index = self.enforce_index(cs, file_scope.clone(), function_scope.clone(), index)?;
|
||||
|
||||
// Modify the single value of the array in place
|
||||
match self.get_mutable_assignee(name)? {
|
||||
@ -104,18 +109,14 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
ConstrainedValue::Function(_circuit_identifier, function) => {
|
||||
return Err(StatementError::ImmutableCircuitFunction(
|
||||
function.function_name.to_string(),
|
||||
))
|
||||
));
|
||||
}
|
||||
ConstrainedValue::Static(_value) => {
|
||||
return Err(StatementError::ImmutableCircuitFunction("static".into()))
|
||||
return Err(StatementError::ImmutableCircuitFunction("static".into()));
|
||||
}
|
||||
_ => object.1 = new_value.to_owned(),
|
||||
},
|
||||
None => {
|
||||
return Err(StatementError::UndefinedCircuitObject(
|
||||
object_name.to_string(),
|
||||
))
|
||||
}
|
||||
None => return Err(StatementError::UndefinedCircuitObject(object_name.to_string())),
|
||||
}
|
||||
}
|
||||
_ => return Err(StatementError::UndefinedCircuit(object_name.to_string())),
|
||||
@ -136,13 +137,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let variable_name = self.resolve_assignee(function_scope.clone(), assignee.clone());
|
||||
|
||||
// Evaluate new value
|
||||
let new_value = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&vec![],
|
||||
expression,
|
||||
)?;
|
||||
let new_value = self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), &vec![], expression)?;
|
||||
|
||||
// Mutate the old value into the new value
|
||||
match assignee {
|
||||
@ -232,10 +227,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
function,
|
||||
)? {
|
||||
ConstrainedValue::Return(values) => values,
|
||||
value => unimplemented!(
|
||||
"multiple assignment only implemented for functions, got {}",
|
||||
value
|
||||
),
|
||||
value => unimplemented!("multiple assignment only implemented for functions, got {}", value),
|
||||
};
|
||||
|
||||
if variables.len() != return_values.len() {
|
||||
@ -332,30 +324,16 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
|
||||
// use gadget impl
|
||||
if condition.eq(&Boolean::Constant(true)) {
|
||||
self.iterate_or_early_return(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
statement.statements,
|
||||
return_types,
|
||||
)
|
||||
self.iterate_or_early_return(cs, file_scope, function_scope, statement.statements, return_types)
|
||||
} else {
|
||||
match statement.next {
|
||||
Some(next) => match next {
|
||||
ConditionalNestedOrEndStatement::Nested(nested) => self.enforce_conditional_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
*nested,
|
||||
return_types,
|
||||
),
|
||||
ConditionalNestedOrEndStatement::End(statements) => self.iterate_or_early_return(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
statements,
|
||||
return_types,
|
||||
),
|
||||
ConditionalNestedOrEndStatement::Nested(nested) => {
|
||||
self.enforce_conditional_statement(cs, file_scope, function_scope, *nested, return_types)
|
||||
}
|
||||
ConditionalNestedOrEndStatement::End(statements) => {
|
||||
self.iterate_or_early_return(cs, file_scope, function_scope, statements, return_types)
|
||||
}
|
||||
},
|
||||
None => Ok(None),
|
||||
}
|
||||
@ -410,11 +388,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
|
||||
self.enforce_boolean_eq(cs, bool_1, bool_2)?
|
||||
}
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.enforce_equal(cs, &num_2).map_err(|_| {
|
||||
StatementError::AssertionFailed(num_1.to_string(), num_2.to_string())
|
||||
})?
|
||||
}
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => num_1
|
||||
.enforce_equal(cs, &num_2)
|
||||
.map_err(|_| StatementError::AssertionFailed(num_1.to_string(), num_2.to_string()))?,
|
||||
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => fe_1
|
||||
.enforce_equal(cs, &fe_2)
|
||||
.map_err(|_| StatementError::AssertionFailed(fe_1.to_string(), fe_2.to_string()))?,
|
||||
@ -426,12 +402,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
self.enforce_assert_eq_statement(cs, left, right)?;
|
||||
}
|
||||
}
|
||||
(val_1, val_2) => {
|
||||
return Err(StatementError::AssertEq(
|
||||
val_1.to_string(),
|
||||
val_2.to_string(),
|
||||
))
|
||||
}
|
||||
(val_1, val_2) => return Err(StatementError::AssertEq(val_1.to_string(), val_2.to_string())),
|
||||
})
|
||||
}
|
||||
|
||||
@ -446,49 +417,21 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
let mut res = None;
|
||||
match statement {
|
||||
Statement::Return(expressions) => {
|
||||
res = Some(self.enforce_return_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
expressions,
|
||||
return_types,
|
||||
)?);
|
||||
res = Some(self.enforce_return_statement(cs, file_scope, function_scope, expressions, return_types)?);
|
||||
}
|
||||
Statement::Definition(variable, expression) => {
|
||||
self.enforce_definition_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
variable,
|
||||
expression,
|
||||
)?;
|
||||
self.enforce_definition_statement(cs, file_scope, function_scope, variable, expression)?;
|
||||
}
|
||||
Statement::Assign(variable, expression) => {
|
||||
self.enforce_assign_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
variable,
|
||||
expression,
|
||||
)?;
|
||||
self.enforce_assign_statement(cs, file_scope, function_scope, variable, expression)?;
|
||||
}
|
||||
Statement::MultipleAssign(variables, function) => {
|
||||
self.enforce_multiple_definition_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
variables,
|
||||
function,
|
||||
)?;
|
||||
self.enforce_multiple_definition_statement(cs, file_scope, function_scope, variables, function)?;
|
||||
}
|
||||
Statement::Conditional(statement) => {
|
||||
if let Some(early_return) = self.enforce_conditional_statement(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
statement,
|
||||
return_types,
|
||||
)? {
|
||||
if let Some(early_return) =
|
||||
self.enforce_conditional_statement(cs, file_scope, function_scope, statement, return_types)?
|
||||
{
|
||||
res = Some(early_return)
|
||||
}
|
||||
}
|
||||
@ -507,31 +450,15 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
|
||||
}
|
||||
}
|
||||
Statement::AssertEq(left, right) => {
|
||||
let resolved_left = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&vec![],
|
||||
left,
|
||||
)?;
|
||||
let resolved_right = self.enforce_expression(
|
||||
cs,
|
||||
file_scope.clone(),
|
||||
function_scope.clone(),
|
||||
&vec![],
|
||||
right,
|
||||
)?;
|
||||
let resolved_left =
|
||||
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), &vec![], left)?;
|
||||
let resolved_right =
|
||||
self.enforce_expression(cs, file_scope.clone(), function_scope.clone(), &vec![], right)?;
|
||||
|
||||
self.enforce_assert_eq_statement(cs, resolved_left, resolved_right)?;
|
||||
}
|
||||
Statement::Expression(expression) => {
|
||||
match self.enforce_expression(
|
||||
cs,
|
||||
file_scope,
|
||||
function_scope,
|
||||
&vec![],
|
||||
expression.clone(),
|
||||
)? {
|
||||
match self.enforce_expression(cs, file_scope, function_scope, &vec![], expression.clone())? {
|
||||
ConstrainedValue::Return(values) => {
|
||||
if !values.is_empty() {
|
||||
return Err(StatementError::Unassigned(expression.to_string()));
|
||||
|
@ -1,9 +1,6 @@
|
||||
//! The in memory stored value for a defined name in a resolved Leo program.
|
||||
|
||||
use crate::{
|
||||
errors::ValueError,
|
||||
FieldType, GroupType,
|
||||
};
|
||||
use crate::{errors::ValueError, FieldType, GroupType};
|
||||
use leo_types::{Circuit, Function, Identifier, Integer, IntegerType, Type};
|
||||
|
||||
use snarkos_models::{
|
||||
@ -16,10 +13,7 @@ use snarkos_models::{
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct ConstrainedCircuitMember<F: Field + PrimeField, G: GroupType<F>>(
|
||||
pub Identifier,
|
||||
pub ConstrainedValue<F, G>,
|
||||
);
|
||||
pub struct ConstrainedCircuitMember<F: Field + PrimeField, G: GroupType<F>>(pub Identifier, pub ConstrainedValue<F, G>);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
|
||||
@ -42,10 +36,7 @@ pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
pub(crate) fn from_other(
|
||||
value: String,
|
||||
other: &ConstrainedValue<F, G>,
|
||||
) -> Result<Self, ValueError> {
|
||||
pub(crate) fn from_other(value: String, other: &ConstrainedValue<F, G>) -> Result<Self, ValueError> {
|
||||
let other_type = other.to_type();
|
||||
|
||||
ConstrainedValue::from_type(value, &other_type)
|
||||
@ -62,9 +53,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
})),
|
||||
Type::Field => Ok(ConstrainedValue::Field(FieldType::constant(value)?)),
|
||||
Type::Group => Ok(ConstrainedValue::Group(G::constant(value)?)),
|
||||
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(
|
||||
value.parse::<bool>()?,
|
||||
))),
|
||||
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(value.parse::<bool>()?))),
|
||||
Type::Array(ref _type, _dimensions) => ConstrainedValue::from_type(value, _type),
|
||||
_ => Ok(ConstrainedValue::Unresolved(value)),
|
||||
}
|
||||
@ -137,9 +126,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F
|
||||
ConstrainedValue::CircuitDefinition(ref _definition) => {
|
||||
unimplemented!("cannot return circuit definition in program")
|
||||
}
|
||||
ConstrainedValue::Function(ref _circuit_option, ref function) => {
|
||||
write!(f, "{}", function)
|
||||
}
|
||||
ConstrainedValue::Function(ref _circuit_option, ref function) => write!(f, "{}", function),
|
||||
ConstrainedValue::Mutable(ref value) => write!(f, "mut {}", value),
|
||||
ConstrainedValue::Static(ref value) => write!(f, "static {}", value),
|
||||
ConstrainedValue::Unresolved(ref value) => write!(f, "unresolved {}", value),
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::errors::{FunctionError, ImportError};
|
||||
use leo_ast::{SyntaxError, ParserError};
|
||||
use leo_ast::{ParserError, SyntaxError};
|
||||
use leo_types::IntegerError;
|
||||
|
||||
use std::{io, path::PathBuf};
|
||||
|
@ -1,6 +1,4 @@
|
||||
use crate::errors::{
|
||||
BooleanError, FieldError, FunctionError, GroupError, ValueError,
|
||||
};
|
||||
use crate::errors::{BooleanError, FieldError, FunctionError, GroupError, ValueError};
|
||||
use leo_types::IntegerError;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
@ -47,10 +45,7 @@ pub enum ExpressionError {
|
||||
#[error("Spread should contain an array, got {}", _0)]
|
||||
InvalidSpread(String),
|
||||
|
||||
#[error(
|
||||
"Array {} must be declared before it is used in an inline expression",
|
||||
_0
|
||||
)]
|
||||
#[error("Array {} must be declared before it is used in an inline expression", _0)]
|
||||
UndefinedArray(String),
|
||||
|
||||
// Circuits
|
||||
@ -66,10 +61,7 @@ pub enum ExpressionError {
|
||||
#[error("Static member {} must be accessed using `::` syntax", _0)]
|
||||
InvalidStaticAccess(String),
|
||||
|
||||
#[error(
|
||||
"Circuit {} must be declared before it is used in an inline expression",
|
||||
_0
|
||||
)]
|
||||
#[error("Circuit {} must be declared before it is used in an inline expression", _0)]
|
||||
UndefinedCircuit(String),
|
||||
|
||||
#[error("Circuit {} has no member {}", _0, _1)]
|
||||
@ -85,10 +77,7 @@ pub enum ExpressionError {
|
||||
#[error("{}", _0)]
|
||||
FunctionError(#[from] Box<FunctionError>),
|
||||
|
||||
#[error(
|
||||
"Function {} must be declared before it is used in an inline expression",
|
||||
_0
|
||||
)]
|
||||
#[error("Function {} must be declared before it is used in an inline expression", _0)]
|
||||
UndefinedFunction(String),
|
||||
|
||||
// Conditionals
|
||||
|
@ -1,6 +1,4 @@
|
||||
use crate::errors::{
|
||||
BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError,
|
||||
};
|
||||
use crate::errors::{BooleanError, ExpressionError, FieldError, GroupError, StatementError, ValueError};
|
||||
use leo_types::IntegerError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
@ -43,11 +43,7 @@ pub enum StatementError {
|
||||
#[error("Cannot assign to immutable variable {}", _0)]
|
||||
ImmutableAssign(String),
|
||||
|
||||
#[error(
|
||||
"Multiple definition statement expected {} return values, got {}",
|
||||
_0,
|
||||
_1
|
||||
)]
|
||||
#[error("Multiple definition statement expected {} return values, got {}", _0, _1)]
|
||||
InvalidNumberOfDefinitions(usize, usize),
|
||||
|
||||
#[error("Function return statement expected {} return values, got {}", _0, _1)]
|
||||
|
@ -3,11 +3,10 @@
|
||||
use crate::errors::FieldError;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::gadgets::curves::FieldGadget;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
curves::FpGadget,
|
||||
curves::{FieldGadget, FpGadget},
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{
|
||||
alloc::AllocGadget,
|
||||
@ -15,12 +14,12 @@ use snarkos_models::{
|
||||
eq::{ConditionalEqGadget, EqGadget},
|
||||
select::CondSelectGadget,
|
||||
uint::UInt8,
|
||||
ToBitsGadget, ToBytesGadget,
|
||||
ToBitsGadget,
|
||||
ToBytesGadget,
|
||||
},
|
||||
},
|
||||
};
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp::Ordering;
|
||||
use std::{borrow::Borrow, cmp::Ordering};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum FieldType<F: Field + PrimeField> {
|
||||
@ -55,9 +54,9 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(
|
||||
FieldType::Allocated(allocated_value.add_constant(cs, constant_value)?),
|
||||
),
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => {
|
||||
Ok(FieldType::Allocated(allocated_value.add_constant(cs, constant_value)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,9 +73,9 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(
|
||||
FieldType::Allocated(allocated_value.sub_constant(cs, constant_value)?),
|
||||
),
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => {
|
||||
Ok(FieldType::Allocated(allocated_value.sub_constant(cs, constant_value)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,22 +92,16 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
}
|
||||
|
||||
(FieldType::Constant(constant_value), FieldType::Allocated(allocated_value))
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(
|
||||
FieldType::Allocated(allocated_value.mul_by_constant(cs, constant_value)?),
|
||||
),
|
||||
| (FieldType::Allocated(allocated_value), FieldType::Constant(constant_value)) => Ok(FieldType::Allocated(
|
||||
allocated_value.mul_by_constant(cs, constant_value)?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn div<CS: ConstraintSystem<F>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
other: &Self,
|
||||
) -> Result<Self, FieldError> {
|
||||
pub fn div<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Self, FieldError> {
|
||||
let inverse = match other {
|
||||
FieldType::Constant(constant) => {
|
||||
let constant_inverse = constant
|
||||
.inverse()
|
||||
.ok_or(FieldError::NoInverse(constant.to_string()))?;
|
||||
let constant_inverse = constant.inverse().ok_or(FieldError::NoInverse(constant.to_string()))?;
|
||||
FieldType::Constant(constant_inverse)
|
||||
}
|
||||
FieldType::Allocated(allocated) => {
|
||||
@ -134,25 +127,16 @@ impl<F: Field + PrimeField> FieldType<F> {
|
||||
F::from_str(&field_string).map_err(|_| SynthesisError::AssignmentMissing)
|
||||
}
|
||||
|
||||
pub fn allocated<CS: ConstraintSystem<F>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<FpGadget<F>, SynthesisError> {
|
||||
pub fn allocated<CS: ConstraintSystem<F>>(&self, mut cs: CS) -> Result<FpGadget<F>, SynthesisError> {
|
||||
match self {
|
||||
FieldType::Constant(constant) => {
|
||||
FpGadget::alloc(&mut cs.ns(|| format!("{:?}", constant)), || Ok(constant))
|
||||
}
|
||||
FieldType::Constant(constant) => FpGadget::alloc(&mut cs.ns(|| format!("{:?}", constant)), || Ok(constant)),
|
||||
FieldType::Allocated(allocated) => Ok(allocated.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> AllocGadget<String, F> for FieldType<F> {
|
||||
fn alloc<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<F>,
|
||||
>(
|
||||
fn alloc<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
@ -161,11 +145,7 @@ impl<F: Field + PrimeField> AllocGadget<String, F> for FieldType<F> {
|
||||
Ok(FieldType::Allocated(value))
|
||||
}
|
||||
|
||||
fn alloc_input<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<F>,
|
||||
>(
|
||||
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<F>>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
@ -239,11 +219,7 @@ impl<F: Field + PrimeField> CondSelectGadget<F> for FieldType<F> {
|
||||
second: &Self,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
if let Boolean::Constant(cond) = *cond {
|
||||
if cond {
|
||||
Ok(first.clone())
|
||||
} else {
|
||||
Ok(second.clone())
|
||||
}
|
||||
if cond { Ok(first.clone()) } else { Ok(second.clone()) }
|
||||
} else {
|
||||
let first_gadget = first.allocated(&mut cs)?;
|
||||
let second_gadget = second.allocated(&mut cs)?;
|
||||
@ -264,10 +240,7 @@ impl<F: Field + PrimeField> ToBitsGadget<F> for FieldType<F> {
|
||||
self_gadget.to_bits(cs)
|
||||
}
|
||||
|
||||
fn to_bits_strict<CS: ConstraintSystem<F>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
fn to_bits_strict<CS: ConstraintSystem<F>>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bits_strict(cs)
|
||||
}
|
||||
@ -279,10 +252,7 @@ impl<F: Field + PrimeField> ToBytesGadget<F> for FieldType<F> {
|
||||
self_gadget.to_bytes(cs)
|
||||
}
|
||||
|
||||
fn to_bytes_strict<CS: ConstraintSystem<F>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<UInt8>, SynthesisError> {
|
||||
fn to_bytes_strict<CS: ConstraintSystem<F>>(&self, mut cs: CS) -> Result<Vec<UInt8>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bytes_strict(cs)
|
||||
}
|
||||
|
@ -17,7 +17,8 @@ use snarkos_models::{
|
||||
eq::{ConditionalEqGadget, EqGadget},
|
||||
select::CondSelectGadget,
|
||||
uint::UInt8,
|
||||
ToBitsGadget, ToBytesGadget,
|
||||
ToBitsGadget,
|
||||
ToBytesGadget,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -43,23 +44,18 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
}
|
||||
|
||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
let result = <EdwardsBlsGadget as GroupGadget<
|
||||
GroupAffine<EdwardsParameters>,
|
||||
Fq,
|
||||
>>::add(self_value, cs, other_value)?;
|
||||
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::add(
|
||||
self_value,
|
||||
cs,
|
||||
other_value,
|
||||
)?;
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
}
|
||||
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => Ok(EdwardsGroupType::Allocated(
|
||||
allocated_value.add_constant(cs, constant_value)?,
|
||||
)),
|
||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => Ok(
|
||||
EdwardsGroupType::Allocated(allocated_value.add_constant(cs, constant_value)?),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,23 +66,18 @@ impl GroupType<Fq> for EdwardsGroupType {
|
||||
}
|
||||
|
||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
let result = <EdwardsBlsGadget as GroupGadget<
|
||||
GroupAffine<EdwardsParameters>,
|
||||
Fq,
|
||||
>>::sub(self_value, cs, other_value)?;
|
||||
let result = <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::sub(
|
||||
self_value,
|
||||
cs,
|
||||
other_value,
|
||||
)?;
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
}
|
||||
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => Ok(EdwardsGroupType::Allocated(
|
||||
allocated_value.sub_constant(cs, constant_value)?,
|
||||
)),
|
||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => Ok(
|
||||
EdwardsGroupType::Allocated(allocated_value.sub_constant(cs, constant_value)?),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,10 +105,7 @@ impl EdwardsGroupType {
|
||||
Self::edwards_affine_from_str(affine_string).map_err(|_| SynthesisError::AssignmentMissing)
|
||||
}
|
||||
|
||||
pub fn allocated<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<EdwardsBlsGadget, SynthesisError> {
|
||||
pub fn allocated<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<EdwardsBlsGadget, SynthesisError> {
|
||||
match self {
|
||||
EdwardsGroupType::Constant(constant) => {
|
||||
<EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(
|
||||
@ -131,35 +119,24 @@ impl EdwardsGroupType {
|
||||
}
|
||||
|
||||
impl AllocGadget<String, Fq> for EdwardsGroupType {
|
||||
fn alloc<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<Fq>,
|
||||
>(
|
||||
fn alloc<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<Fq>>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(
|
||||
cs,
|
||||
|| Self::alloc_x_helper(value_gen),
|
||||
)?;
|
||||
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(cs, || {
|
||||
Self::alloc_x_helper(value_gen)
|
||||
})?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
}
|
||||
|
||||
fn alloc_input<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<Fq>,
|
||||
>(
|
||||
fn alloc_input<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>, CS: ConstraintSystem<Fq>>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
let value =
|
||||
<EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc_input(
|
||||
cs,
|
||||
|| Self::alloc_x_helper(value_gen),
|
||||
)?;
|
||||
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc_input(cs, || {
|
||||
Self::alloc_x_helper(value_gen)
|
||||
})?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
}
|
||||
@ -176,18 +153,12 @@ impl PartialEq for EdwardsGroupType {
|
||||
self_value.eq(other_value)
|
||||
}
|
||||
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(
|
||||
allocated_value,
|
||||
)
|
||||
.map(|allocated_value| allocated_value == *constant_value)
|
||||
.unwrap_or(false),
|
||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
||||
<EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(allocated_value)
|
||||
.map(|allocated_value| allocated_value == *constant_value)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,22 +185,11 @@ impl ConditionalEqGadget<Fq> for EdwardsGroupType {
|
||||
}
|
||||
// a - a
|
||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
<EdwardsBlsGadget>::conditional_enforce_equal(
|
||||
self_value,
|
||||
cs,
|
||||
other_value,
|
||||
condition,
|
||||
)
|
||||
<EdwardsBlsGadget>::conditional_enforce_equal(self_value, cs, other_value, condition)
|
||||
}
|
||||
// c - a = a - c
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => {
|
||||
(EdwardsGroupType::Constant(constant_value), EdwardsGroupType::Allocated(allocated_value))
|
||||
| (EdwardsGroupType::Allocated(allocated_value), EdwardsGroupType::Constant(constant_value)) => {
|
||||
let x = FpGadget::from(&mut cs, &constant_value.x);
|
||||
let y = FpGadget::from(&mut cs, &constant_value.y);
|
||||
let constant_gadget = EdwardsBlsGadget::new(x, y);
|
||||
@ -252,16 +212,11 @@ impl CondSelectGadget<Fq> for EdwardsGroupType {
|
||||
second: &Self,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
if let Boolean::Constant(cond) = *cond {
|
||||
if cond {
|
||||
Ok(first.clone())
|
||||
} else {
|
||||
Ok(second.clone())
|
||||
}
|
||||
if cond { Ok(first.clone()) } else { Ok(second.clone()) }
|
||||
} else {
|
||||
let first_gadget = first.allocated(&mut cs)?;
|
||||
let second_gadget = second.allocated(&mut cs)?;
|
||||
let result =
|
||||
EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
|
||||
let result = EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
}
|
||||
@ -273,18 +228,12 @@ impl CondSelectGadget<Fq> for EdwardsGroupType {
|
||||
}
|
||||
|
||||
impl ToBitsGadget<Fq> for EdwardsGroupType {
|
||||
fn to_bits<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
fn to_bits<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bits(cs)
|
||||
}
|
||||
|
||||
fn to_bits_strict<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
fn to_bits_strict<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bits_strict(cs)
|
||||
}
|
||||
@ -296,10 +245,7 @@ impl ToBytesGadget<Fq> for EdwardsGroupType {
|
||||
self_gadget.to_bytes(cs)
|
||||
}
|
||||
|
||||
fn to_bytes_strict<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<UInt8>, SynthesisError> {
|
||||
fn to_bytes_strict<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<Vec<UInt8>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bytes_strict(cs)
|
||||
}
|
||||
|
@ -10,7 +10,8 @@ use snarkos_models::{
|
||||
alloc::AllocGadget,
|
||||
eq::{ConditionalEqGadget, EqGadget},
|
||||
select::CondSelectGadget,
|
||||
ToBitsGadget, ToBytesGadget,
|
||||
ToBitsGadget,
|
||||
ToBytesGadget,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use crate::{get_error, get_output, parse_program, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, FunctionError},
|
||||
ConstrainedValue,
|
||||
@ -7,15 +7,16 @@ use leo_types::{InputValue, Integer, IntegerError};
|
||||
|
||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/array/";
|
||||
|
||||
// [1, 1, 1]
|
||||
fn output_ones(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Array(
|
||||
vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32))); 3]
|
||||
)])
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Array(vec![
|
||||
ConstrainedValue::Integer(
|
||||
Integer::U32(UInt32::constant(1u32))
|
||||
);
|
||||
3
|
||||
])])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
@ -46,9 +47,7 @@ fn fail_array(program: EdwardsTestCompiler) {
|
||||
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(
|
||||
IntegerError::SynthesisError(_string),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::SynthesisError(_string))) => {}
|
||||
error => panic!("Expected synthesis error, got {}", error),
|
||||
}
|
||||
}
|
||||
@ -57,31 +56,41 @@ fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_inline() {
|
||||
let program = compile_program(DIRECTORY_NAME, "inline.leo").unwrap();
|
||||
let bytes = include_bytes!("inline.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_ones(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_initializer() {
|
||||
let program = compile_program(DIRECTORY_NAME, "initializer.leo").unwrap();
|
||||
let bytes = include_bytes!("initializer.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_ones(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_spread() {
|
||||
let program = compile_program(DIRECTORY_NAME, "spread.leo").unwrap();
|
||||
let bytes = include_bytes!("spread.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_ones(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slice() {
|
||||
let program = compile_program(DIRECTORY_NAME, "slice.leo").unwrap();
|
||||
let bytes = include_bytes!("slice.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_ones(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi() {
|
||||
let program = compile_program(DIRECTORY_NAME, "multi.leo").unwrap();
|
||||
let bytes = include_bytes!("multi.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_multi(program);
|
||||
}
|
||||
|
||||
@ -89,26 +98,30 @@ fn test_multi() {
|
||||
|
||||
#[test]
|
||||
fn test_input_array() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input_array.leo").unwrap();
|
||||
program.set_inputs(vec![Some(InputValue::Array(vec![
|
||||
InputValue::Integer(
|
||||
1u128
|
||||
);
|
||||
3
|
||||
]))]);
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Array(vec![InputValue::Integer(1u128); 3]))]);
|
||||
|
||||
output_ones(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_array_fail() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input_array.leo").unwrap();
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1u128))]);
|
||||
|
||||
fail_array(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_field_none() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input_array.leo").unwrap();
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![None]);
|
||||
|
||||
fail_synthesis(program)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use crate::{get_error, get_output, parse_program, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError},
|
||||
ConstrainedValue,
|
||||
@ -7,15 +7,10 @@ use leo_types::InputValue;
|
||||
|
||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/boolean/";
|
||||
|
||||
pub fn output_expected_boolean(program: EdwardsTestCompiler, boolean: bool) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(
|
||||
boolean
|
||||
))])
|
||||
.to_string(),
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(boolean))]).to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
@ -30,67 +25,69 @@ pub fn output_false(program: EdwardsTestCompiler) {
|
||||
|
||||
fn fail_evaluate(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::BooleanError(
|
||||
BooleanError::CannotEvaluate(_string),
|
||||
)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::BooleanError(BooleanError::CannotEvaluate(_string)),
|
||||
))) => {}
|
||||
error => panic!("Expected evaluate error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_enforce(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::BooleanError(
|
||||
BooleanError::CannotEnforce(_string),
|
||||
)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::BooleanError(BooleanError::CannotEnforce(_string)),
|
||||
))) => {}
|
||||
error => panic!("Expected evaluate error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_boolean(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::BooleanError(
|
||||
BooleanError::InvalidBoolean(_string),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::BooleanError(BooleanError::InvalidBoolean(_string))) => {}
|
||||
error => panic!("Expected invalid boolean error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::BooleanError(
|
||||
BooleanError::SynthesisError(_string),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::BooleanError(BooleanError::SynthesisError(_string))) => {}
|
||||
error => panic!("Expected synthesis error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true() {
|
||||
let program = compile_program(DIRECTORY_NAME, "true.leo").unwrap();
|
||||
let bytes = include_bytes!("true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_true(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "false.leo").unwrap();
|
||||
let bytes = include_bytes!("false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_false(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_bool_field() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input_bool.leo").unwrap();
|
||||
let bytes = include_bytes!("input_bool.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1u128))]);
|
||||
|
||||
fail_boolean(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_bool_none() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input_bool.leo").unwrap();
|
||||
let bytes = include_bytes!("input_bool.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![None]);
|
||||
|
||||
fail_synthesis(program);
|
||||
}
|
||||
|
||||
@ -98,19 +95,25 @@ fn test_input_bool_none() {
|
||||
|
||||
#[test]
|
||||
fn test_not_true() {
|
||||
let program = compile_program(DIRECTORY_NAME, "not_true.leo").unwrap();
|
||||
let bytes = include_bytes!("not_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_false(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "not_false.leo").unwrap();
|
||||
let bytes = include_bytes!("not_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_true(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_u32() {
|
||||
let program = compile_program(DIRECTORY_NAME, "not_u32.leo").unwrap();
|
||||
let bytes = include_bytes!("not_u32.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_evaluate(program);
|
||||
}
|
||||
|
||||
@ -118,25 +121,33 @@ fn test_not_u32() {
|
||||
|
||||
#[test]
|
||||
fn test_true_or_true() {
|
||||
let program = compile_program(DIRECTORY_NAME, "true_||_true.leo").unwrap();
|
||||
let bytes = include_bytes!("true_||_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_true(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_or_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "true_||_false.leo").unwrap();
|
||||
let bytes = include_bytes!("true_||_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_true(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_false_or_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "false_||_false.leo").unwrap();
|
||||
let bytes = include_bytes!("false_||_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_false(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_or_u32() {
|
||||
let program = compile_program(DIRECTORY_NAME, "true_||_u32.leo").unwrap();
|
||||
let bytes = include_bytes!("true_||_u32.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_enforce(program);
|
||||
}
|
||||
|
||||
@ -144,25 +155,33 @@ fn test_true_or_u32() {
|
||||
|
||||
#[test]
|
||||
fn test_true_and_true() {
|
||||
let program = compile_program(DIRECTORY_NAME, "true_&&_true.leo").unwrap();
|
||||
let bytes = include_bytes!("true_&&_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_true(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_and_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "true_&&_false.leo").unwrap();
|
||||
let bytes = include_bytes!("true_&&_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_false(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_false_and_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "false_&&_false.leo").unwrap();
|
||||
let bytes = include_bytes!("false_&&_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_false(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_true_and_u32() {
|
||||
let program = compile_program(DIRECTORY_NAME, "true_&&_u32.leo").unwrap();
|
||||
let bytes = include_bytes!("true_&&_u32.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_enforce(program);
|
||||
}
|
||||
|
||||
@ -170,6 +189,8 @@ fn test_true_and_u32() {
|
||||
|
||||
#[test]
|
||||
fn test_all() {
|
||||
let program = compile_program(DIRECTORY_NAME, "all.leo").unwrap();
|
||||
let bytes = include_bytes!("all.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_false(program);
|
||||
}
|
||||
|
@ -1,18 +1,20 @@
|
||||
use crate::{
|
||||
compile_program, get_error, get_output, integers::u32::output_one, EdwardsConstrainedValue,
|
||||
get_error,
|
||||
get_output,
|
||||
integers::u32::output_one,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
|
||||
ConstrainedCircuitMember, ConstrainedValue,
|
||||
ConstrainedCircuitMember,
|
||||
ConstrainedValue,
|
||||
};
|
||||
use leo_types::{Expression, Function, Identifier, Integer,
|
||||
Statement, Type,};
|
||||
use leo_types::{Expression, Function, Identifier, Integer, Statement, Type};
|
||||
|
||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/circuits/";
|
||||
|
||||
// Circ { x: 1u32 }
|
||||
fn output_circuit(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
@ -31,18 +33,18 @@ fn output_circuit(program: EdwardsTestCompiler) {
|
||||
|
||||
fn fail_expected_member(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::ExpectedCircuitMember(_string)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::ExpectedCircuitMember(_string),
|
||||
))) => {}
|
||||
error => panic!("Expected invalid circuit member error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_undefined_member(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::UndefinedMemberAccess(_, _)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::UndefinedMemberAccess(_, _),
|
||||
))) => {}
|
||||
error => panic!("Expected undefined circuit member error, got {}", error),
|
||||
}
|
||||
}
|
||||
@ -51,23 +53,29 @@ fn fail_undefined_member(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_inline() {
|
||||
let program = compile_program(DIRECTORY_NAME, "inline.leo").unwrap();
|
||||
let bytes = include_bytes!("inline.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_circuit(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inline_fail() {
|
||||
let program = compile_program(DIRECTORY_NAME, "inline_fail.leo").unwrap();
|
||||
let bytes = include_bytes!("inline_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_expected_member(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inline_undefined() {
|
||||
let program = compile_program(DIRECTORY_NAME, "inline_undefined.leo").unwrap();
|
||||
let bytes = include_bytes!("inline_undefined.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::UndefinedCircuit(_)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::UndefinedCircuit(_),
|
||||
))) => {}
|
||||
error => panic!("Expected undefined circuit error, got {}", error),
|
||||
}
|
||||
}
|
||||
@ -76,62 +84,79 @@ fn test_inline_undefined() {
|
||||
|
||||
#[test]
|
||||
fn test_member_field() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_field.leo").unwrap();
|
||||
let bytes = include_bytes!("member_field.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_field_fail() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_field_fail.leo").unwrap();
|
||||
let bytes = include_bytes!("member_field_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_undefined_member(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_function() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_function.leo").unwrap();
|
||||
let bytes = include_bytes!("member_function.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_function_fail() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_function_fail.leo").unwrap();
|
||||
let bytes = include_bytes!("member_function_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_undefined_member(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_function_invalid() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_function_invalid.leo").unwrap();
|
||||
let bytes = include_bytes!("member_function_invalid.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::InvalidStaticAccess(_)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::InvalidStaticAccess(_),
|
||||
))) => {}
|
||||
error => panic!("Expected invalid function error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_static_function() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_static_function.leo").unwrap();
|
||||
let bytes = include_bytes!("member_static_function.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_static_function_undefined() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_static_function_undefined.leo").unwrap();
|
||||
let bytes = include_bytes!("member_static_function_undefined.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::UndefinedStaticAccess(_, _)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::UndefinedStaticAccess(_, _),
|
||||
))) => {}
|
||||
error => panic!("Expected undefined static function error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_member_static_function_invalid() {
|
||||
let program = compile_program(DIRECTORY_NAME, "member_static_function_invalid.leo").unwrap();
|
||||
let bytes = include_bytes!("member_static_function_invalid.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::InvalidMemberAccess(_)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::InvalidMemberAccess(_),
|
||||
))) => {}
|
||||
error => panic!("Expected invalid static function error, got {}", error),
|
||||
}
|
||||
}
|
||||
@ -139,7 +164,9 @@ fn test_member_static_function_invalid() {
|
||||
// Self
|
||||
#[test]
|
||||
fn test_self() {
|
||||
let program = compile_program(DIRECTORY_NAME, "self.leo").unwrap();
|
||||
let bytes = include_bytes!("self.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
let output = get_output(program);
|
||||
|
||||
// circuit Circ {
|
||||
|
@ -1,29 +1,33 @@
|
||||
use crate::boolean::{output_expected_boolean, output_false, output_true};
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use crate::{
|
||||
boolean::{output_expected_boolean, output_false, output_true},
|
||||
get_error,
|
||||
get_output,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, FieldError, FunctionError},
|
||||
ConstrainedValue, FieldType,
|
||||
ConstrainedValue,
|
||||
FieldType,
|
||||
};
|
||||
use leo_types::InputValue;
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_gadgets::curves::edwards_bls12::FqGadget;
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use snarkos_models::gadgets::{
|
||||
curves::field::FieldGadget,
|
||||
r1cs::{ConstraintSystem, TestConstraintSystem},
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
curves::field::FieldGadget,
|
||||
r1cs::{ConstraintSystem, TestConstraintSystem},
|
||||
},
|
||||
};
|
||||
use snarkos_utilities::biginteger::BigInteger256;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/field/";
|
||||
|
||||
fn output_expected_constant(program: EdwardsTestCompiler, expected: Fq) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Field(FieldType::Constant(
|
||||
expected
|
||||
))])
|
||||
.to_string(),
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Field(FieldType::Constant(expected))]).to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
@ -33,9 +37,7 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: FqGadget) {
|
||||
|
||||
match output {
|
||||
EdwardsConstrainedValue::Return(vec) => match vec.as_slice() {
|
||||
[ConstrainedValue::Field(FieldType::Allocated(fp_gadget))] => {
|
||||
assert_eq!(*fp_gadget, expected as FqGadget)
|
||||
}
|
||||
[ConstrainedValue::Field(FieldType::Allocated(fp_gadget))] => assert_eq!(*fp_gadget, expected as FqGadget),
|
||||
_ => panic!("program output unknown return value"),
|
||||
},
|
||||
_ => panic!("program output unknown return value"),
|
||||
@ -59,28 +61,32 @@ fn fail_field(program: EdwardsTestCompiler) {
|
||||
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::FieldError(FieldError::SynthesisError(
|
||||
_string,
|
||||
))) => {}
|
||||
CompilerError::FunctionError(FunctionError::FieldError(FieldError::SynthesisError(_string))) => {}
|
||||
error => panic!("Expected synthesis error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
||||
let bytes = include_bytes!("zero.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_zero(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one() {
|
||||
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
|
||||
let bytes = include_bytes!("one.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_pass() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Field("1".into()))]);
|
||||
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
@ -91,14 +97,18 @@ fn test_input_pass() {
|
||||
|
||||
#[test]
|
||||
fn test_input_fail_bool() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
fail_field(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_fail_none() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![None]);
|
||||
fail_synthesis(program);
|
||||
}
|
||||
@ -122,7 +132,9 @@ fn test_add() {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let sum_allocated = FqGadget::from(cs, &sum);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "add.leo").unwrap();
|
||||
let bytes = include_bytes!("add.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -151,7 +163,9 @@ fn test_sub() {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let difference_allocated = FqGadget::from(cs, &difference);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
|
||||
let bytes = include_bytes!("sub.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -180,7 +194,9 @@ fn test_mul() {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let product_allocated = FqGadget::from(cs, &product);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "mul.leo").unwrap();
|
||||
let bytes = include_bytes!("mul.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -209,7 +225,9 @@ fn test_div() {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let quotient_allocated = FqGadget::from(cs, "ient);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "div.leo").unwrap();
|
||||
let bytes = include_bytes!("div.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -225,7 +243,9 @@ fn test_eq() {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
|
||||
let bytes = include_bytes!("eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
@ -238,7 +258,8 @@ fn test_eq() {
|
||||
|
||||
let result = r1.eq(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "eq.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -254,7 +275,9 @@ fn test_ge() {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "ge.leo").unwrap();
|
||||
let bytes = include_bytes!("ge.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
@ -267,7 +290,8 @@ fn test_ge() {
|
||||
|
||||
let result = r1.ge(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "ge.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -283,7 +307,9 @@ fn test_gt() {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "gt.leo").unwrap();
|
||||
let bytes = include_bytes!("gt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
@ -296,7 +322,8 @@ fn test_gt() {
|
||||
|
||||
let result = r1.gt(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "gt.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -312,7 +339,9 @@ fn test_le() {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "le.leo").unwrap();
|
||||
let bytes = include_bytes!("le.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
@ -325,7 +354,8 @@ fn test_le() {
|
||||
|
||||
let result = r1.le(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "le.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -341,7 +371,9 @@ fn test_lt() {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program(DIRECTORY_NAME, "lt.leo").unwrap();
|
||||
let bytes = include_bytes!("lt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
@ -354,7 +386,8 @@ fn test_lt() {
|
||||
|
||||
let result = r1.lt(&r2);
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "lt.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -369,7 +402,9 @@ fn test_assert_eq_pass() {
|
||||
for _ in 0..10 {
|
||||
let r1: u64 = rand::random();
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "assert_eq.leo").unwrap();
|
||||
let bytes = include_bytes!("assert_eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
@ -389,7 +424,9 @@ fn test_assert_eq_fail() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut program = compile_program(DIRECTORY_NAME, "assert_eq.leo").unwrap();
|
||||
let bytes = include_bytes!("assert_eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1.to_string())),
|
||||
Some(InputValue::Field(r2.to_string())),
|
||||
@ -416,7 +453,8 @@ fn test_ternary() {
|
||||
let g1 = FqGadget::from(cs.ns(|| "g1"), &f1);
|
||||
let g2 = FqGadget::from(cs.ns(|| "g2"), &f2);
|
||||
|
||||
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program_1 = parse_program(bytes).unwrap();
|
||||
let mut program_2 = program_1.clone();
|
||||
|
||||
// true -> field 1
|
||||
|
@ -1,5 +1,9 @@
|
||||
use crate::{
|
||||
compile_program, get_error, get_output, integers::u32::output_one, EdwardsConstrainedValue,
|
||||
get_error,
|
||||
get_output,
|
||||
integers::u32::output_one,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::{
|
||||
@ -9,14 +13,9 @@ use leo_compiler::{
|
||||
|
||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/function/";
|
||||
|
||||
pub(crate) fn output_empty(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![]).to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
assert_eq!(EdwardsConstrainedValue::Return(vec![]).to_string(), output.to_string());
|
||||
}
|
||||
|
||||
// (true, false)
|
||||
@ -34,9 +33,9 @@ pub(crate) fn output_multiple(program: EdwardsTestCompiler) {
|
||||
|
||||
fn fail_undefined_identifier(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::UndefinedIdentifier(_)),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::UndefinedIdentifier(_),
|
||||
))) => {}
|
||||
error => panic!("Expected function undefined, got {}", error),
|
||||
}
|
||||
}
|
||||
@ -45,19 +44,25 @@ fn fail_undefined_identifier(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
let program = compile_program(DIRECTORY_NAME, "empty.leo").unwrap();
|
||||
let bytes = include_bytes!("empty.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_empty(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_return() {
|
||||
let program = compile_program(DIRECTORY_NAME, "return.leo").unwrap();
|
||||
let bytes = include_bytes!("return.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_undefined() {
|
||||
let program = compile_program(DIRECTORY_NAME, "undefined.leo").unwrap();
|
||||
let bytes = include_bytes!("undefined.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_undefined_identifier(program);
|
||||
}
|
||||
|
||||
@ -65,14 +70,15 @@ fn test_undefined() {
|
||||
|
||||
#[test]
|
||||
fn test_global_scope_fail() {
|
||||
let program = compile_program(DIRECTORY_NAME, "scope_fail.leo").unwrap();
|
||||
let bytes = include_bytes!("scope_fail.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::FunctionError(value)),
|
||||
)) => match *value {
|
||||
FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::UndefinedIdentifier(_),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ExpressionError(
|
||||
ExpressionError::FunctionError(value),
|
||||
))) => match *value {
|
||||
FunctionError::StatementError(StatementError::ExpressionError(ExpressionError::UndefinedIdentifier(_))) => {
|
||||
}
|
||||
error => panic!("Expected function undefined, got {}", error),
|
||||
},
|
||||
error => panic!("Expected function undefined, got {}", error),
|
||||
@ -81,7 +87,9 @@ fn test_global_scope_fail() {
|
||||
|
||||
#[test]
|
||||
fn test_value_unchanged() {
|
||||
let program = compile_program(DIRECTORY_NAME, "value_unchanged.leo").unwrap();
|
||||
let bytes = include_bytes!("value_unchanged.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
@ -89,11 +97,15 @@ fn test_value_unchanged() {
|
||||
|
||||
#[test]
|
||||
fn test_multiple_returns() {
|
||||
let program = compile_program(DIRECTORY_NAME, "multiple.leo").unwrap();
|
||||
let bytes = include_bytes!("multiple.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_multiple(program);
|
||||
}
|
||||
#[test]
|
||||
fn test_multiple_returns_main() {
|
||||
let program = compile_program(DIRECTORY_NAME, "multiple_main.leo").unwrap();
|
||||
let bytes = include_bytes!("multiple_main.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_multiple(program);
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
use crate::{
|
||||
boolean::{output_false, output_true},
|
||||
compile_program, fail_enforce, get_output, EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||
fail_enforce,
|
||||
get_output,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::{group::edwards_bls12::EdwardsGroupType, ConstrainedValue};
|
||||
use leo_types::InputValue;
|
||||
@ -13,18 +17,14 @@ use snarkos_models::{
|
||||
};
|
||||
use std::str::FromStr;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/group/";
|
||||
|
||||
const TEST_POINT_1: &str = "(7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)";
|
||||
const TEST_POINT_2: &str = "(1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)";
|
||||
|
||||
fn output_expected_constant(program: EdwardsTestCompiler, expected: EdwardsAffine) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(EdwardsGroupType::Constant(
|
||||
expected
|
||||
))])
|
||||
.to_string(),
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(EdwardsGroupType::Constant(expected))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
@ -49,27 +49,32 @@ fn output_zero(program: EdwardsTestCompiler) {
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
||||
let bytes = include_bytes!("zero.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_zero(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_point() {
|
||||
let point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let program = compile_program(DIRECTORY_NAME, "point.leo").unwrap();
|
||||
let bytes = include_bytes!("point.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_expected_constant(program, point);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Group(TEST_POINT_1.into()))]);
|
||||
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let constant_point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let allocated_point =
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point))
|
||||
.unwrap();
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point)).unwrap();
|
||||
|
||||
output_expected_allocated(program, allocated_point);
|
||||
}
|
||||
@ -83,7 +88,9 @@ fn test_add() {
|
||||
|
||||
let sum = point_1.add(&point_2);
|
||||
|
||||
let program = compile_program(DIRECTORY_NAME, "add.leo").unwrap();
|
||||
let bytes = include_bytes!("add.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_expected_constant(program, sum);
|
||||
}
|
||||
|
||||
@ -96,37 +103,48 @@ fn test_sub() {
|
||||
|
||||
let sum = point_1.sub(&point_2);
|
||||
|
||||
let program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
|
||||
let bytes = include_bytes!("sub.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_expected_constant(program, sum);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq_true() {
|
||||
let program = compile_program(DIRECTORY_NAME, "eq_true.leo").unwrap();
|
||||
let bytes = include_bytes!("eq_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_true(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "eq_false.leo").unwrap();
|
||||
let bytes = include_bytes!("eq_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_false(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assert_eq_pass() {
|
||||
let program = compile_program(DIRECTORY_NAME, "assert_eq_true.leo").unwrap();
|
||||
let bytes = include_bytes!("assert_eq_true.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
let _res = get_output(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assert_eq_fail() {
|
||||
let program = compile_program(DIRECTORY_NAME, "assert_eq_false.leo").unwrap();
|
||||
let bytes = include_bytes!("assert_eq_false.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
fail_enforce(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ternary() {
|
||||
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program_1 = parse_program(bytes).unwrap();
|
||||
|
||||
let mut program_2 = program_1.clone();
|
||||
|
||||
// true -> point_1
|
||||
@ -135,8 +153,7 @@ fn test_ternary() {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let point_1 = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let expected_point_1 =
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_1))
|
||||
.unwrap();
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_1)).unwrap();
|
||||
output_expected_allocated(program_1, expected_point_1);
|
||||
|
||||
// false -> point_2
|
||||
@ -145,7 +162,6 @@ fn test_ternary() {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let point_2 = EdwardsAffine::from_str(TEST_POINT_2).unwrap();
|
||||
let expected_point_2 =
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_2))
|
||||
.unwrap();
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(point_2)).unwrap();
|
||||
output_expected_allocated(program_2, expected_point_2);
|
||||
}
|
||||
|
@ -1,27 +1,39 @@
|
||||
use crate::{compile_program, integers::u32::output_one};
|
||||
use crate::{integers::u32::output_one, parse_program};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/import/";
|
||||
// Import tests rely on knowledge of local directories. They should be run locally only.
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_basic() {
|
||||
let program = compile_program(DIRECTORY_NAME, "basic.leo").unwrap();
|
||||
let bytes = include_bytes!("basic.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_multiple() {
|
||||
let program = compile_program(DIRECTORY_NAME, "multiple.leo").unwrap();
|
||||
let bytes = include_bytes!("multiple.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_star() {
|
||||
let program = compile_program(DIRECTORY_NAME, "star.leo").unwrap();
|
||||
let bytes = include_bytes!("star.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_alias() {
|
||||
let program = compile_program(DIRECTORY_NAME, "alias.leo").unwrap();
|
||||
let bytes = include_bytes!("alias.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
macro_rules! test_uint {
|
||||
($name: ident, $_type: ty, $gadget: ty, $directory: expr) => {
|
||||
($name: ident, $_type: ty, $gadget: ty) => {
|
||||
pub struct $name {}
|
||||
|
||||
impl $name {
|
||||
fn test_min(min: $_type) {
|
||||
let min_allocated = <$gadget>::constant(min);
|
||||
|
||||
let program = compile_program($directory, "min.leo").unwrap();
|
||||
let bytes = include_bytes!("min.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_expected_allocated(program, min_allocated);
|
||||
}
|
||||
@ -14,7 +15,8 @@ macro_rules! test_uint {
|
||||
fn test_max(max: $_type) {
|
||||
let max_allocated = <$gadget>::constant(max);
|
||||
|
||||
let program = compile_program($directory, "max.leo").unwrap();
|
||||
let bytes = include_bytes!("max.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_expected_allocated(program, max_allocated);
|
||||
}
|
||||
@ -26,18 +28,21 @@ macro_rules! test_uint {
|
||||
let num: $_type = rand::random();
|
||||
let expected = <$gadget>::constant(num);
|
||||
|
||||
let mut program = compile_program($directory, "input.leo").unwrap();
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(num as u128))]);
|
||||
|
||||
output_expected_allocated(program, expected);
|
||||
|
||||
// invalid input
|
||||
let mut program = compile_program($directory, "input.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
fail_integer(program);
|
||||
|
||||
// None input
|
||||
let mut program = compile_program($directory, "input.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
program.set_inputs(vec![None]);
|
||||
fail_synthesis(program);
|
||||
}
|
||||
@ -52,7 +57,9 @@ macro_rules! test_uint {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let sum_allocated = <$gadget>::alloc(cs, || Ok(sum)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "add.leo").unwrap();
|
||||
let bytes = include_bytes!("add.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -72,7 +79,9 @@ macro_rules! test_uint {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let difference_allocated = <$gadget>::alloc(cs, || Ok(difference)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "sub.leo").unwrap();
|
||||
let bytes = include_bytes!("sub.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -92,7 +101,9 @@ macro_rules! test_uint {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let product_allocated = <$gadget>::alloc(cs, || Ok(product)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "mul.leo").unwrap();
|
||||
let bytes = include_bytes!("mul.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -112,7 +123,9 @@ macro_rules! test_uint {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let quotient_allocated = <$gadget>::alloc(cs, || Ok(quotient)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "div.leo").unwrap();
|
||||
let bytes = include_bytes!("div.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -133,7 +146,9 @@ macro_rules! test_uint {
|
||||
let cs = TestConstraintSystem::<Fq>::new();
|
||||
let result_allocated = <$gadget>::alloc(cs, || Ok(result)).unwrap();
|
||||
|
||||
let mut program = compile_program($directory, "pow.leo").unwrap();
|
||||
let bytes = include_bytes!("pow.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -148,7 +163,9 @@ macro_rules! test_uint {
|
||||
let r1: $_type = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program($directory, "eq.leo").unwrap();
|
||||
let bytes = include_bytes!("eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
@ -161,7 +178,8 @@ macro_rules! test_uint {
|
||||
|
||||
let result = r1.eq(&r2);
|
||||
|
||||
let mut program = compile_program($directory, "eq.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -176,7 +194,9 @@ macro_rules! test_uint {
|
||||
let r1: $_type = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program($directory, "ge.leo").unwrap();
|
||||
let bytes = include_bytes!("ge.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
@ -189,7 +209,8 @@ macro_rules! test_uint {
|
||||
|
||||
let result = r1.ge(&r2);
|
||||
|
||||
let mut program = compile_program($directory, "ge.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -204,7 +225,9 @@ macro_rules! test_uint {
|
||||
let r1: $_type = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program($directory, "gt.leo").unwrap();
|
||||
let bytes = include_bytes!("gt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
@ -217,7 +240,8 @@ macro_rules! test_uint {
|
||||
|
||||
let result = r1.gt(&r2);
|
||||
|
||||
let mut program = compile_program($directory, "gt.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -232,7 +256,9 @@ macro_rules! test_uint {
|
||||
let r1: $_type = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program($directory, "le.leo").unwrap();
|
||||
let bytes = include_bytes!("le.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
@ -245,7 +271,8 @@ macro_rules! test_uint {
|
||||
|
||||
let result = r1.le(&r2);
|
||||
|
||||
let mut program = compile_program($directory, "le.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -260,7 +287,9 @@ macro_rules! test_uint {
|
||||
let r1: $_type = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program($directory, "lt.leo").unwrap();
|
||||
let bytes = include_bytes!("lt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
@ -273,7 +302,8 @@ macro_rules! test_uint {
|
||||
|
||||
let result = r1.lt(&r2);
|
||||
|
||||
let mut program = compile_program($directory, "lt.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -288,7 +318,9 @@ macro_rules! test_uint {
|
||||
let r1: $_type = rand::random();
|
||||
|
||||
// test equal
|
||||
let mut program = compile_program($directory, "assert_eq.leo").unwrap();
|
||||
let bytes = include_bytes!("assert_eq.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
@ -303,7 +335,8 @@ macro_rules! test_uint {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut program = compile_program($directory, "assert_eq.leo").unwrap();
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Integer(r1 as u128)),
|
||||
Some(InputValue::Integer(r2 as u128)),
|
||||
@ -322,7 +355,9 @@ macro_rules! test_uint {
|
||||
let g1 = <$gadget>::constant(r1);
|
||||
let g2 = <$gadget>::constant(r2);
|
||||
|
||||
let mut program_1 = compile_program($directory, "ternary.leo").unwrap();
|
||||
let bytes = include_bytes!("ternary.leo");
|
||||
let mut program_1 = parse_program(bytes).unwrap();
|
||||
|
||||
let mut program_2 = program_1.clone();
|
||||
|
||||
// true -> field 1
|
||||
|
@ -48,18 +48,14 @@ pub trait IntegerTester {
|
||||
|
||||
pub(crate) fn fail_integer(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(
|
||||
IntegerError::InvalidInteger(_string),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::InvalidInteger(_string))) => {}
|
||||
error => panic!("Expected invalid boolean error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(
|
||||
IntegerError::SynthesisError(_string),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(IntegerError::SynthesisError(_string))) => {}
|
||||
error => panic!("Expected synthesis error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,19 @@
|
||||
use crate::{
|
||||
boolean::{output_expected_boolean, output_false, output_true},
|
||||
compile_program, get_output,
|
||||
get_output,
|
||||
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::ConstrainedValue;
|
||||
use leo_types::{Integer, InputValue};
|
||||
use leo_types::{InputValue, Integer};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt128};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/integers/u128/";
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::TestConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, uint::UInt128},
|
||||
};
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt128) {
|
||||
let output = get_output(program);
|
||||
@ -26,8 +28,9 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt128) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // temporarily ignore memory expensive tests for travis
|
||||
fn test_u128() {
|
||||
test_uint!(TestU128, u128, UInt128, DIRECTORY_NAME);
|
||||
test_uint!(TestU128, u128, UInt128);
|
||||
|
||||
TestU128::test_min(std::u128::MIN);
|
||||
TestU128::test_max(std::u128::MAX);
|
||||
|
@ -1,17 +1,19 @@
|
||||
use crate::{
|
||||
boolean::{output_expected_boolean, output_false, output_true},
|
||||
compile_program, get_output,
|
||||
get_output,
|
||||
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::ConstrainedValue;
|
||||
use leo_types::{Integer, InputValue};
|
||||
use leo_types::{InputValue, Integer};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt16};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/integers/u16/";
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::TestConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, uint::UInt16},
|
||||
};
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt16) {
|
||||
let output = get_output(program);
|
||||
@ -27,7 +29,7 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt16) {
|
||||
|
||||
#[test]
|
||||
fn test_u16() {
|
||||
test_uint!(Testu16, u16, UInt16, DIRECTORY_NAME);
|
||||
test_uint!(Testu16, u16, UInt16);
|
||||
|
||||
Testu16::test_min(std::u16::MIN);
|
||||
Testu16::test_max(std::u16::MAX);
|
||||
|
@ -1,17 +1,19 @@
|
||||
use crate::{
|
||||
boolean::{output_expected_boolean, output_false, output_true},
|
||||
compile_program, get_output,
|
||||
get_output,
|
||||
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::ConstrainedValue;
|
||||
use leo_types::{Integer, InputValue};
|
||||
use leo_types::{InputValue, Integer};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt32};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/integers/u32/";
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::TestConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, uint::UInt32},
|
||||
};
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
|
||||
let output = get_output(program);
|
||||
@ -28,10 +30,8 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt32) {
|
||||
pub(crate) fn output_zero(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(0u32)
|
||||
))])
|
||||
.to_string(),
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0u32)))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
@ -39,17 +39,15 @@ pub(crate) fn output_zero(program: EdwardsTestCompiler) {
|
||||
pub(crate) fn output_one(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(1u32)
|
||||
))])
|
||||
.to_string(),
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32)))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_u32() {
|
||||
test_uint!(TestU32, u32, UInt32, DIRECTORY_NAME);
|
||||
test_uint!(TestU32, u32, UInt32);
|
||||
|
||||
TestU32::test_min(std::u32::MIN);
|
||||
TestU32::test_max(std::u32::MAX);
|
||||
@ -74,12 +72,16 @@ fn test_u32() {
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
||||
let bytes = include_bytes!("zero.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_zero(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one() {
|
||||
let program = compile_program(DIRECTORY_NAME, "one.leo").unwrap();
|
||||
let bytes = include_bytes!("one.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
@ -1,17 +1,19 @@
|
||||
use crate::{
|
||||
boolean::{output_expected_boolean, output_false, output_true},
|
||||
compile_program, get_output,
|
||||
get_output,
|
||||
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::ConstrainedValue;
|
||||
use leo_types::{Integer, InputValue};
|
||||
use leo_types::{InputValue, Integer};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt64};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/integers/u64/";
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::TestConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, uint::UInt64},
|
||||
};
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt64) {
|
||||
let output = get_output(program);
|
||||
@ -26,8 +28,9 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt64) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] //temporarily ignore memory expensive tests for travis
|
||||
fn test_u64() {
|
||||
test_uint!(Testu64, u64, UInt64, DIRECTORY_NAME);
|
||||
test_uint!(Testu64, u64, UInt64);
|
||||
|
||||
Testu64::test_min(std::u64::MIN);
|
||||
Testu64::test_max(std::u64::MAX);
|
||||
|
@ -1,17 +1,19 @@
|
||||
use crate::{
|
||||
boolean::{output_expected_boolean, output_false, output_true},
|
||||
compile_program, get_output,
|
||||
get_output,
|
||||
integers::{fail_integer, fail_synthesis, IntegerTester},
|
||||
EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||
parse_program,
|
||||
EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::ConstrainedValue;
|
||||
use leo_types::{Integer, InputValue};
|
||||
use leo_types::{InputValue, Integer};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::{alloc::AllocGadget, uint::UInt8};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/integers/u8/";
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::TestConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, uint::UInt8},
|
||||
};
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt8) {
|
||||
let output = get_output(program);
|
||||
@ -27,7 +29,7 @@ fn output_expected_allocated(program: EdwardsTestCompiler, expected: UInt8) {
|
||||
|
||||
#[test]
|
||||
fn test_u8() {
|
||||
test_uint!(Testu8, u8, UInt8, DIRECTORY_NAME);
|
||||
test_uint!(Testu8, u8, UInt8);
|
||||
|
||||
Testu8::test_min(std::u8::MIN);
|
||||
Testu8::test_max(std::u8::MAX);
|
||||
|
@ -19,7 +19,6 @@ use leo_compiler::{
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use std::env::current_dir;
|
||||
|
||||
pub type EdwardsTestCompiler = Compiler<Fq, EdwardsGroupType>;
|
||||
pub type EdwardsConstrainedValue = ConstrainedValue<Fq, EdwardsGroupType>;
|
||||
@ -38,32 +37,17 @@ pub(crate) fn get_error(program: EdwardsTestCompiler) -> CompilerError {
|
||||
|
||||
pub(crate) fn fail_enforce(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::AssertionFailed(_, _),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::AssertionFailed(_, _))) => {}
|
||||
error => panic!("Expected evaluate error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compile_program(
|
||||
directory_name: &str,
|
||||
file_name: &str,
|
||||
) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let path = current_dir().map_err(|error| CompilerError::DirectoryError(error))?;
|
||||
pub(crate) fn parse_program(bytes: &[u8]) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let program_string = String::from_utf8_lossy(bytes);
|
||||
|
||||
// Sanitize the package path to the test directory
|
||||
let mut package_path = path.clone();
|
||||
if package_path.is_file() {
|
||||
package_path.pop();
|
||||
}
|
||||
let mut compiler = EdwardsTestCompiler::new();
|
||||
|
||||
// Construct the path to the test file in the test directory
|
||||
let mut main_file_path = package_path.clone();
|
||||
main_file_path.push(directory_name);
|
||||
main_file_path.push(file_name);
|
||||
compiler.parse_program(&program_string)?;
|
||||
|
||||
println!("Compiling file - {:?}", main_file_path);
|
||||
|
||||
// Compile from the main file path
|
||||
EdwardsTestCompiler::init(file_name.to_string(), main_file_path)
|
||||
Ok(compiler)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{compile_program, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use crate::{parse_program, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, FunctionError, StatementError},
|
||||
ConstrainedValue,
|
||||
@ -8,18 +8,13 @@ use leo_types::{InputValue, Integer};
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint::UInt32};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/mutability/";
|
||||
|
||||
fn mut_success(program: EdwardsTestCompiler) {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let output = program.compile_constraints(&mut cs).unwrap();
|
||||
|
||||
assert!(cs.is_satisfied());
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(0)
|
||||
))])
|
||||
.to_string(),
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0)))]).to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
@ -31,59 +26,73 @@ fn mut_fail(program: EdwardsTestCompiler) {
|
||||
// It would be ideal if assert_eq!(Error1, Error2) were possible but unfortunately it is not due to
|
||||
// https://github.com/rust-lang/rust/issues/34158#issuecomment-224910299
|
||||
match err {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ImmutableAssign(_string),
|
||||
)) => {}
|
||||
CompilerError::FunctionError(FunctionError::StatementError(StatementError::ImmutableAssign(_string))) => {}
|
||||
err => panic!("Expected immutable assign error, got {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_let() {
|
||||
let program = compile_program(DIRECTORY_NAME, "let.leo").unwrap();
|
||||
let bytes = include_bytes!("let.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
mut_fail(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_let_mut() {
|
||||
let program = compile_program(DIRECTORY_NAME, "let_mut.leo").unwrap();
|
||||
let bytes = include_bytes!("let_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
mut_success(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array() {
|
||||
let program = compile_program(DIRECTORY_NAME, "array.leo").unwrap();
|
||||
let bytes = include_bytes!("array.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
mut_fail(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_array_mut() {
|
||||
let program = compile_program(DIRECTORY_NAME, "array_mut.leo").unwrap();
|
||||
let bytes = include_bytes!("array_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
mut_success(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit() {
|
||||
let program = compile_program(DIRECTORY_NAME, "circuit.leo").unwrap();
|
||||
let bytes = include_bytes!("circuit.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
mut_fail(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_circuit_mut() {
|
||||
let program = compile_program(DIRECTORY_NAME, "circuit_mut.leo").unwrap();
|
||||
let bytes = include_bytes!("circuit_mut.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
mut_success(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_input() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "function_input.leo").unwrap();
|
||||
let bytes = include_bytes!("function_input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1))]);
|
||||
mut_fail(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_input_mut() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "function_input_mut.leo").unwrap();
|
||||
let bytes = include_bytes!("function_input_mut.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1))]);
|
||||
mut_success(program);
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
use crate::{
|
||||
compile_program,
|
||||
integers::u32::{output_one, output_zero},
|
||||
parse_program,
|
||||
};
|
||||
use leo_types::InputValue;
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/statements/";
|
||||
|
||||
// Ternary if {bool}? {expression} : {expression};
|
||||
|
||||
#[test]
|
||||
fn test_ternary_basic() {
|
||||
let mut program_input_true = compile_program(DIRECTORY_NAME, "ternary_basic.leo").unwrap();
|
||||
let bytes = include_bytes!("ternary_basic.leo");
|
||||
let mut program_input_true = parse_program(bytes).unwrap();
|
||||
|
||||
let mut program_input_false = program_input_true.clone();
|
||||
|
||||
program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
@ -27,7 +27,9 @@ fn test_ternary_basic() {
|
||||
|
||||
#[test]
|
||||
fn test_iteration_basic() {
|
||||
let program = compile_program(DIRECTORY_NAME, "iteration_basic.leo").unwrap();
|
||||
let bytes = include_bytes!("iteration_basic.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
output_one(program);
|
||||
}
|
||||
|
||||
@ -35,15 +37,14 @@ fn test_iteration_basic() {
|
||||
|
||||
#[test]
|
||||
fn test_assertion_basic() {
|
||||
let program = compile_program(DIRECTORY_NAME, "assertion_basic.leo").unwrap();
|
||||
let bytes = include_bytes!("assertion_basic.leo");
|
||||
let program = parse_program(bytes).unwrap();
|
||||
|
||||
let mut program_input_true = program.clone();
|
||||
let mut cs_satisfied = TestConstraintSystem::<Fq>::new();
|
||||
|
||||
program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
let _output = program_input_true
|
||||
.compile_constraints(&mut cs_satisfied)
|
||||
.unwrap();
|
||||
let _output = program_input_true.compile_constraints(&mut cs_satisfied).unwrap();
|
||||
|
||||
assert!(cs_satisfied.is_satisfied());
|
||||
|
||||
@ -51,9 +52,7 @@ fn test_assertion_basic() {
|
||||
let mut cs_unsatisfied = TestConstraintSystem::<Fq>::new();
|
||||
|
||||
program_input_false.set_inputs(vec![Some(InputValue::Boolean(false))]);
|
||||
let _output = program_input_false
|
||||
.compile_constraints(&mut cs_unsatisfied)
|
||||
.unwrap();
|
||||
let _output = program_input_false.compile_constraints(&mut cs_unsatisfied).unwrap();
|
||||
|
||||
assert!(!cs_unsatisfied.is_satisfied());
|
||||
}
|
||||
|
@ -1,16 +1,14 @@
|
||||
use crate::compile_program;
|
||||
use crate::parse_program;
|
||||
use leo_ast::ParserError;
|
||||
use leo_compiler::errors::CompilerError;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/syntax/";
|
||||
|
||||
#[test]
|
||||
fn test_semicolon() {
|
||||
let error = compile_program(DIRECTORY_NAME, "semicolon.leo")
|
||||
.err()
|
||||
.unwrap();
|
||||
let bytes = include_bytes!("semicolon.leo");
|
||||
let error = parse_program(bytes).err().unwrap();
|
||||
|
||||
match error {
|
||||
CompilerError::ParserError(_) => {}
|
||||
CompilerError::ParserError(ParserError::SyntaxError(_)) => {}
|
||||
_ => panic!("test_semicolon failed the wrong expected error, should be a ParserError"),
|
||||
}
|
||||
}
|
||||
|
11
leo/cli.rs
11
leo/cli.rs
@ -1,5 +1,4 @@
|
||||
use crate::cli_types::*;
|
||||
use crate::errors::CLIError;
|
||||
use crate::{cli_types::*, errors::CLIError};
|
||||
|
||||
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||
|
||||
@ -31,9 +30,7 @@ pub trait CLI {
|
||||
.conflicts_with_all(a.1)
|
||||
.possible_values(a.2)
|
||||
.requires_all(a.3),
|
||||
false => Arg::from_usage(a.0)
|
||||
.conflicts_with_all(a.1)
|
||||
.requires_all(a.3),
|
||||
false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
|
||||
})
|
||||
.collect::<Vec<Arg<'static, 'static>>>();
|
||||
let subcommands = Self::SUBCOMMANDS
|
||||
@ -48,9 +45,7 @@ pub trait CLI {
|
||||
.conflicts_with_all(a.1)
|
||||
.possible_values(a.2)
|
||||
.requires_all(a.3),
|
||||
false => Arg::from_usage(a.0)
|
||||
.conflicts_with_all(a.1)
|
||||
.requires_all(a.3),
|
||||
false => Arg::from_usage(a.0).conflicts_with_all(a.1).requires_all(a.3),
|
||||
})
|
||||
.collect::<Vec<Arg<'static, 'static>>>(),
|
||||
)
|
||||
|
@ -21,9 +21,4 @@ pub type OptionType = (
|
||||
&'static [&'static str],
|
||||
);
|
||||
|
||||
pub type SubCommandType = (
|
||||
NameType,
|
||||
AboutType,
|
||||
&'static [OptionType],
|
||||
&'static [AppSettings],
|
||||
);
|
||||
pub type SubCommandType = (NameType, AboutType, &'static [OptionType], &'static [AppSettings]);
|
||||
|
@ -1,15 +1,17 @@
|
||||
use crate::directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory};
|
||||
use crate::errors::{BuildError, CLIError};
|
||||
use crate::files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory},
|
||||
errors::{BuildError, CLIError},
|
||||
files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME},
|
||||
};
|
||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||
|
||||
use snarkos_algorithms::snark::KeypairAssembly;
|
||||
use snarkos_curves::{bls12_377::Bls12_377, edwards_bls12::Fq};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BuildCommand;
|
||||
@ -18,10 +20,10 @@ impl CLI for BuildCommand {
|
||||
type Options = ();
|
||||
type Output = (Compiler<Fq, EdwardsGroupType>, bool);
|
||||
|
||||
const NAME: NameType = "build";
|
||||
const ABOUT: AboutType = "Compile the current package as a program";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "build";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
@ -46,9 +48,7 @@ impl CLI for BuildCommand {
|
||||
|
||||
// Verify the main file exists
|
||||
if !MainFile::exists_at(&package_path) {
|
||||
return Err(
|
||||
BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into(),
|
||||
);
|
||||
return Err(BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
|
||||
}
|
||||
|
||||
// Create the outputs directory
|
||||
@ -60,8 +60,7 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Compute the current program checksum
|
||||
let program =
|
||||
Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program_checksum = program.checksum()?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
|
@ -1,11 +1,7 @@
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeployCommand;
|
||||
@ -14,10 +10,10 @@ impl CLI for DeployCommand {
|
||||
type Options = ();
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "deploy";
|
||||
const ABOUT: AboutType = "Deploy the current package as a program to the network (*)";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "deploy";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
use crate::directories::{InputsDirectory, SourceDirectory};
|
||||
use crate::errors::{CLIError, InitError};
|
||||
use crate::files::{Gitignore, MainFile, Manifest};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
directories::{InputsDirectory, SourceDirectory},
|
||||
errors::{CLIError, InitError},
|
||||
files::{Gitignore, MainFile, Manifest},
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::env::current_dir;
|
||||
@ -13,10 +16,10 @@ impl CLI for InitCommand {
|
||||
type Options = Option<String>;
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "init";
|
||||
const ABOUT: AboutType = "Create a new Leo package in an existing directory";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "init";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoadCommand;
|
||||
@ -14,10 +10,10 @@ impl CLI for LoadCommand {
|
||||
type Options = ();
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "load";
|
||||
const ABOUT: AboutType = "Install a package from the package manager (*)";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "load";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
use crate::directories::{InputsDirectory, SourceDirectory};
|
||||
use crate::errors::{CLIError, NewError};
|
||||
use crate::files::{Gitignore, MainFile, Manifest};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
directories::{InputsDirectory, SourceDirectory},
|
||||
errors::{CLIError, NewError},
|
||||
files::{Gitignore, MainFile, Manifest},
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::env::current_dir;
|
||||
use std::fs;
|
||||
use std::{env::current_dir, fs};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NewCommand;
|
||||
@ -14,7 +16,6 @@ impl CLI for NewCommand {
|
||||
type Options = Option<String>;
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "new";
|
||||
const ABOUT: AboutType = "Create a new Leo package in a new directory";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[
|
||||
// (name, description, required, index)
|
||||
@ -26,6 +27,7 @@ impl CLI for NewCommand {
|
||||
),
|
||||
];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "new";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
|
@ -1,16 +1,17 @@
|
||||
use crate::commands::SetupCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::{Manifest, ProofFile};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::SetupCommand,
|
||||
errors::CLIError,
|
||||
files::{Manifest, ProofFile},
|
||||
};
|
||||
|
||||
use snarkos_algorithms::snark::{create_random_proof, Proof};
|
||||
use snarkos_curves::bls12_377::Bls12_377;
|
||||
|
||||
use clap::ArgMatches;
|
||||
use rand::thread_rng;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::time::Instant;
|
||||
use std::{convert::TryFrom, env::current_dir, time::Instant};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProveCommand;
|
||||
@ -19,10 +20,10 @@ impl CLI for ProveCommand {
|
||||
type Options = ();
|
||||
type Output = Proof<Bls12_377>;
|
||||
|
||||
const NAME: NameType = "prove";
|
||||
const ABOUT: AboutType = "Run the program and produce a proof";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "prove";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
@ -45,10 +46,7 @@ impl CLI for ProveCommand {
|
||||
let rng = &mut thread_rng();
|
||||
let program_proof = create_random_proof(program, ¶meters, rng).unwrap();
|
||||
|
||||
log::info!(
|
||||
"Prover completed in {:?} milliseconds",
|
||||
start.elapsed().as_millis()
|
||||
);
|
||||
log::info!("Prover completed in {:?} milliseconds", start.elapsed().as_millis());
|
||||
|
||||
// Write the proof file to the outputs directory
|
||||
let mut proof = vec![];
|
||||
|
@ -1,11 +1,7 @@
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PublishCommand;
|
||||
@ -14,10 +10,10 @@ impl CLI for PublishCommand {
|
||||
type Options = ();
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "publish";
|
||||
const ABOUT: AboutType = "Publish the current package to the package manager (*)";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "publish";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
use crate::commands::{ProveCommand, SetupCommand};
|
||||
use crate::errors::CLIError;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::{ProveCommand, SetupCommand},
|
||||
errors::CLIError,
|
||||
};
|
||||
|
||||
use snarkos_algorithms::snark::verify_proof;
|
||||
|
||||
@ -14,10 +17,10 @@ impl CLI for RunCommand {
|
||||
type Options = ();
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "run";
|
||||
const ABOUT: AboutType = "Run a program with inputs";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "run";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
@ -42,10 +45,7 @@ impl CLI for RunCommand {
|
||||
verifying += start.elapsed();
|
||||
|
||||
println!(" ");
|
||||
println!(
|
||||
" Verifier time : {:?} milliseconds",
|
||||
verifying.as_millis()
|
||||
);
|
||||
println!(" Verifier time : {:?} milliseconds", verifying.as_millis());
|
||||
println!(" Verifier output : {}", is_success);
|
||||
println!(" ");
|
||||
|
||||
|
@ -1,20 +1,19 @@
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::{CLIError, VerificationKeyFileError};
|
||||
use crate::files::{Manifest, ProvingKeyFile, VerificationKeyFile};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::BuildCommand,
|
||||
errors::{CLIError, VerificationKeyFileError},
|
||||
files::{Manifest, ProvingKeyFile, VerificationKeyFile},
|
||||
};
|
||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||
|
||||
use snarkos_algorithms::snark::{
|
||||
generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey,
|
||||
};
|
||||
use snarkos_algorithms::snark::{generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey};
|
||||
use snarkos_curves::{bls12_377::Bls12_377, edwards_bls12::Fq};
|
||||
use snarkos_utilities::bytes::ToBytes;
|
||||
|
||||
use clap::ArgMatches;
|
||||
use rand::thread_rng;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::time::Instant;
|
||||
use std::{convert::TryFrom, env::current_dir, time::Instant};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SetupCommand;
|
||||
@ -27,10 +26,10 @@ impl CLI for SetupCommand {
|
||||
PreparedVerifyingKey<Bls12_377>,
|
||||
);
|
||||
|
||||
const NAME: NameType = "setup";
|
||||
const ABOUT: AboutType = "Run a program setup";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "setup";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
@ -58,15 +57,11 @@ impl CLI for SetupCommand {
|
||||
|
||||
// Run the program setup operation
|
||||
let rng = &mut thread_rng();
|
||||
let parameters =
|
||||
generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap();
|
||||
let parameters = generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap();
|
||||
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶meters.vk);
|
||||
|
||||
// End the timer
|
||||
log::info!(
|
||||
"Setup completed in {:?} milliseconds",
|
||||
start.elapsed().as_millis()
|
||||
);
|
||||
log::info!("Setup completed in {:?} milliseconds", start.elapsed().as_millis());
|
||||
|
||||
// TODO (howardwu): Convert parameters to a 'proving key' struct for serialization.
|
||||
// Write the proving key file to the outputs directory
|
||||
@ -95,10 +90,7 @@ impl CLI for SetupCommand {
|
||||
prepared_verifying_key.write(&mut verification_key)?;
|
||||
|
||||
// Check that the constructed prepared verification key matches the stored verification key
|
||||
let compare: Vec<(u8, u8)> = verification_key
|
||||
.into_iter()
|
||||
.zip(stored_vk.into_iter())
|
||||
.collect();
|
||||
let compare: Vec<(u8, u8)> = verification_key.into_iter().zip(stored_vk.into_iter()).collect();
|
||||
for (a, b) in compare {
|
||||
if a != b {
|
||||
return Err(VerificationKeyFileError::IncorrectVerificationKey.into());
|
||||
|
@ -1,16 +1,17 @@
|
||||
use crate::directories::source::SOURCE_DIRECTORY_NAME;
|
||||
use crate::errors::{CLIError, TestError};
|
||||
use crate::files::{MainFile, Manifest, MAIN_FILE_NAME};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use leo_compiler::compiler::Compiler;
|
||||
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
directories::source::SOURCE_DIRECTORY_NAME,
|
||||
errors::{CLIError, TestError},
|
||||
files::{MainFile, Manifest, MAIN_FILE_NAME},
|
||||
};
|
||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TestCommand;
|
||||
@ -19,10 +20,10 @@ impl CLI for TestCommand {
|
||||
type Options = ();
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "test";
|
||||
const ABOUT: AboutType = "Compile and run all tests in the current package";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "test";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
@ -47,9 +48,7 @@ impl CLI for TestCommand {
|
||||
|
||||
// Verify the main file exists
|
||||
if !MainFile::exists_at(&package_path) {
|
||||
return Err(
|
||||
TestError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into(),
|
||||
);
|
||||
return Err(TestError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
|
||||
}
|
||||
|
||||
// Construct the path to the main file in the source directory
|
||||
@ -58,8 +57,7 @@ impl CLI for TestCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Compute the current program checksum
|
||||
let program =
|
||||
Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
{
|
||||
|
@ -1,11 +1,7 @@
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
use std::env::current_dir;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnloadCommand;
|
||||
@ -14,10 +10,10 @@ impl CLI for UnloadCommand {
|
||||
type Options = ();
|
||||
type Output = ();
|
||||
|
||||
const NAME: NameType = "unload";
|
||||
const ABOUT: AboutType = "Uninstall a package from the current package (*)";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "unload";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::errors::InputsDirectoryError;
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
pub(crate) static INPUTS_DIRECTORY_NAME: &str = "inputs/";
|
||||
|
||||
@ -32,9 +31,9 @@ impl InputsDirectory {
|
||||
let file_path = file_entry.path();
|
||||
|
||||
// Verify that the entry is structured as a valid file
|
||||
let file_type = file_entry.file_type().map_err(|error| {
|
||||
InputsDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error)
|
||||
})?;
|
||||
let file_type = file_entry
|
||||
.file_type()
|
||||
.map_err(|error| InputsDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?;
|
||||
if !file_type.is_file() {
|
||||
return Err(InputsDirectoryError::InvalidFileType(
|
||||
file_path.as_os_str().to_owned(),
|
||||
@ -43,9 +42,9 @@ impl InputsDirectory {
|
||||
}
|
||||
|
||||
// Verify that the file has the default file extension
|
||||
let file_extension = file_path.extension().ok_or_else(|| {
|
||||
InputsDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned())
|
||||
})?;
|
||||
let file_extension = file_path
|
||||
.extension()
|
||||
.ok_or_else(|| InputsDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?;
|
||||
if file_extension != INPUTS_FILE_EXTENSION {
|
||||
return Err(InputsDirectoryError::InvalidFileExtension(
|
||||
file_path.as_os_str().to_owned(),
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::errors::OutputsDirectoryError;
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
pub(crate) static OUTPUTS_DIRECTORY_NAME: &str = "outputs/";
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::errors::SourceDirectoryError;
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
pub(crate) static SOURCE_DIRECTORY_NAME: &str = "src/";
|
||||
|
||||
@ -32,9 +31,9 @@ impl SourceDirectory {
|
||||
let file_path = file_entry.path();
|
||||
|
||||
// Verify that the entry is structured as a valid file
|
||||
let file_type = file_entry.file_type().map_err(|error| {
|
||||
SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error)
|
||||
})?;
|
||||
let file_type = file_entry
|
||||
.file_type()
|
||||
.map_err(|error| SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?;
|
||||
if !file_type.is_file() {
|
||||
return Err(SourceDirectoryError::InvalidFileType(
|
||||
file_path.as_os_str().to_owned(),
|
||||
@ -43,9 +42,9 @@ impl SourceDirectory {
|
||||
}
|
||||
|
||||
// Verify that the file has the default file extension
|
||||
let file_extension = file_path.extension().ok_or_else(|| {
|
||||
SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned())
|
||||
})?;
|
||||
let file_extension = file_path
|
||||
.extension()
|
||||
.ok_or_else(|| SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?;
|
||||
if file_extension != SOURCE_FILE_EXTENSION {
|
||||
return Err(SourceDirectoryError::InvalidFileExtension(
|
||||
file_path.as_os_str().to_owned(),
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::errors::ManifestError;
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
use std::{ffi::OsString, io};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum InitError {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::errors::ManifestError;
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
use std::{ffi::OsString, io};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum NewError {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ChecksumFileError {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ProofFileError {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ProvingKeyFileError {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum VerificationKeyFileError {
|
||||
|
@ -1,12 +1,13 @@
|
||||
//! The build checksum file.
|
||||
|
||||
use crate::directories::outputs::OUTPUTS_DIRECTORY_NAME;
|
||||
use crate::errors::ChecksumFileError;
|
||||
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::ChecksumFileError};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
pub static CHECKSUM_FILE_EXTENSION: &str = ".leo.checksum";
|
||||
|
||||
@ -31,10 +32,7 @@ impl ChecksumFile {
|
||||
pub fn read_from(&self, path: &PathBuf) -> Result<String, ChecksumFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
Ok(
|
||||
fs::read_to_string(&path)
|
||||
.map_err(|_| ChecksumFileError::FileReadError(path.clone()))?,
|
||||
)
|
||||
Ok(fs::read_to_string(&path).map_err(|_| ChecksumFileError::FileReadError(path.clone()))?)
|
||||
}
|
||||
|
||||
/// Writes the given checksum to a file.
|
||||
|
@ -3,9 +3,7 @@
|
||||
use crate::errors::GitignoreError;
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::{fs::File, io::Write, path::PathBuf};
|
||||
|
||||
pub static GITIGNORE_FILE_NAME: &str = ".gitignore";
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
//! The `main.leo` file.
|
||||
|
||||
use crate::directories::source::SOURCE_DIRECTORY_NAME;
|
||||
use crate::errors::MainFileError;
|
||||
use crate::{directories::source::SOURCE_DIRECTORY_NAME, errors::MainFileError};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::{fs::File, io::Write, path::PathBuf};
|
||||
|
||||
pub static MAIN_FILE_NAME: &str = "main.leo";
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
use crate::errors::ManifestError;
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
pub static MANIFEST_FILE_NAME: &str = "Leo.toml";
|
||||
|
||||
@ -48,8 +49,7 @@ impl Manifest {
|
||||
path.push(PathBuf::from(MANIFEST_FILE_NAME));
|
||||
}
|
||||
|
||||
let mut file = File::create(&path)
|
||||
.map_err(|error| ManifestError::Creating(MANIFEST_FILE_NAME, error))?;
|
||||
let mut file = File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILE_NAME, error))?;
|
||||
file.write_all(self.template().as_bytes())
|
||||
.map_err(|error| ManifestError::Writing(MANIFEST_FILE_NAME, error))
|
||||
}
|
||||
@ -74,8 +74,7 @@ impl TryFrom<&PathBuf> for Manifest {
|
||||
path.push(PathBuf::from(MANIFEST_FILE_NAME));
|
||||
}
|
||||
|
||||
let mut file =
|
||||
File::open(path).map_err(|error| ManifestError::Opening(MANIFEST_FILE_NAME, error))?;
|
||||
let mut file = File::open(path).map_err(|error| ManifestError::Opening(MANIFEST_FILE_NAME, error))?;
|
||||
let size = file
|
||||
.metadata()
|
||||
.map_err(|error| ManifestError::Metadata(MANIFEST_FILE_NAME, error))?
|
||||
@ -85,7 +84,6 @@ impl TryFrom<&PathBuf> for Manifest {
|
||||
file.read_to_string(&mut buffer)
|
||||
.map_err(|error| ManifestError::Reading(MANIFEST_FILE_NAME, error))?;
|
||||
|
||||
Ok(toml::from_str(&buffer)
|
||||
.map_err(|error| ManifestError::Parsing(MANIFEST_FILE_NAME, error))?)
|
||||
Ok(toml::from_str(&buffer).map_err(|error| ManifestError::Parsing(MANIFEST_FILE_NAME, error))?)
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
//! The proof file.
|
||||
|
||||
use crate::directories::outputs::OUTPUTS_DIRECTORY_NAME;
|
||||
use crate::errors::ProofFileError;
|
||||
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::ProofFileError};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
pub static PROOF_FILE_EXTENSION: &str = ".leo.proof";
|
||||
|
||||
@ -31,8 +32,7 @@ impl ProofFile {
|
||||
pub fn read_from(&self, path: &PathBuf) -> Result<String, ProofFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
let proof =
|
||||
fs::read_to_string(&path).map_err(|_| ProofFileError::FileReadError(path.clone()))?;
|
||||
let proof = fs::read_to_string(&path).map_err(|_| ProofFileError::FileReadError(path.clone()))?;
|
||||
Ok(proof)
|
||||
}
|
||||
|
||||
@ -54,10 +54,7 @@ impl ProofFile {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!(
|
||||
"{}{}",
|
||||
self.package_name, PROOF_FILE_EXTENSION
|
||||
)));
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, PROOF_FILE_EXTENSION)));
|
||||
}
|
||||
path
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
//! The proving key file.
|
||||
|
||||
use crate::directories::outputs::OUTPUTS_DIRECTORY_NAME;
|
||||
use crate::errors::ProvingKeyFileError;
|
||||
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::ProvingKeyFileError};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
pub static PROVING_KEY_FILE_EXTENSION: &str = ".leo.pk";
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user