merge dev
This commit is contained in:
commit
39e28615e3
269 changed files with 5685 additions and 621 deletions
|
@ -11,6 +11,7 @@ sudo: required
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- CRATE_NAME=zokrates
|
- CRATE_NAME=zokrates
|
||||||
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
@ -67,7 +68,7 @@ branches:
|
||||||
only:
|
only:
|
||||||
# release tags
|
# release tags
|
||||||
- /^\d+\.\d+\.\d+.*$/
|
- /^\d+\.\d+\.\d+.*$/
|
||||||
- master
|
- deploy
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
|
|
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
https://github.com/Zokrates/ZoKrates/compare/latest...develop
|
https://github.com/Zokrates/ZoKrates/compare/latest...develop
|
||||||
|
|
||||||
|
## [0.7.0] - 2021-04-09
|
||||||
|
|
||||||
|
### Release
|
||||||
|
- https://github.com/Zokrates/ZoKrates/releases/tag/0.7.0
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Re-export embed functions as stdlib modules, add field to uint casts to stdlib (#801, @dark64)
|
||||||
|
- Change left `<<` and right `>>` shifts to take `u32` as a second parameter (#783, @schaeff)
|
||||||
|
- Introduce u64 type, add keccak{256,384,512} and sha3{256,384,512} hash functions to stdlib (#772, @dark64)
|
||||||
|
- Add negative `-` and positive `+` unary operators, restricting accepted expressions in some places (exponent) to allow for better parsing (#762, @schaeff)
|
||||||
|
- Make embed functions generic, enabling unpacking to any width at minimal cost (#754, @schaeff)
|
||||||
|
- Add global `--verbose` flag to CLI for verbose logging, add `--ztf` flag to `compile` command, deprecate `--light` flag as its behaviour is now a default. (#751, @dark64)
|
||||||
|
- Introduce constant generics for `u32` values. Introduce literal inference (#695, @schaeff)
|
||||||
|
|
||||||
## [0.6.4] - 2021-03-19
|
## [0.6.4] - 2021-03-19
|
||||||
### Release
|
### Release
|
||||||
- https://github.com/Zokrates/ZoKrates/releases/tag/0.6.4
|
- https://github.com/Zokrates/ZoKrates/releases/tag/0.6.4
|
||||||
|
|
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -2258,7 +2258,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_abi"
|
name = "zokrates_abi"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
@ -2269,7 +2269,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_cli"
|
name = "zokrates_cli"
|
||||||
version = "0.6.4"
|
version = "0.7.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_cli",
|
"assert_cli",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -2294,7 +2294,7 @@ version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_core"
|
name = "zokrates_core"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ark-bls12-377",
|
"ark-bls12-377",
|
||||||
"ark-bn254",
|
"ark-bn254",
|
||||||
|
@ -2335,7 +2335,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_core_test"
|
name = "zokrates_core_test"
|
||||||
version = "0.1.5"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zokrates_test",
|
"zokrates_test",
|
||||||
"zokrates_test_derive",
|
"zokrates_test_derive",
|
||||||
|
@ -2343,7 +2343,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_embed"
|
name = "zokrates_embed"
|
||||||
version = "0.1.1"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bellman_ce",
|
"bellman_ce",
|
||||||
"sapling-crypto_ce",
|
"sapling-crypto_ce",
|
||||||
|
@ -2351,7 +2351,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_field"
|
name = "zokrates_field"
|
||||||
version = "0.3.8"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ark-bls12-377",
|
"ark-bls12-377",
|
||||||
"ark-bn254",
|
"ark-bn254",
|
||||||
|
@ -2381,7 +2381,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_parser"
|
name = "zokrates_parser"
|
||||||
version = "0.1.6"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob 0.2.11",
|
"glob 0.2.11",
|
||||||
"pest",
|
"pest",
|
||||||
|
@ -2390,7 +2390,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_pest_ast"
|
name = "zokrates_pest_ast"
|
||||||
version = "0.1.5"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"from-pest",
|
"from-pest",
|
||||||
"glob 0.2.11",
|
"glob 0.2.11",
|
||||||
|
@ -2402,7 +2402,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zokrates_stdlib"
|
name = "zokrates_stdlib"
|
||||||
version = "0.1.8"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fs_extra",
|
"fs_extra",
|
||||||
"zokrates_test",
|
"zokrates_test",
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
def id<N>() -> u32:
|
|
||||||
return N
|
|
||||||
|
|
||||||
def main():
|
|
||||||
assert(id::<5>() == 5)
|
|
||||||
assert(id::<6>() == 6)
|
|
||||||
return
|
|
6
build.sh
6
build.sh
|
@ -3,4 +3,8 @@
|
||||||
# Exit if any subcommand fails
|
# Exit if any subcommand fails
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
cargo build
|
if [ -n "$WITH_LIBSNARK" ]; then
|
||||||
|
cargo -Z package-features build --package zokrates_cli --features="libsnark"
|
||||||
|
else
|
||||||
|
cargo build
|
||||||
|
fi
|
|
@ -1 +0,0 @@
|
||||||
Introduce constant generics for `u32` values. Introduce literal inference
|
|
|
@ -1 +0,0 @@
|
||||||
Add global `--verbose` flag to CLI for verbose logging, add `--ztf` flag to `compile` command, deprecate `--light` flag as its behaviour is now a default.
|
|
|
@ -1 +0,0 @@
|
||||||
Make embed functions generic, enabling unpacking to any width at minimal cost
|
|
|
@ -1 +0,0 @@
|
||||||
Change left `<<` and right `>>` shifts to take `u32` as a second parameter
|
|
1
changelogs/unreleased/800-dark64
Normal file
1
changelogs/unreleased/800-dark64
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Allow optional underscore before type suffix (e.g. `42_u32`)
|
1
changelogs/unreleased/806-dark64
Normal file
1
changelogs/unreleased/806-dark64
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add [poseidon](https://www.poseidon-hash.info/) zk-friendly hashing algorithm to stdlib
|
1
changelogs/unreleased/809-dark64
Normal file
1
changelogs/unreleased/809-dark64
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add the ability to import multiple symbols in a single import statement
|
|
@ -28,7 +28,14 @@ main() {
|
||||||
|
|
||||||
test -f Cargo.lock || cargo generate-lockfile
|
test -f Cargo.lock || cargo generate-lockfile
|
||||||
|
|
||||||
cross build --bin zokrates --target $TARGET --release
|
case $TRAVIS_OS_NAME in
|
||||||
|
linux)
|
||||||
|
cross build --bin zokrates --package zokrates_cli --features="libsnark" --target $TARGET --release
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cross build --bin zokrates --package zokrates_cli --target $TARGET --release
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# Package artifacts
|
# Package artifacts
|
||||||
# Binary
|
# Binary
|
||||||
|
|
11
example.zok
11
example.zok
|
@ -1,11 +0,0 @@
|
||||||
def foo<N>(field[N] x) -> field[N]:
|
|
||||||
return x
|
|
||||||
|
|
||||||
def bar<N>(field[N] x) -> field[N]:
|
|
||||||
field[N] r = x
|
|
||||||
return r
|
|
||||||
|
|
||||||
def main(field[3] x) -> field[2]:
|
|
||||||
field[2] z = foo(x)[0..2]
|
|
||||||
|
|
||||||
return bar(z)
|
|
|
@ -3,4 +3,8 @@
|
||||||
# Exit if any subcommand fails
|
# Exit if any subcommand fails
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
cargo test --release -- --ignored --test-threads=1
|
if [ -n "$WITH_LIBSNARK" ]; then
|
||||||
|
cargo -Z package-features test --release --package zokrates_cli --features="libsnark" -- --ignored --test-threads=1
|
||||||
|
else
|
||||||
|
cargo test --release -- --ignored --test-threads=1
|
||||||
|
fi
|
6
test.sh
6
test.sh
|
@ -3,4 +3,8 @@
|
||||||
# Exit if any subcommand fails
|
# Exit if any subcommand fails
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
cargo test --release -- --test-threads=1
|
if [ -n "$WITH_LIBSNARK" ]; then
|
||||||
|
cargo -Z package-features test --release --package zokrates_cli --features="libsnark" -- --test-threads=1
|
||||||
|
else
|
||||||
|
cargo test --release -- --test-threads=1
|
||||||
|
fi
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
[package]
|
[package]
|
||||||
name = "zokrates_abi"
|
name = "zokrates_abi"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
authors = ["Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
authors = ["Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
zokrates_field = { version = "0.3", path = "../zokrates_field", default-features = false }
|
zokrates_field = { version = "0.4", path = "../zokrates_field", default-features = false }
|
||||||
zokrates_core = { version = "0.5", path = "../zokrates_core", default-features = false }
|
zokrates_core = { version = "0.6", path = "../zokrates_core", default-features = false }
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
|
@ -45,6 +45,7 @@ enum Value<T> {
|
||||||
U8(u8),
|
U8(u8),
|
||||||
U16(u16),
|
U16(u16),
|
||||||
U32(u32),
|
U32(u32),
|
||||||
|
U64(u64),
|
||||||
Field(T),
|
Field(T),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Array(Vec<Value<T>>),
|
Array(Vec<Value<T>>),
|
||||||
|
@ -56,6 +57,7 @@ enum CheckedValue<T> {
|
||||||
U8(u8),
|
U8(u8),
|
||||||
U16(u16),
|
U16(u16),
|
||||||
U32(u32),
|
U32(u32),
|
||||||
|
U64(u64),
|
||||||
Field(T),
|
Field(T),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Array(Vec<CheckedValue<T>>),
|
Array(Vec<CheckedValue<T>>),
|
||||||
|
@ -72,6 +74,7 @@ impl<T: Field> fmt::Display for Value<T> {
|
||||||
Value::U8(v) => write!(f, "{:#04x}", v),
|
Value::U8(v) => write!(f, "{:#04x}", v),
|
||||||
Value::U16(v) => write!(f, "{:#06x}", v),
|
Value::U16(v) => write!(f, "{:#06x}", v),
|
||||||
Value::U32(v) => write!(f, "{:#010x}", v),
|
Value::U32(v) => write!(f, "{:#010x}", v),
|
||||||
|
Value::U64(v) => write!(f, "{:#018x}", v),
|
||||||
Value::Boolean(v) => write!(f, "{}", v),
|
Value::Boolean(v) => write!(f, "{}", v),
|
||||||
Value::Array(v) => write!(
|
Value::Array(v) => write!(
|
||||||
f,
|
f,
|
||||||
|
@ -100,6 +103,7 @@ impl<T: Field> Value<T> {
|
||||||
(Value::U8(f), ConcreteType::Uint(UBitwidth::B8)) => Ok(CheckedValue::U8(f)),
|
(Value::U8(f), ConcreteType::Uint(UBitwidth::B8)) => Ok(CheckedValue::U8(f)),
|
||||||
(Value::U16(f), ConcreteType::Uint(UBitwidth::B16)) => Ok(CheckedValue::U16(f)),
|
(Value::U16(f), ConcreteType::Uint(UBitwidth::B16)) => Ok(CheckedValue::U16(f)),
|
||||||
(Value::U32(f), ConcreteType::Uint(UBitwidth::B32)) => Ok(CheckedValue::U32(f)),
|
(Value::U32(f), ConcreteType::Uint(UBitwidth::B32)) => Ok(CheckedValue::U32(f)),
|
||||||
|
(Value::U64(f), ConcreteType::Uint(UBitwidth::B64)) => Ok(CheckedValue::U64(f)),
|
||||||
(Value::Boolean(b), ConcreteType::Boolean) => Ok(CheckedValue::Boolean(b)),
|
(Value::Boolean(b), ConcreteType::Boolean) => Ok(CheckedValue::Boolean(b)),
|
||||||
(Value::Array(a), ConcreteType::Array(array_type)) => {
|
(Value::Array(a), ConcreteType::Array(array_type)) => {
|
||||||
let size = array_type.size;
|
let size = array_type.size;
|
||||||
|
@ -162,6 +166,7 @@ impl<T: From<usize>> Encode<T> for CheckedValue<T> {
|
||||||
CheckedValue::U8(t) => vec![T::from(t as usize)],
|
CheckedValue::U8(t) => vec![T::from(t as usize)],
|
||||||
CheckedValue::U16(t) => vec![T::from(t as usize)],
|
CheckedValue::U16(t) => vec![T::from(t as usize)],
|
||||||
CheckedValue::U32(t) => vec![T::from(t as usize)],
|
CheckedValue::U32(t) => vec![T::from(t as usize)],
|
||||||
|
CheckedValue::U64(t) => vec![T::from(t as usize)],
|
||||||
CheckedValue::Boolean(b) => vec![if b { 1.into() } else { 0.into() }],
|
CheckedValue::Boolean(b) => vec![if b { 1.into() } else { 0.into() }],
|
||||||
CheckedValue::Array(a) => a.into_iter().flat_map(|v| v.encode()).collect(),
|
CheckedValue::Array(a) => a.into_iter().flat_map(|v| v.encode()).collect(),
|
||||||
CheckedValue::Struct(s) => s.into_iter().flat_map(|(_, v)| v.encode()).collect(),
|
CheckedValue::Struct(s) => s.into_iter().flat_map(|(_, v)| v.encode()).collect(),
|
||||||
|
@ -205,6 +210,9 @@ impl<T: Field> Decode<T> for CheckedValue<T> {
|
||||||
ConcreteType::Uint(UBitwidth::B32) => {
|
ConcreteType::Uint(UBitwidth::B32) => {
|
||||||
CheckedValue::U32(raw.pop().unwrap().to_dec_string().parse().unwrap())
|
CheckedValue::U32(raw.pop().unwrap().to_dec_string().parse().unwrap())
|
||||||
}
|
}
|
||||||
|
ConcreteType::Uint(UBitwidth::B64) => {
|
||||||
|
CheckedValue::U64(raw.pop().unwrap().to_dec_string().parse().unwrap())
|
||||||
|
}
|
||||||
ConcreteType::Boolean => {
|
ConcreteType::Boolean => {
|
||||||
let v = raw.pop().unwrap();
|
let v = raw.pop().unwrap();
|
||||||
CheckedValue::Boolean(if v == 0.into() {
|
CheckedValue::Boolean(if v == 0.into() {
|
||||||
|
@ -276,6 +284,9 @@ impl<T: Field> TryFrom<serde_json::Value> for Value<T> {
|
||||||
10 => u32::from_str_radix(&s[2..], 16)
|
10 => u32::from_str_radix(&s[2..], 16)
|
||||||
.map(Value::U32)
|
.map(Value::U32)
|
||||||
.map_err(|_| format!("Expected u32 value, found {}", s)),
|
.map_err(|_| format!("Expected u32 value, found {}", s)),
|
||||||
|
18 => u64::from_str_radix(&s[2..], 16)
|
||||||
|
.map(Value::U64)
|
||||||
|
.map_err(|_| format!("Expected u64 value, found {}", s)),
|
||||||
_ => Err(format!("Cannot parse {} to any type", s)),
|
_ => Err(format!("Cannot parse {} to any type", s)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -306,6 +317,7 @@ impl<T: Field> CheckedValue<T> {
|
||||||
CheckedValue::U8(u) => serde_json::Value::String(format!("{:#04x}", u)),
|
CheckedValue::U8(u) => serde_json::Value::String(format!("{:#04x}", u)),
|
||||||
CheckedValue::U16(u) => serde_json::Value::String(format!("{:#06x}", u)),
|
CheckedValue::U16(u) => serde_json::Value::String(format!("{:#06x}", u)),
|
||||||
CheckedValue::U32(u) => serde_json::Value::String(format!("{:#010x}", u)),
|
CheckedValue::U32(u) => serde_json::Value::String(format!("{:#010x}", u)),
|
||||||
|
CheckedValue::U64(u) => serde_json::Value::String(format!("{:#018x}", u)),
|
||||||
CheckedValue::Boolean(b) => serde_json::Value::Bool(b),
|
CheckedValue::Boolean(b) => serde_json::Value::Bool(b),
|
||||||
CheckedValue::Array(a) => {
|
CheckedValue::Array(a) => {
|
||||||
serde_json::Value::Array(a.into_iter().map(|e| e.into_serde_json()).collect())
|
serde_json::Value::Array(a.into_iter().map(|e| e.into_serde_json()).collect())
|
||||||
|
|
|
@ -13,6 +13,12 @@ from "./path/to/my/module" import MySymbol
|
||||||
// `MySymbol` is now in scope.
|
// `MySymbol` is now in scope.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To import multiple symbols with a single import statement, separate the symbols names with commas:
|
||||||
|
|
||||||
|
```zokrates
|
||||||
|
from "./path/to/my/module" import MySymbol, MyOtherSymbol
|
||||||
|
```
|
||||||
|
|
||||||
#### Aliasing
|
#### Aliasing
|
||||||
|
|
||||||
The `as` keyword enables renaming symbols:
|
The `as` keyword enables renaming symbols:
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
## Operators
|
## Operators
|
||||||
|
|
||||||
The following table lists the precedence and associativity of all available operators. Operators are listed top to bottom, in ascending precedence.
|
The following table lists the precedence and associativity of all operators. Operators are listed top to bottom, in ascending precedence. Operators in the same box group left to right. Operators are binary, unless the syntax is provided.
|
||||||
|
|
||||||
| Operator | Description | Associativity | Remarks |
|
|
||||||
|------------------------------|--------------------------------------------------------------|------------------------------------|---------|
|
|
||||||
| ** <br> | Power | Left | [^1] |
|
|
||||||
| *<br> /<br> %<br> | Multiplication <br> Division <br> Remainder | Left <br> Left <br>Left | |
|
|
||||||
| + <br> - <br> | Addition <br> Subtraction <br> | Left <br> Left | |
|
|
||||||
| << <br> >> <br> | Left shift <br> Right shift <br> | Left <br> Left | [^2] |
|
|
||||||
| & | Bitwise AND | Left <br> Left | |
|
|
||||||
| \| | Bitwise OR | Left <br> Left | |
|
|
||||||
| ^ | Bitwise XOR | Left <br> Left | |
|
|
||||||
| >= <br><br> > <br> <= <br> < | Greater or equal <br> Greater <br> Lower or equal <br> Lower | Left <br> Left <br> Left <br> Left | [^3] |
|
|
||||||
| != <br> == <br> | Not Equal <br> Equal <br> | Left <br> Left | |
|
|
||||||
| && | Boolean AND | Left | |
|
|
||||||
| \|\| | Boolean OR | Left | |
|
|
||||||
|
|
||||||
|
|
||||||
|
| Operator | Description | Remarks |
|
||||||
|
|---------------------------------|-------------------------------------------------------------------|---------|
|
||||||
|
| `**` <br> | Power | [^1] |
|
||||||
|
| `+x` <br> `-x` <br> `!x` <br> | Positive <br> Negative <br> Negation <br> | |
|
||||||
|
| `*` <br> `/` <br> `%` <br> | Multiplication <br> Division <br> Remainder <br> | |
|
||||||
|
| `+` <br> `-` <br> | Addition <br> Subtraction <br> | |
|
||||||
|
| `<<` <br> `>>` <br> | Left shift <br> Right shift <br> | [^2] |
|
||||||
|
| `&` | Bitwise AND | |
|
||||||
|
| <code>|</code> | Bitwise OR | |
|
||||||
|
| `^` | Bitwise XOR | |
|
||||||
|
| `>=` <br> `>` <br> `<=` <br> `<`| Greater or equal <br> Greater <br> Lower or equal <br> Lower <br> | [^3] |
|
||||||
|
| `!=` <br> `==` <br> | Not Equal <br> Equal <br> | |
|
||||||
|
| `&&` | Boolean AND | |
|
||||||
|
| <code>||</code> | Boolean OR | |
|
||||||
|
| `if c then x else y fi` | Conditional expression | |
|
||||||
|
|
||||||
[^1]: The exponent must be a compile-time constant of type `u32`
|
[^1]: The exponent must be a compile-time constant of type `u32`
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ Note that for field elements, the division operation multiplies the numerator wi
|
||||||
|
|
||||||
Booleans are available in ZoKrates. When a boolean is used as a parameter of the main function, the program is constrained to only accept `0` or `1` for that parameter. A boolean can be asserted to be true using an `assert(bool)` statement.
|
Booleans are available in ZoKrates. When a boolean is used as a parameter of the main function, the program is constrained to only accept `0` or `1` for that parameter. A boolean can be asserted to be true using an `assert(bool)` statement.
|
||||||
|
|
||||||
### `u8/u16/u32`
|
### `u8/u16/u32/u64`
|
||||||
|
|
||||||
Unsigned integers represent positive numbers of the interval `[0, 2 ** bitwidth[`, where `bitwidth` is specified in the type's name, e.g., 32 bits in the case of u32. Their arithmetics are defined modulo `2 ** bitwidth`.
|
Unsigned integers represent positive numbers of the interval `[0, 2 ** bitwidth[`, where `bitwidth` is specified in the type's name, e.g., 32 bits in the case of u32. Their arithmetics are defined modulo `2 ** bitwidth`.
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ The division operation calculates the standard floor division for integers. The
|
||||||
|
|
||||||
### Numeric inference
|
### Numeric inference
|
||||||
|
|
||||||
In the case of decimal literals like `42`, the compiler tries to find the appropriate type (`field`, `u8`, `u16` or `u32`) depending on the context. If it cannot converge to a single option, an error is returned. This means that there is no default type for decimal literals.
|
In the case of decimal literals like `42`, the compiler tries to find the appropriate type (`field`, `u8`, `u16`, `u32` or `u64`) depending on the context. If it cannot converge to a single option, an error is returned. This means that there is no default type for decimal literals.
|
||||||
|
|
||||||
All operations between literals have the semantics of the infered type.
|
All operations between literals have the semantics of the inferred type.
|
||||||
|
|
||||||
```zokrates
|
```zokrates
|
||||||
{{#include ../../../zokrates_cli/examples/book/numeric_inference.zok}}
|
{{#include ../../../zokrates_cli/examples/book/numeric_inference.zok}}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "zokrates_cli"
|
name = "zokrates_cli"
|
||||||
version = "0.6.4"
|
version = "0.7.0"
|
||||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>", "Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>", "Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||||
repository = "https://github.com/JacobEberhardt/ZoKrates.git"
|
repository = "https://github.com/JacobEberhardt/ZoKrates.git"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
@ -16,9 +16,9 @@ cfg-if = "0.1"
|
||||||
clap = "2.26.2"
|
clap = "2.26.2"
|
||||||
bincode = "0.8.0"
|
bincode = "0.8.0"
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
zokrates_field = { version = "0.3", path = "../zokrates_field", default-features = false }
|
zokrates_field = { version = "0.4", path = "../zokrates_field", default-features = false }
|
||||||
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
|
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
|
||||||
zokrates_core = { version = "0.5", path = "../zokrates_core", default-features = false }
|
zokrates_core = { version = "0.6", path = "../zokrates_core", default-features = false }
|
||||||
zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"}
|
zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"}
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
dirs = "3.0.1"
|
dirs = "3.0.1"
|
||||||
|
|
3
zokrates_cli/examples/compile_errors/double_negation.zok
Normal file
3
zokrates_cli/examples/compile_errors/double_negation.zok
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
def main():
|
||||||
|
field a = - - 1
|
||||||
|
return
|
3
zokrates_cli/examples/compile_errors/double_power.zok
Normal file
3
zokrates_cli/examples/compile_errors/double_power.zok
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
def main():
|
||||||
|
field a = 1**2**3 // parentheses are required here
|
||||||
|
return
|
4
zokrates_cli/examples/decimal_literal.zok
Normal file
4
zokrates_cli/examples/decimal_literal.zok
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
def main() -> field:
|
||||||
|
field a = 1f
|
||||||
|
field b = 1_f // allow underscore between the literal and the suffix
|
||||||
|
return a + b
|
5
zokrates_cli/examples/imports/import_multiple.zok
Normal file
5
zokrates_cli/examples/imports/import_multiple.zok
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from "./bar" import Bar, main as f
|
||||||
|
|
||||||
|
def main() -> field:
|
||||||
|
Bar bar = Bar {}
|
||||||
|
return f()
|
|
@ -5,4 +5,4 @@ import "./foo" as f
|
||||||
def main() -> field:
|
def main() -> field:
|
||||||
field foo = f()
|
field foo = f()
|
||||||
assert(foo == bar() + baz())
|
assert(foo == bar() + baz())
|
||||||
return foo
|
return foo
|
|
@ -1 +0,0 @@
|
||||||
[]
|
|
|
@ -1,2 +0,0 @@
|
||||||
def main():
|
|
||||||
return
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "zokrates_core"
|
name = "zokrates_core"
|
||||||
version = "0.5.4"
|
version = "0.6.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>"]
|
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>"]
|
||||||
repository = "https://github.com/JacobEberhardt/ZoKrates"
|
repository = "https://github.com/JacobEberhardt/ZoKrates"
|
||||||
|
@ -28,10 +28,10 @@ serde_json = "1.0"
|
||||||
bincode = "0.8.0"
|
bincode = "0.8.0"
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
zokrates_field = { version = "0.3.0", path = "../zokrates_field", default-features = false }
|
zokrates_field = { version = "0.4.0", path = "../zokrates_field", default-features = false }
|
||||||
zokrates_pest_ast = { version = "0.1.0", path = "../zokrates_pest_ast" }
|
zokrates_pest_ast = { version = "0.2.0", path = "../zokrates_pest_ast" }
|
||||||
zokrates_common = { path = "../zokrates_common" }
|
zokrates_common = { path = "../zokrates_common" }
|
||||||
zokrates_embed = { path = "../zokrates_embed" }
|
zokrates_embed = { version = "0.1.0", path = "../zokrates_embed" }
|
||||||
getrandom = { version = "0.2", features = ["js"] }
|
getrandom = { version = "0.2", features = ["js"] }
|
||||||
rand_0_4 = { version = "0.4", package = "rand" }
|
rand_0_4 = { version = "0.4", package = "rand" }
|
||||||
rand_0_7 = { version = "0.7", package = "rand" }
|
rand_0_7 = { version = "0.7", package = "rand" }
|
||||||
|
|
|
@ -22,30 +22,45 @@ impl<'ast> From<pest::File<'ast>> for absy::Module<'ast> {
|
||||||
.map(absy::SymbolDeclarationNode::from),
|
.map(absy::SymbolDeclarationNode::from),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.imports(prog.imports.into_iter().map(absy::ImportNode::from))
|
.imports(
|
||||||
|
prog.imports
|
||||||
|
.into_iter()
|
||||||
|
.map(absy::ImportDirective::from)
|
||||||
|
.flatten(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> From<pest::ImportDirective<'ast>> for absy::ImportNode<'ast> {
|
impl<'ast> From<pest::ImportDirective<'ast>> for absy::ImportDirective<'ast> {
|
||||||
fn from(import: pest::ImportDirective<'ast>) -> absy::ImportNode<'ast> {
|
fn from(import: pest::ImportDirective<'ast>) -> absy::ImportDirective<'ast> {
|
||||||
use crate::absy::NodeValue;
|
use crate::absy::NodeValue;
|
||||||
|
|
||||||
match import {
|
match import {
|
||||||
pest::ImportDirective::Main(import) => {
|
pest::ImportDirective::Main(import) => absy::ImportDirective::Main(
|
||||||
imports::Import::new(None, std::path::Path::new(import.source.span.as_str()))
|
imports::Import::new(None, std::path::Path::new(import.source.span.as_str()))
|
||||||
.alias(import.alias.map(|a| a.span.as_str()))
|
.alias(import.alias.map(|a| a.span.as_str()))
|
||||||
.span(import.span)
|
.span(import.span),
|
||||||
}
|
),
|
||||||
pest::ImportDirective::From(import) => {
|
pest::ImportDirective::From(import) => absy::ImportDirective::From(
|
||||||
let symbol_str = import.symbol.span.as_str();
|
import
|
||||||
|
.symbols
|
||||||
imports::Import::new(
|
.iter()
|
||||||
Some(import.symbol.span.as_str()),
|
.map(|symbol| {
|
||||||
std::path::Path::new(import.source.span.as_str()),
|
imports::Import::new(
|
||||||
)
|
Some(symbol.symbol.span.as_str()),
|
||||||
.alias(import.alias.map(|a| a.span.as_str()).or(Some(symbol_str)))
|
std::path::Path::new(import.source.span.as_str()),
|
||||||
.span(import.span)
|
)
|
||||||
}
|
.alias(
|
||||||
|
symbol
|
||||||
|
.alias
|
||||||
|
.as_ref()
|
||||||
|
.map(|a| a.span.as_str())
|
||||||
|
.or_else(|| Some(symbol.symbol.span.as_str())),
|
||||||
|
)
|
||||||
|
.span(symbol.span.clone())
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -541,10 +556,12 @@ impl<'ast> From<pest::UnaryExpression<'ast>> for absy::ExpressionNode<'ast> {
|
||||||
fn from(unary: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<'ast> {
|
fn from(unary: pest::UnaryExpression<'ast>) -> absy::ExpressionNode<'ast> {
|
||||||
use crate::absy::NodeValue;
|
use crate::absy::NodeValue;
|
||||||
|
|
||||||
|
let expression = Box::new(absy::ExpressionNode::from(*unary.expression));
|
||||||
|
|
||||||
match unary.op {
|
match unary.op {
|
||||||
pest::UnaryOperator::Not(_) => {
|
pest::UnaryOperator::Not(..) => absy::Expression::Not(expression),
|
||||||
absy::Expression::Not(Box::new(absy::ExpressionNode::from(*unary.expression)))
|
pest::UnaryOperator::Neg(..) => absy::Expression::Neg(expression),
|
||||||
}
|
pest::UnaryOperator::Pos(..) => absy::Expression::Pos(expression),
|
||||||
}
|
}
|
||||||
.span(unary.span)
|
.span(unary.span)
|
||||||
}
|
}
|
||||||
|
@ -609,6 +626,9 @@ impl<'ast> From<pest::DecimalLiteralExpression<'ast>> for absy::ExpressionNode<'
|
||||||
pest::DecimalSuffix::Field(_) => absy::Expression::FieldConstant(
|
pest::DecimalSuffix::Field(_) => absy::Expression::FieldConstant(
|
||||||
BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
BigUint::parse_bytes(&expression.value.span.as_str().as_bytes(), 10).unwrap(),
|
||||||
),
|
),
|
||||||
|
pest::DecimalSuffix::U64(_) => {
|
||||||
|
absy::Expression::U64Constant(expression.value.span.as_str().parse().unwrap())
|
||||||
|
}
|
||||||
pest::DecimalSuffix::U32(_) => {
|
pest::DecimalSuffix::U32(_) => {
|
||||||
absy::Expression::U32Constant(expression.value.span.as_str().parse().unwrap())
|
absy::Expression::U32Constant(expression.value.span.as_str().parse().unwrap())
|
||||||
}
|
}
|
||||||
|
@ -633,6 +653,9 @@ impl<'ast> From<pest::HexLiteralExpression<'ast>> for absy::ExpressionNode<'ast>
|
||||||
use crate::absy::NodeValue;
|
use crate::absy::NodeValue;
|
||||||
|
|
||||||
match expression.value {
|
match expression.value {
|
||||||
|
pest::HexNumberExpression::U64(e) => {
|
||||||
|
absy::Expression::U64Constant(u64::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||||
|
}
|
||||||
pest::HexNumberExpression::U32(e) => {
|
pest::HexNumberExpression::U32(e) => {
|
||||||
absy::Expression::U32Constant(u32::from_str_radix(&e.span.as_str(), 16).unwrap())
|
absy::Expression::U32Constant(u32::from_str_radix(&e.span.as_str(), 16).unwrap())
|
||||||
}
|
}
|
||||||
|
@ -709,6 +732,7 @@ impl<'ast> From<pest::Type<'ast>> for absy::UnresolvedTypeNode<'ast> {
|
||||||
pest::BasicType::U8(t) => UnresolvedType::Uint(8).span(t.span),
|
pest::BasicType::U8(t) => UnresolvedType::Uint(8).span(t.span),
|
||||||
pest::BasicType::U16(t) => UnresolvedType::Uint(16).span(t.span),
|
pest::BasicType::U16(t) => UnresolvedType::Uint(16).span(t.span),
|
||||||
pest::BasicType::U32(t) => UnresolvedType::Uint(32).span(t.span),
|
pest::BasicType::U32(t) => UnresolvedType::Uint(32).span(t.span),
|
||||||
|
pest::BasicType::U64(t) => UnresolvedType::Uint(64).span(t.span),
|
||||||
},
|
},
|
||||||
pest::Type::Array(t) => {
|
pest::Type::Array(t) => {
|
||||||
let inner_type = match t.ty {
|
let inner_type = match t.ty {
|
||||||
|
@ -718,6 +742,7 @@ impl<'ast> From<pest::Type<'ast>> for absy::UnresolvedTypeNode<'ast> {
|
||||||
pest::BasicType::U8(t) => UnresolvedType::Uint(8).span(t.span),
|
pest::BasicType::U8(t) => UnresolvedType::Uint(8).span(t.span),
|
||||||
pest::BasicType::U16(t) => UnresolvedType::Uint(16).span(t.span),
|
pest::BasicType::U16(t) => UnresolvedType::Uint(16).span(t.span),
|
||||||
pest::BasicType::U32(t) => UnresolvedType::Uint(32).span(t.span),
|
pest::BasicType::U32(t) => UnresolvedType::Uint(32).span(t.span),
|
||||||
|
pest::BasicType::U64(t) => UnresolvedType::Uint(64).span(t.span),
|
||||||
},
|
},
|
||||||
pest::BasicOrStructType::Struct(t) => {
|
pest::BasicOrStructType::Struct(t) => {
|
||||||
UnresolvedType::User(t.span.as_str().to_string()).span(t.span)
|
UnresolvedType::User(t.span.as_str().to_string()).span(t.span)
|
||||||
|
|
|
@ -18,6 +18,7 @@ pub use crate::absy::variable::{Variable, VariableNode};
|
||||||
use crate::embed::FlatEmbed;
|
use crate::embed::FlatEmbed;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use crate::imports::ImportDirective;
|
||||||
use crate::imports::ImportNode;
|
use crate::imports::ImportNode;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
@ -538,6 +539,7 @@ pub enum Expression<'ast> {
|
||||||
U8Constant(u8),
|
U8Constant(u8),
|
||||||
U16Constant(u16),
|
U16Constant(u16),
|
||||||
U32Constant(u32),
|
U32Constant(u32),
|
||||||
|
U64Constant(u64),
|
||||||
Identifier(Identifier<'ast>),
|
Identifier(Identifier<'ast>),
|
||||||
Add(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
Add(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
||||||
Sub(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
Sub(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
||||||
|
@ -545,6 +547,8 @@ pub enum Expression<'ast> {
|
||||||
Div(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
Div(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
||||||
Rem(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
Rem(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
||||||
Pow(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
Pow(Box<ExpressionNode<'ast>>, Box<ExpressionNode<'ast>>),
|
||||||
|
Neg(Box<ExpressionNode<'ast>>),
|
||||||
|
Pos(Box<ExpressionNode<'ast>>),
|
||||||
IfElse(
|
IfElse(
|
||||||
Box<ExpressionNode<'ast>>,
|
Box<ExpressionNode<'ast>>,
|
||||||
Box<ExpressionNode<'ast>>,
|
Box<ExpressionNode<'ast>>,
|
||||||
|
@ -584,6 +588,7 @@ impl<'ast> fmt::Display for Expression<'ast> {
|
||||||
Expression::U8Constant(ref i) => write!(f, "{}", i),
|
Expression::U8Constant(ref i) => write!(f, "{}", i),
|
||||||
Expression::U16Constant(ref i) => write!(f, "{}", i),
|
Expression::U16Constant(ref i) => write!(f, "{}", i),
|
||||||
Expression::U32Constant(ref i) => write!(f, "{}", i),
|
Expression::U32Constant(ref i) => write!(f, "{}", i),
|
||||||
|
Expression::U64Constant(ref i) => write!(f, "{}", i),
|
||||||
Expression::IntConstant(ref i) => write!(f, "{}", i),
|
Expression::IntConstant(ref i) => write!(f, "{}", i),
|
||||||
Expression::Identifier(ref var) => write!(f, "{}", var),
|
Expression::Identifier(ref var) => write!(f, "{}", var),
|
||||||
Expression::Add(ref lhs, ref rhs) => write!(f, "({} + {})", lhs, rhs),
|
Expression::Add(ref lhs, ref rhs) => write!(f, "({} + {})", lhs, rhs),
|
||||||
|
@ -592,6 +597,8 @@ impl<'ast> fmt::Display for Expression<'ast> {
|
||||||
Expression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
Expression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
||||||
Expression::Rem(ref lhs, ref rhs) => write!(f, "({} % {})", lhs, rhs),
|
Expression::Rem(ref lhs, ref rhs) => write!(f, "({} % {})", lhs, rhs),
|
||||||
Expression::Pow(ref lhs, ref rhs) => write!(f, "({}**{})", lhs, rhs),
|
Expression::Pow(ref lhs, ref rhs) => write!(f, "({}**{})", lhs, rhs),
|
||||||
|
Expression::Neg(ref e) => write!(f, "(-{})", e),
|
||||||
|
Expression::Pos(ref e) => write!(f, "(+{})", e),
|
||||||
Expression::BooleanConstant(b) => write!(f, "{}", b),
|
Expression::BooleanConstant(b) => write!(f, "{}", b),
|
||||||
Expression::IfElse(ref condition, ref consequent, ref alternative) => write!(
|
Expression::IfElse(ref condition, ref consequent, ref alternative) => write!(
|
||||||
f,
|
f,
|
||||||
|
@ -667,6 +674,7 @@ impl<'ast> fmt::Debug for Expression<'ast> {
|
||||||
Expression::U8Constant(ref i) => write!(f, "U8({:x})", i),
|
Expression::U8Constant(ref i) => write!(f, "U8({:x})", i),
|
||||||
Expression::U16Constant(ref i) => write!(f, "U16({:x})", i),
|
Expression::U16Constant(ref i) => write!(f, "U16({:x})", i),
|
||||||
Expression::U32Constant(ref i) => write!(f, "U32({:x})", i),
|
Expression::U32Constant(ref i) => write!(f, "U32({:x})", i),
|
||||||
|
Expression::U64Constant(ref i) => write!(f, "U64({:x})", i),
|
||||||
Expression::FieldConstant(ref i) => write!(f, "Field({:?})", i),
|
Expression::FieldConstant(ref i) => write!(f, "Field({:?})", i),
|
||||||
Expression::IntConstant(ref i) => write!(f, "Int({:?})", i),
|
Expression::IntConstant(ref i) => write!(f, "Int({:?})", i),
|
||||||
Expression::Identifier(ref var) => write!(f, "Ide({})", var),
|
Expression::Identifier(ref var) => write!(f, "Ide({})", var),
|
||||||
|
@ -676,6 +684,8 @@ impl<'ast> fmt::Debug for Expression<'ast> {
|
||||||
Expression::Div(ref lhs, ref rhs) => write!(f, "Div({:?}, {:?})", lhs, rhs),
|
Expression::Div(ref lhs, ref rhs) => write!(f, "Div({:?}, {:?})", lhs, rhs),
|
||||||
Expression::Rem(ref lhs, ref rhs) => write!(f, "Rem({:?}, {:?})", lhs, rhs),
|
Expression::Rem(ref lhs, ref rhs) => write!(f, "Rem({:?}, {:?})", lhs, rhs),
|
||||||
Expression::Pow(ref lhs, ref rhs) => write!(f, "Pow({:?}, {:?})", lhs, rhs),
|
Expression::Pow(ref lhs, ref rhs) => write!(f, "Pow({:?}, {:?})", lhs, rhs),
|
||||||
|
Expression::Neg(ref e) => write!(f, "Neg({:?})", e),
|
||||||
|
Expression::Pos(ref e) => write!(f, "Pos({:?})", e),
|
||||||
Expression::BooleanConstant(b) => write!(f, "{}", b),
|
Expression::BooleanConstant(b) => write!(f, "{}", b),
|
||||||
Expression::IfElse(ref condition, ref consequent, ref alternative) => write!(
|
Expression::IfElse(ref condition, ref consequent, ref alternative) => write!(
|
||||||
f,
|
f,
|
||||||
|
|
|
@ -29,9 +29,11 @@ pub enum FlatEmbed {
|
||||||
U8ToBits,
|
U8ToBits,
|
||||||
U16ToBits,
|
U16ToBits,
|
||||||
U32ToBits,
|
U32ToBits,
|
||||||
|
U64ToBits,
|
||||||
U8FromBits,
|
U8FromBits,
|
||||||
U16FromBits,
|
U16FromBits,
|
||||||
U32FromBits,
|
U32FromBits,
|
||||||
|
U64FromBits,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlatEmbed {
|
impl FlatEmbed {
|
||||||
|
@ -65,6 +67,12 @@ impl FlatEmbed {
|
||||||
DeclarationType::Boolean,
|
DeclarationType::Boolean,
|
||||||
32usize,
|
32usize,
|
||||||
))]),
|
))]),
|
||||||
|
FlatEmbed::U64ToBits => DeclarationSignature::new()
|
||||||
|
.inputs(vec![DeclarationType::uint(64)])
|
||||||
|
.outputs(vec![DeclarationType::array((
|
||||||
|
DeclarationType::Boolean,
|
||||||
|
64usize,
|
||||||
|
))]),
|
||||||
FlatEmbed::U8FromBits => DeclarationSignature::new()
|
FlatEmbed::U8FromBits => DeclarationSignature::new()
|
||||||
.outputs(vec![DeclarationType::uint(8)])
|
.outputs(vec![DeclarationType::uint(8)])
|
||||||
.inputs(vec![DeclarationType::array((
|
.inputs(vec![DeclarationType::array((
|
||||||
|
@ -83,6 +91,12 @@ impl FlatEmbed {
|
||||||
DeclarationType::Boolean,
|
DeclarationType::Boolean,
|
||||||
32usize,
|
32usize,
|
||||||
))]),
|
))]),
|
||||||
|
FlatEmbed::U64FromBits => DeclarationSignature::new()
|
||||||
|
.outputs(vec![DeclarationType::uint(64)])
|
||||||
|
.inputs(vec![DeclarationType::array((
|
||||||
|
DeclarationType::Boolean,
|
||||||
|
64usize,
|
||||||
|
))]),
|
||||||
#[cfg(feature = "bellman")]
|
#[cfg(feature = "bellman")]
|
||||||
FlatEmbed::Sha256Round => DeclarationSignature::new()
|
FlatEmbed::Sha256Round => DeclarationSignature::new()
|
||||||
.inputs(vec![
|
.inputs(vec![
|
||||||
|
@ -120,9 +134,11 @@ impl FlatEmbed {
|
||||||
FlatEmbed::U8ToBits => "_U8_TO_BITS",
|
FlatEmbed::U8ToBits => "_U8_TO_BITS",
|
||||||
FlatEmbed::U16ToBits => "_U16_TO_BITS",
|
FlatEmbed::U16ToBits => "_U16_TO_BITS",
|
||||||
FlatEmbed::U32ToBits => "_U32_TO_BITS",
|
FlatEmbed::U32ToBits => "_U32_TO_BITS",
|
||||||
|
FlatEmbed::U64ToBits => "_U64_TO_BITS",
|
||||||
FlatEmbed::U8FromBits => "_U8_FROM_BITS",
|
FlatEmbed::U8FromBits => "_U8_FROM_BITS",
|
||||||
FlatEmbed::U16FromBits => "_U16_FROM_BITS",
|
FlatEmbed::U16FromBits => "_U16_FROM_BITS",
|
||||||
FlatEmbed::U32FromBits => "_U32_FROM_BITS",
|
FlatEmbed::U32FromBits => "_U32_FROM_BITS",
|
||||||
|
FlatEmbed::U64FromBits => "_U64_FROM_BITS",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -857,6 +857,11 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
||||||
param_expressions: Vec<ZirExpression<'ast, T>>,
|
param_expressions: Vec<ZirExpression<'ast, T>>,
|
||||||
) -> Vec<FlatUExpression<T>> {
|
) -> Vec<FlatUExpression<T>> {
|
||||||
match embed {
|
match embed {
|
||||||
|
crate::embed::FlatEmbed::U64ToBits => self.flatten_u_to_bits(
|
||||||
|
statements_flattened,
|
||||||
|
param_expressions[0].clone(),
|
||||||
|
64.into(),
|
||||||
|
),
|
||||||
crate::embed::FlatEmbed::U32ToBits => self.flatten_u_to_bits(
|
crate::embed::FlatEmbed::U32ToBits => self.flatten_u_to_bits(
|
||||||
statements_flattened,
|
statements_flattened,
|
||||||
param_expressions[0].clone(),
|
param_expressions[0].clone(),
|
||||||
|
@ -870,6 +875,9 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
||||||
crate::embed::FlatEmbed::U8ToBits => {
|
crate::embed::FlatEmbed::U8ToBits => {
|
||||||
self.flatten_u_to_bits(statements_flattened, param_expressions[0].clone(), 8.into())
|
self.flatten_u_to_bits(statements_flattened, param_expressions[0].clone(), 8.into())
|
||||||
}
|
}
|
||||||
|
crate::embed::FlatEmbed::U64FromBits => {
|
||||||
|
vec![self.flatten_bits_to_u(statements_flattened, param_expressions, 64.into())]
|
||||||
|
}
|
||||||
crate::embed::FlatEmbed::U32FromBits => {
|
crate::embed::FlatEmbed::U32FromBits => {
|
||||||
vec![self.flatten_bits_to_u(statements_flattened, param_expressions, 32.into())]
|
vec![self.flatten_bits_to_u(statements_flattened, param_expressions, 32.into())]
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1133,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
||||||
let _ = self.get_bits(
|
let _ = self.get_bits(
|
||||||
FlatUExpression::with_field(FlatExpression::Add(
|
FlatUExpression::with_field(FlatExpression::Add(
|
||||||
box FlatExpression::Sub(box r.into(), box d.clone()),
|
box FlatExpression::Sub(box r.into(), box d.clone()),
|
||||||
box FlatExpression::Number(T::from(2usize.pow(target_bitwidth.to_usize() as u32))),
|
box FlatExpression::Number(T::from(2_u128.pow(target_bitwidth.to_usize() as u32))),
|
||||||
)),
|
)),
|
||||||
target_bitwidth.to_usize(),
|
target_bitwidth.to_usize(),
|
||||||
target_bitwidth,
|
target_bitwidth,
|
||||||
|
@ -2077,7 +2085,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match embed {
|
match embed {
|
||||||
FlatEmbed::U32FromBits
|
FlatEmbed::U64FromBits
|
||||||
|
| FlatEmbed::U32FromBits
|
||||||
| FlatEmbed::U16FromBits
|
| FlatEmbed::U16FromBits
|
||||||
| FlatEmbed::U8FromBits => {
|
| FlatEmbed::U8FromBits => {
|
||||||
let bits = exprs
|
let bits = exprs
|
||||||
|
|
|
@ -56,6 +56,25 @@ impl From<io::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone)]
|
||||||
|
pub enum ImportDirective<'ast> {
|
||||||
|
Main(ImportNode<'ast>),
|
||||||
|
From(Vec<ImportNode<'ast>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast> IntoIterator for ImportDirective<'ast> {
|
||||||
|
type Item = ImportNode<'ast>;
|
||||||
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
let vec = match self {
|
||||||
|
ImportDirective::Main(v) => vec![v],
|
||||||
|
ImportDirective::From(v) => v,
|
||||||
|
};
|
||||||
|
vec.into_iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ImportPath<'ast> = &'ast Path;
|
type ImportPath<'ast> = &'ast Path;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone)]
|
#[derive(PartialEq, Clone)]
|
||||||
|
@ -179,6 +198,17 @@ impl Importer {
|
||||||
.start_end(pos.0, pos.1),
|
.start_end(pos.0, pos.1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"EMBED/u64_to_bits" => {
|
||||||
|
let alias = alias.unwrap_or("u64_to_bits");
|
||||||
|
|
||||||
|
symbols.push(
|
||||||
|
SymbolDeclaration {
|
||||||
|
id: &alias,
|
||||||
|
symbol: Symbol::Flat(FlatEmbed::U64ToBits),
|
||||||
|
}
|
||||||
|
.start_end(pos.0, pos.1),
|
||||||
|
);
|
||||||
|
}
|
||||||
"EMBED/u32_to_bits" => {
|
"EMBED/u32_to_bits" => {
|
||||||
let alias = alias.unwrap_or("u32_to_bits");
|
let alias = alias.unwrap_or("u32_to_bits");
|
||||||
|
|
||||||
|
@ -212,6 +242,17 @@ impl Importer {
|
||||||
.start_end(pos.0, pos.1),
|
.start_end(pos.0, pos.1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"EMBED/u64_from_bits" => {
|
||||||
|
let alias = alias.unwrap_or("u64_from_bits");
|
||||||
|
|
||||||
|
symbols.push(
|
||||||
|
SymbolDeclaration {
|
||||||
|
id: &alias,
|
||||||
|
symbol: Symbol::Flat(FlatEmbed::U64FromBits),
|
||||||
|
}
|
||||||
|
.start_end(pos.0, pos.1),
|
||||||
|
);
|
||||||
|
}
|
||||||
"EMBED/u32_from_bits" => {
|
"EMBED/u32_from_bits" => {
|
||||||
let alias = alias.unwrap_or("u32_from_bits");
|
let alias = alias.unwrap_or("u32_from_bits");
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn prepare_public_inputs<T: Field>(public_inputs: Vec<T>) -> (Vec<[u8; 32]>,
|
||||||
let mut public_inputs_arr: Vec<[u8; 32]> = vec![[0u8; 32]; public_inputs_length];
|
let mut public_inputs_arr: Vec<[u8; 32]> = vec![[0u8; 32]; public_inputs_length];
|
||||||
|
|
||||||
for (index, value) in public_inputs.into_iter().enumerate() {
|
for (index, value) in public_inputs.into_iter().enumerate() {
|
||||||
public_inputs_arr[index] = vec_as_u8_32_array(&value.into_byte_vector());
|
public_inputs_arr[index] = vec_as_u8_32_array(&value.to_byte_vector());
|
||||||
}
|
}
|
||||||
|
|
||||||
(public_inputs_arr, public_inputs_length)
|
(public_inputs_arr, public_inputs_length)
|
||||||
|
@ -62,21 +62,21 @@ pub fn prepare_setup<T: Field>(
|
||||||
a_vec.push((
|
a_vec.push((
|
||||||
row as i32,
|
row as i32,
|
||||||
idx as i32,
|
idx as i32,
|
||||||
vec_as_u8_32_array(&val.into_byte_vector()),
|
vec_as_u8_32_array(&val.to_byte_vector()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
for &(idx, ref val) in &b[row] {
|
for &(idx, ref val) in &b[row] {
|
||||||
b_vec.push((
|
b_vec.push((
|
||||||
row as i32,
|
row as i32,
|
||||||
idx as i32,
|
idx as i32,
|
||||||
vec_as_u8_32_array(&val.into_byte_vector()),
|
vec_as_u8_32_array(&val.to_byte_vector()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
for &(idx, ref val) in &c[row] {
|
for &(idx, ref val) in &c[row] {
|
||||||
c_vec.push((
|
c_vec.push((
|
||||||
row as i32,
|
row as i32,
|
||||||
idx as i32,
|
idx as i32,
|
||||||
vec_as_u8_32_array(&val.into_byte_vector()),
|
vec_as_u8_32_array(&val.to_byte_vector()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,10 +177,10 @@ pub fn prepare_generate_proof<T: Field>(
|
||||||
|
|
||||||
//convert inputs
|
//convert inputs
|
||||||
for (index, value) in public_inputs.into_iter().enumerate() {
|
for (index, value) in public_inputs.into_iter().enumerate() {
|
||||||
public_inputs_arr[index] = vec_as_u8_32_array(&value.into_byte_vector());
|
public_inputs_arr[index] = vec_as_u8_32_array(&value.to_byte_vector());
|
||||||
}
|
}
|
||||||
for (index, value) in private_inputs.into_iter().enumerate() {
|
for (index, value) in private_inputs.into_iter().enumerate() {
|
||||||
private_inputs_arr[index] = vec_as_u8_32_array(&value.into_byte_vector());
|
private_inputs_arr[index] = vec_as_u8_32_array(&value.to_byte_vector());
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
|
|
|
@ -1852,6 +1852,44 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Expression::Neg(box e) => {
|
||||||
|
let e = self.check_expression(e, module_id, &types)?;
|
||||||
|
|
||||||
|
match e {
|
||||||
|
TypedExpression::Int(e) => Ok(IntExpression::Neg(box e).into()),
|
||||||
|
TypedExpression::FieldElement(e) => {
|
||||||
|
Ok(FieldElementExpression::Neg(box e).into())
|
||||||
|
}
|
||||||
|
TypedExpression::Uint(e) => Ok((-e).into()),
|
||||||
|
e => Err(ErrorInner {
|
||||||
|
pos: Some(pos),
|
||||||
|
message: format!(
|
||||||
|
"Unary operator `-` cannot be applied to {} of type {}",
|
||||||
|
e,
|
||||||
|
e.get_type()
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expression::Pos(box e) => {
|
||||||
|
let e = self.check_expression(e, module_id, &types)?;
|
||||||
|
|
||||||
|
match e {
|
||||||
|
TypedExpression::Int(e) => Ok(IntExpression::Pos(box e).into()),
|
||||||
|
TypedExpression::FieldElement(e) => {
|
||||||
|
Ok(FieldElementExpression::Pos(box e).into())
|
||||||
|
}
|
||||||
|
TypedExpression::Uint(e) => Ok(UExpression::pos(e).into()),
|
||||||
|
e => Err(ErrorInner {
|
||||||
|
pos: Some(pos),
|
||||||
|
message: format!(
|
||||||
|
"Unary operator `+` cannot be applied to {} of type {}",
|
||||||
|
e,
|
||||||
|
e.get_type()
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
Expression::IfElse(box condition, box consequence, box alternative) => {
|
Expression::IfElse(box condition, box consequence, box alternative) => {
|
||||||
let condition_checked = self.check_expression(condition, module_id, &types)?;
|
let condition_checked = self.check_expression(condition, module_id, &types)?;
|
||||||
let consequence_checked = self.check_expression(consequence, module_id, &types)?;
|
let consequence_checked = self.check_expression(consequence, module_id, &types)?;
|
||||||
|
@ -1921,6 +1959,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
||||||
Expression::U8Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(8).into()),
|
Expression::U8Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(8).into()),
|
||||||
Expression::U16Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(16).into()),
|
Expression::U16Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(16).into()),
|
||||||
Expression::U32Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(32).into()),
|
Expression::U32Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(32).into()),
|
||||||
|
Expression::U64Constant(n) => Ok(UExpressionInner::Value(n.into()).annotate(64).into()),
|
||||||
Expression::FunctionCall(fun_id, generics, arguments) => {
|
Expression::FunctionCall(fun_id, generics, arguments) => {
|
||||||
// check the generic arguments, if any
|
// check the generic arguments, if any
|
||||||
let generics_checked: Option<Vec<Option<UExpression<'ast, T>>>> = generics
|
let generics_checked: Option<Vec<Option<UExpression<'ast, T>>>> = generics
|
||||||
|
|
|
@ -562,6 +562,15 @@ pub fn fold_field_expression<'ast, T: Field>(
|
||||||
let e2 = f.fold_uint_expression(e2);
|
let e2 = f.fold_uint_expression(e2);
|
||||||
zir::FieldElementExpression::Pow(box e1, box e2)
|
zir::FieldElementExpression::Pow(box e1, box e2)
|
||||||
}
|
}
|
||||||
|
typed_absy::FieldElementExpression::Neg(box e) => {
|
||||||
|
let e = f.fold_field_expression(e);
|
||||||
|
|
||||||
|
zir::FieldElementExpression::Sub(
|
||||||
|
box zir::FieldElementExpression::Number(T::zero()),
|
||||||
|
box e,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
typed_absy::FieldElementExpression::Pos(box e) => f.fold_field_expression(e),
|
||||||
typed_absy::FieldElementExpression::IfElse(box cond, box cons, box alt) => {
|
typed_absy::FieldElementExpression::IfElse(box cond, box cons, box alt) => {
|
||||||
let cond = f.fold_boolean_expression(cond);
|
let cond = f.fold_boolean_expression(cond);
|
||||||
let cons = f.fold_field_expression(cons);
|
let cons = f.fold_field_expression(cons);
|
||||||
|
@ -861,6 +870,18 @@ pub fn fold_uint_expression_inner<'ast, T: Field>(
|
||||||
|
|
||||||
zir::UExpressionInner::Not(box e)
|
zir::UExpressionInner::Not(box e)
|
||||||
}
|
}
|
||||||
|
typed_absy::UExpressionInner::Neg(box e) => {
|
||||||
|
let bitwidth = e.bitwidth();
|
||||||
|
|
||||||
|
f.fold_uint_expression(typed_absy::UExpressionInner::Value(0).annotate(bitwidth) - e)
|
||||||
|
.into_inner()
|
||||||
|
}
|
||||||
|
|
||||||
|
typed_absy::UExpressionInner::Pos(box e) => {
|
||||||
|
let e = f.fold_uint_expression(e);
|
||||||
|
|
||||||
|
e.into_inner()
|
||||||
|
}
|
||||||
typed_absy::UExpressionInner::FunctionCall(..) => {
|
typed_absy::UExpressionInner::FunctionCall(..) => {
|
||||||
unreachable!("function calls should have been removed")
|
unreachable!("function calls should have been removed")
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,6 +439,11 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
||||||
true => {
|
true => {
|
||||||
let r: Option<TypedExpression<'ast, T>> = match embed {
|
let r: Option<TypedExpression<'ast, T>> = match embed {
|
||||||
FlatEmbed::U32ToField => None, // todo
|
FlatEmbed::U32ToField => None, // todo
|
||||||
|
FlatEmbed::U64FromBits => Some(process_u_from_bits(
|
||||||
|
assignees.clone(),
|
||||||
|
arguments.clone(),
|
||||||
|
UBitwidth::B64,
|
||||||
|
)),
|
||||||
FlatEmbed::U32FromBits => Some(process_u_from_bits(
|
FlatEmbed::U32FromBits => Some(process_u_from_bits(
|
||||||
assignees.clone(),
|
assignees.clone(),
|
||||||
arguments.clone(),
|
arguments.clone(),
|
||||||
|
@ -454,6 +459,11 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
||||||
arguments.clone(),
|
arguments.clone(),
|
||||||
UBitwidth::B8,
|
UBitwidth::B8,
|
||||||
)),
|
)),
|
||||||
|
FlatEmbed::U64ToBits => Some(process_u_to_bits(
|
||||||
|
assignees.clone(),
|
||||||
|
arguments.clone(),
|
||||||
|
UBitwidth::B64,
|
||||||
|
)),
|
||||||
FlatEmbed::U32ToBits => Some(process_u_to_bits(
|
FlatEmbed::U32ToBits => Some(process_u_to_bits(
|
||||||
assignees.clone(),
|
assignees.clone(),
|
||||||
arguments.clone(),
|
arguments.clone(),
|
||||||
|
@ -863,6 +873,23 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
||||||
e => UExpressionInner::Not(box e.annotate(bitwidth)),
|
e => UExpressionInner::Not(box e.annotate(bitwidth)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UExpressionInner::Neg(box e) => {
|
||||||
|
let e = self.fold_uint_expression(e)?.into_inner();
|
||||||
|
match e {
|
||||||
|
UExpressionInner::Value(v) => UExpressionInner::Value(
|
||||||
|
(0u128.wrapping_sub(v))
|
||||||
|
% 2_u128.pow(bitwidth.to_usize().try_into().unwrap()),
|
||||||
|
),
|
||||||
|
e => UExpressionInner::Neg(box e.annotate(bitwidth)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UExpressionInner::Pos(box e) => {
|
||||||
|
let e = self.fold_uint_expression(e)?.into_inner();
|
||||||
|
match e {
|
||||||
|
UExpressionInner::Value(v) => UExpressionInner::Value(v),
|
||||||
|
e => UExpressionInner::Pos(box e.annotate(bitwidth)),
|
||||||
|
}
|
||||||
|
}
|
||||||
UExpressionInner::Select(box array, box index) => {
|
UExpressionInner::Select(box array, box index) => {
|
||||||
let array = self.fold_array_expression(array)?;
|
let array = self.fold_array_expression(array)?;
|
||||||
let index = self.fold_uint_expression(index)?;
|
let index = self.fold_uint_expression(index)?;
|
||||||
|
@ -981,6 +1008,14 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
||||||
}
|
}
|
||||||
(e1, e2) => FieldElementExpression::Div(box e1, box e2),
|
(e1, e2) => FieldElementExpression::Div(box e1, box e2),
|
||||||
},
|
},
|
||||||
|
FieldElementExpression::Neg(box e) => match self.fold_field_expression(e)? {
|
||||||
|
FieldElementExpression::Number(n) => FieldElementExpression::Number(T::zero() - n),
|
||||||
|
e => FieldElementExpression::Neg(box e),
|
||||||
|
},
|
||||||
|
FieldElementExpression::Pos(box e) => match self.fold_field_expression(e)? {
|
||||||
|
FieldElementExpression::Number(n) => FieldElementExpression::Number(n),
|
||||||
|
e => FieldElementExpression::Pos(box e),
|
||||||
|
},
|
||||||
FieldElementExpression::Pow(box e1, box e2) => {
|
FieldElementExpression::Pow(box e1, box e2) => {
|
||||||
let e1 = self.fold_field_expression(e1)?;
|
let e1 = self.fold_field_expression(e1)?;
|
||||||
let e2 = self.fold_uint_expression(e2)?;
|
let e2 = self.fold_uint_expression(e2)?;
|
||||||
|
@ -1362,8 +1397,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
||||||
let e2 = self.fold_uint_expression(e2)?;
|
let e2 = self.fold_uint_expression(e2)?;
|
||||||
|
|
||||||
match (e1.as_inner(), e2.as_inner()) {
|
match (e1.as_inner(), e2.as_inner()) {
|
||||||
(UExpressionInner::Value(v1), UExpressionInner::Value(v2)) => {
|
(UExpressionInner::Value(n1), UExpressionInner::Value(n2)) => {
|
||||||
BooleanExpression::Value(v1 == v2)
|
BooleanExpression::Value(n1 == n2)
|
||||||
}
|
}
|
||||||
_ => BooleanExpression::UintEq(box e1, box e2),
|
_ => BooleanExpression::UintEq(box e1, box e2),
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||||
|
|
||||||
let range = e.bitwidth.to_usize();
|
let range = e.bitwidth.to_usize();
|
||||||
|
|
||||||
let range_max: T = (2_usize.pow(range as u32) - 1).into();
|
let range_max: T = (2_u128.pow(range as u32) - 1).into();
|
||||||
|
|
||||||
assert!(range < max_bitwidth / 2);
|
assert!(range < max_bitwidth / 2);
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||||
let e = self.fold_uint_expression(e);
|
let e = self.fold_uint_expression(e);
|
||||||
let by = self.fold_uint_expression(by);
|
let by = self.fold_uint_expression(by);
|
||||||
|
|
||||||
let by_max: usize = by
|
let by_max: u128 = by
|
||||||
.metadata
|
.metadata
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -327,7 +327,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||||
.to_dec_string()
|
.to_dec_string()
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let e_max: usize = e
|
let e_max: u128 = e
|
||||||
.metadata
|
.metadata
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -336,7 +336,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let max = T::from((e_max << by_max) & (2_usize.pow(range as u32) - 1));
|
let max = T::from((e_max << by_max) & (2_u128.pow(range as u32) - 1));
|
||||||
|
|
||||||
UExpression::left_shift(force_reduce(e), force_reduce(by)).with_max(max)
|
UExpression::left_shift(force_reduce(e), force_reduce(by)).with_max(max)
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let e_max: usize = e
|
let e_max: u128 = e
|
||||||
.metadata
|
.metadata
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -360,7 +360,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let max = (e_max & (2_usize.pow(range as u32) - 1)) >> by_u;
|
let max = (e_max & (2_u128.pow(range as u32) - 1)) >> by_u;
|
||||||
|
|
||||||
let max = T::from(max);
|
let max = T::from(max);
|
||||||
|
|
||||||
|
@ -423,6 +423,21 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||||
)],
|
)],
|
||||||
ZirStatement::MultipleDefinition(lhs, rhs) => match rhs {
|
ZirStatement::MultipleDefinition(lhs, rhs) => match rhs {
|
||||||
ZirExpressionList::EmbedCall(embed, generics, arguments) => match embed {
|
ZirExpressionList::EmbedCall(embed, generics, arguments) => match embed {
|
||||||
|
FlatEmbed::U64FromBits => {
|
||||||
|
assert_eq!(lhs.len(), 1);
|
||||||
|
self.register(
|
||||||
|
lhs[0].clone(),
|
||||||
|
UMetadata {
|
||||||
|
max: T::from(2).pow(64) - T::from(1),
|
||||||
|
should_reduce: ShouldReduce::False,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
vec![ZirStatement::MultipleDefinition(
|
||||||
|
lhs,
|
||||||
|
ZirExpressionList::EmbedCall(embed, generics, arguments),
|
||||||
|
)]
|
||||||
|
}
|
||||||
FlatEmbed::U32FromBits => {
|
FlatEmbed::U32FromBits => {
|
||||||
assert_eq!(lhs.len(), 1);
|
assert_eq!(lhs.len(), 1);
|
||||||
self.register(
|
self.register(
|
||||||
|
|
|
@ -369,6 +369,16 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
||||||
let e2 = f.fold_uint_expression(e2);
|
let e2 = f.fold_uint_expression(e2);
|
||||||
FieldElementExpression::Pow(box e1, box e2)
|
FieldElementExpression::Pow(box e1, box e2)
|
||||||
}
|
}
|
||||||
|
FieldElementExpression::Neg(box e) => {
|
||||||
|
let e = f.fold_field_expression(e);
|
||||||
|
|
||||||
|
FieldElementExpression::Neg(box e)
|
||||||
|
}
|
||||||
|
FieldElementExpression::Pos(box e) => {
|
||||||
|
let e = f.fold_field_expression(e);
|
||||||
|
|
||||||
|
FieldElementExpression::Pos(box e)
|
||||||
|
}
|
||||||
FieldElementExpression::IfElse(box cond, box cons, box alt) => {
|
FieldElementExpression::IfElse(box cond, box cons, box alt) => {
|
||||||
let cond = f.fold_boolean_expression(cond);
|
let cond = f.fold_boolean_expression(cond);
|
||||||
let cons = f.fold_field_expression(cons);
|
let cons = f.fold_field_expression(cons);
|
||||||
|
@ -603,6 +613,16 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: Folder<'ast, T>>(
|
||||||
|
|
||||||
UExpressionInner::Not(box e)
|
UExpressionInner::Not(box e)
|
||||||
}
|
}
|
||||||
|
UExpressionInner::Neg(box e) => {
|
||||||
|
let e = f.fold_uint_expression(e);
|
||||||
|
|
||||||
|
UExpressionInner::Neg(box e)
|
||||||
|
}
|
||||||
|
UExpressionInner::Pos(box e) => {
|
||||||
|
let e = f.fold_uint_expression(e);
|
||||||
|
|
||||||
|
UExpressionInner::Pos(box e)
|
||||||
|
}
|
||||||
UExpressionInner::FunctionCall(key, generics, exps) => {
|
UExpressionInner::FunctionCall(key, generics, exps) => {
|
||||||
let generics = generics
|
let generics = generics
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::typed_absy::{
|
||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Add, Div, Mul, Not, Rem, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Not, Rem, Sub};
|
||||||
use zokrates_field::Field;
|
use zokrates_field::Field;
|
||||||
|
|
||||||
type TypedExpressionPair<'ast, T> = (TypedExpression<'ast, T>, TypedExpression<'ast, T>);
|
type TypedExpressionPair<'ast, T> = (TypedExpression<'ast, T>, TypedExpression<'ast, T>);
|
||||||
|
@ -134,6 +134,8 @@ impl<'ast, T: Field> TypedExpression<'ast, T> {
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub enum IntExpression<'ast, T> {
|
pub enum IntExpression<'ast, T> {
|
||||||
Value(BigUint),
|
Value(BigUint),
|
||||||
|
Pos(Box<IntExpression<'ast, T>>),
|
||||||
|
Neg(Box<IntExpression<'ast, T>>),
|
||||||
Add(Box<IntExpression<'ast, T>>, Box<IntExpression<'ast, T>>),
|
Add(Box<IntExpression<'ast, T>>, Box<IntExpression<'ast, T>>),
|
||||||
Sub(Box<IntExpression<'ast, T>>, Box<IntExpression<'ast, T>>),
|
Sub(Box<IntExpression<'ast, T>>, Box<IntExpression<'ast, T>>),
|
||||||
Mult(Box<IntExpression<'ast, T>>, Box<IntExpression<'ast, T>>),
|
Mult(Box<IntExpression<'ast, T>>, Box<IntExpression<'ast, T>>),
|
||||||
|
@ -202,6 +204,14 @@ impl<'ast, T> Not for IntExpression<'ast, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'ast, T> Neg for IntExpression<'ast, T> {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> Self {
|
||||||
|
IntExpression::Neg(box self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'ast, T> IntExpression<'ast, T> {
|
impl<'ast, T> IntExpression<'ast, T> {
|
||||||
pub fn pow(self, other: Self) -> Self {
|
pub fn pow(self, other: Self) -> Self {
|
||||||
IntExpression::Pow(box self, box other)
|
IntExpression::Pow(box self, box other)
|
||||||
|
@ -226,12 +236,18 @@ impl<'ast, T> IntExpression<'ast, T> {
|
||||||
pub fn right_shift(self, by: UExpression<'ast, T>) -> Self {
|
pub fn right_shift(self, by: UExpression<'ast, T>) -> Self {
|
||||||
IntExpression::RightShift(box self, box by)
|
IntExpression::RightShift(box self, box by)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pos(self) -> Self {
|
||||||
|
IntExpression::Pos(box self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast, T: fmt::Display> fmt::Display for IntExpression<'ast, T> {
|
impl<'ast, T: fmt::Display> fmt::Display for IntExpression<'ast, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
IntExpression::Value(ref v) => write!(f, "{}", v),
|
IntExpression::Value(ref v) => write!(f, "{}", v),
|
||||||
|
IntExpression::Pos(ref e) => write!(f, "(+{})", e),
|
||||||
|
IntExpression::Neg(ref e) => write!(f, "(-{})", e),
|
||||||
IntExpression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
IntExpression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
||||||
IntExpression::Rem(ref lhs, ref rhs) => write!(f, "({} % {})", lhs, rhs),
|
IntExpression::Rem(ref lhs, ref rhs) => write!(f, "({} % {})", lhs, rhs),
|
||||||
IntExpression::Pow(ref lhs, ref rhs) => write!(f, "({} ** {})", lhs, rhs),
|
IntExpression::Pow(ref lhs, ref rhs) => write!(f, "({} ** {})", lhs, rhs),
|
||||||
|
@ -297,6 +313,8 @@ impl<'ast, T: Field> FieldElementExpression<'ast, T> {
|
||||||
box Self::try_from_int(e1)?,
|
box Self::try_from_int(e1)?,
|
||||||
box Self::try_from_int(e2)?,
|
box Self::try_from_int(e2)?,
|
||||||
)),
|
)),
|
||||||
|
IntExpression::Pos(box e) => Ok(Self::Pos(box Self::try_from_int(e)?)),
|
||||||
|
IntExpression::Neg(box e) => Ok(Self::Neg(box Self::try_from_int(e)?)),
|
||||||
IntExpression::IfElse(box condition, box consequence, box alternative) => {
|
IntExpression::IfElse(box condition, box consequence, box alternative) => {
|
||||||
Ok(Self::IfElse(
|
Ok(Self::IfElse(
|
||||||
box condition,
|
box condition,
|
||||||
|
@ -374,6 +392,8 @@ impl<'ast, T: Field> UExpression<'ast, T> {
|
||||||
Add(box e1, box e2) => {
|
Add(box e1, box e2) => {
|
||||||
Ok(Self::try_from_int(e1, bitwidth)? + Self::try_from_int(e2, bitwidth)?)
|
Ok(Self::try_from_int(e1, bitwidth)? + Self::try_from_int(e2, bitwidth)?)
|
||||||
}
|
}
|
||||||
|
Pos(box e) => Ok(Self::pos(Self::try_from_int(e, bitwidth)?)),
|
||||||
|
Neg(box e) => Ok(Self::neg(Self::try_from_int(e, bitwidth)?)),
|
||||||
Sub(box e1, box e2) => {
|
Sub(box e1, box e2) => {
|
||||||
Ok(Self::try_from_int(e1, bitwidth)? - Self::try_from_int(e2, bitwidth)?)
|
Ok(Self::try_from_int(e1, bitwidth)? - Self::try_from_int(e2, bitwidth)?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -846,6 +846,8 @@ pub enum FieldElementExpression<'ast, T> {
|
||||||
Box<FieldElementExpression<'ast, T>>,
|
Box<FieldElementExpression<'ast, T>>,
|
||||||
Box<FieldElementExpression<'ast, T>>,
|
Box<FieldElementExpression<'ast, T>>,
|
||||||
),
|
),
|
||||||
|
Neg(Box<FieldElementExpression<'ast, T>>),
|
||||||
|
Pos(Box<FieldElementExpression<'ast, T>>),
|
||||||
FunctionCall(
|
FunctionCall(
|
||||||
DeclarationFunctionKey<'ast>,
|
DeclarationFunctionKey<'ast>,
|
||||||
Vec<Option<UExpression<'ast, T>>>,
|
Vec<Option<UExpression<'ast, T>>>,
|
||||||
|
@ -1269,6 +1271,8 @@ impl<'ast, T: fmt::Display> fmt::Display for FieldElementExpression<'ast, T> {
|
||||||
FieldElementExpression::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs),
|
FieldElementExpression::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs),
|
||||||
FieldElementExpression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
FieldElementExpression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
||||||
FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "{}**{}", lhs, rhs),
|
FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "{}**{}", lhs, rhs),
|
||||||
|
FieldElementExpression::Neg(ref e) => write!(f, "(-{})", e),
|
||||||
|
FieldElementExpression::Pos(ref e) => write!(f, "(+{})", e),
|
||||||
FieldElementExpression::IfElse(ref condition, ref consequent, ref alternative) => {
|
FieldElementExpression::IfElse(ref condition, ref consequent, ref alternative) => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
@ -1326,6 +1330,8 @@ impl<'ast, T: fmt::Display> fmt::Display for UExpression<'ast, T> {
|
||||||
UExpressionInner::RightShift(ref e, ref by) => write!(f, "({} >> {})", e, by),
|
UExpressionInner::RightShift(ref e, ref by) => write!(f, "({} >> {})", e, by),
|
||||||
UExpressionInner::LeftShift(ref e, ref by) => write!(f, "({} << {})", e, by),
|
UExpressionInner::LeftShift(ref e, ref by) => write!(f, "({} << {})", e, by),
|
||||||
UExpressionInner::Not(ref e) => write!(f, "!{}", e),
|
UExpressionInner::Not(ref e) => write!(f, "!{}", e),
|
||||||
|
UExpressionInner::Neg(ref e) => write!(f, "(-{})", e),
|
||||||
|
UExpressionInner::Pos(ref e) => write!(f, "(+{})", e),
|
||||||
UExpressionInner::Select(ref id, ref index) => write!(f, "{}[{}]", id, index),
|
UExpressionInner::Select(ref id, ref index) => write!(f, "{}[{}]", id, index),
|
||||||
UExpressionInner::FunctionCall(ref k, ref generics, ref p) => {
|
UExpressionInner::FunctionCall(ref k, ref generics, ref p) => {
|
||||||
write!(f, "{}", k.id,)?;
|
write!(f, "{}", k.id,)?;
|
||||||
|
@ -1553,6 +1559,8 @@ impl<'ast, T: fmt::Debug> fmt::Debug for FieldElementExpression<'ast, T> {
|
||||||
}
|
}
|
||||||
FieldElementExpression::Div(ref lhs, ref rhs) => write!(f, "Div({:?}, {:?})", lhs, rhs),
|
FieldElementExpression::Div(ref lhs, ref rhs) => write!(f, "Div({:?}, {:?})", lhs, rhs),
|
||||||
FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "Pow({:?}, {:?})", lhs, rhs),
|
FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "Pow({:?}, {:?})", lhs, rhs),
|
||||||
|
FieldElementExpression::Neg(ref e) => write!(f, "Neg({:?})", e),
|
||||||
|
FieldElementExpression::Pos(ref e) => write!(f, "Pos({:?})", e),
|
||||||
FieldElementExpression::IfElse(ref condition, ref consequent, ref alternative) => {
|
FieldElementExpression::IfElse(ref condition, ref consequent, ref alternative) => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
|
|
@ -417,6 +417,16 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
||||||
let e2 = f.fold_uint_expression(e2)?;
|
let e2 = f.fold_uint_expression(e2)?;
|
||||||
FieldElementExpression::Pow(box e1, box e2)
|
FieldElementExpression::Pow(box e1, box e2)
|
||||||
}
|
}
|
||||||
|
FieldElementExpression::Neg(box e) => {
|
||||||
|
let e = f.fold_field_expression(e)?;
|
||||||
|
|
||||||
|
FieldElementExpression::Neg(box e)
|
||||||
|
}
|
||||||
|
FieldElementExpression::Pos(box e) => {
|
||||||
|
let e = f.fold_field_expression(e)?;
|
||||||
|
|
||||||
|
FieldElementExpression::Pos(box e)
|
||||||
|
}
|
||||||
FieldElementExpression::IfElse(box cond, box cons, box alt) => {
|
FieldElementExpression::IfElse(box cond, box cons, box alt) => {
|
||||||
let cond = f.fold_boolean_expression(cond)?;
|
let cond = f.fold_boolean_expression(cond)?;
|
||||||
let cons = f.fold_field_expression(cons)?;
|
let cons = f.fold_field_expression(cons)?;
|
||||||
|
@ -659,6 +669,16 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
||||||
|
|
||||||
UExpressionInner::Not(box e)
|
UExpressionInner::Not(box e)
|
||||||
}
|
}
|
||||||
|
UExpressionInner::Neg(box e) => {
|
||||||
|
let e = f.fold_uint_expression(e)?;
|
||||||
|
|
||||||
|
UExpressionInner::Neg(box e)
|
||||||
|
}
|
||||||
|
UExpressionInner::Pos(box e) => {
|
||||||
|
let e = f.fold_uint_expression(e)?;
|
||||||
|
|
||||||
|
UExpressionInner::Pos(box e)
|
||||||
|
}
|
||||||
UExpressionInner::FunctionCall(key, generics, exps) => {
|
UExpressionInner::FunctionCall(key, generics, exps) => {
|
||||||
let generics = generics
|
let generics = generics
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -387,6 +387,8 @@ pub enum UBitwidth {
|
||||||
B16 = 16,
|
B16 = 16,
|
||||||
#[serde(rename = "32")]
|
#[serde(rename = "32")]
|
||||||
B32 = 32,
|
B32 = 32,
|
||||||
|
#[serde(rename = "64")]
|
||||||
|
B64 = 64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UBitwidth {
|
impl UBitwidth {
|
||||||
|
@ -401,6 +403,7 @@ impl From<usize> for UBitwidth {
|
||||||
8 => UBitwidth::B8,
|
8 => UBitwidth::B8,
|
||||||
16 => UBitwidth::B16,
|
16 => UBitwidth::B16,
|
||||||
32 => UBitwidth::B32,
|
32 => UBitwidth::B32,
|
||||||
|
64 => UBitwidth::B64,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,6 +515,7 @@ impl<'de, S: Deserialize<'de>> Deserialize<'de> for GType<S> {
|
||||||
"u8" => strict_type(mapping, GType::Uint(UBitwidth::B8)),
|
"u8" => strict_type(mapping, GType::Uint(UBitwidth::B8)),
|
||||||
"u16" => strict_type(mapping, GType::Uint(UBitwidth::B16)),
|
"u16" => strict_type(mapping, GType::Uint(UBitwidth::B16)),
|
||||||
"u32" => strict_type(mapping, GType::Uint(UBitwidth::B32)),
|
"u32" => strict_type(mapping, GType::Uint(UBitwidth::B32)),
|
||||||
|
"u64" => strict_type(mapping, GType::Uint(UBitwidth::B64)),
|
||||||
t => Err(D::Error::custom(format!("invalid type `{}`", t))),
|
t => Err(D::Error::custom(format!("invalid type `{}`", t))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::typed_absy::types::UBitwidth;
|
use crate::typed_absy::types::UBitwidth;
|
||||||
use crate::typed_absy::*;
|
use crate::typed_absy::*;
|
||||||
use std::ops::{Add, Div, Mul, Not, Rem, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Not, Rem, Sub};
|
||||||
use zokrates_field::Field;
|
use zokrates_field::Field;
|
||||||
|
|
||||||
type Bitwidth = usize;
|
type Bitwidth = usize;
|
||||||
|
@ -69,6 +69,15 @@ impl<'ast, T> Not for UExpression<'ast, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'ast, T> Neg for UExpression<'ast, T> {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> UExpression<'ast, T> {
|
||||||
|
let bitwidth = self.bitwidth;
|
||||||
|
UExpressionInner::Neg(box self).annotate(bitwidth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'ast, T: Field> UExpression<'ast, T> {
|
impl<'ast, T: Field> UExpression<'ast, T> {
|
||||||
pub fn xor(self, other: Self) -> UExpression<'ast, T> {
|
pub fn xor(self, other: Self) -> UExpression<'ast, T> {
|
||||||
let bitwidth = self.bitwidth;
|
let bitwidth = self.bitwidth;
|
||||||
|
@ -88,6 +97,11 @@ impl<'ast, T: Field> UExpression<'ast, T> {
|
||||||
UExpressionInner::And(box self, box other).annotate(bitwidth)
|
UExpressionInner::And(box self, box other).annotate(bitwidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pos(self) -> UExpression<'ast, T> {
|
||||||
|
let bitwidth = self.bitwidth;
|
||||||
|
UExpressionInner::Pos(box self).annotate(bitwidth)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn left_shift(self, by: UExpression<'ast, T>) -> UExpression<'ast, T> {
|
pub fn left_shift(self, by: UExpression<'ast, T>) -> UExpression<'ast, T> {
|
||||||
let bitwidth = self.bitwidth;
|
let bitwidth = self.bitwidth;
|
||||||
assert_eq!(by.bitwidth, UBitwidth::B32);
|
assert_eq!(by.bitwidth, UBitwidth::B32);
|
||||||
|
@ -173,6 +187,8 @@ pub enum UExpressionInner<'ast, T> {
|
||||||
And(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
And(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||||
Or(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
Or(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||||
Not(Box<UExpression<'ast, T>>),
|
Not(Box<UExpression<'ast, T>>),
|
||||||
|
Neg(Box<UExpression<'ast, T>>),
|
||||||
|
Pos(Box<UExpression<'ast, T>>),
|
||||||
FunctionCall(
|
FunctionCall(
|
||||||
DeclarationFunctionKey<'ast>,
|
DeclarationFunctionKey<'ast>,
|
||||||
Vec<Option<UExpression<'ast, T>>>,
|
Vec<Option<UExpression<'ast, T>>>,
|
||||||
|
|
|
@ -18,6 +18,8 @@ pub enum UBitwidth {
|
||||||
B16 = 16,
|
B16 = 16,
|
||||||
#[serde(rename = "32")]
|
#[serde(rename = "32")]
|
||||||
B32 = 32,
|
B32 = 32,
|
||||||
|
#[serde(rename = "64")]
|
||||||
|
B64 = 64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UBitwidth {
|
impl UBitwidth {
|
||||||
|
@ -26,6 +28,7 @@ impl UBitwidth {
|
||||||
UBitwidth::B8 => 8,
|
UBitwidth::B8 => 8,
|
||||||
UBitwidth::B16 => 16,
|
UBitwidth::B16 => 16,
|
||||||
UBitwidth::B32 => 32,
|
UBitwidth::B32 => 32,
|
||||||
|
UBitwidth::B64 => 64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +39,7 @@ impl From<usize> for UBitwidth {
|
||||||
8 => UBitwidth::B8,
|
8 => UBitwidth::B8,
|
||||||
16 => UBitwidth::B16,
|
16 => UBitwidth::B16,
|
||||||
32 => UBitwidth::B32,
|
32 => UBitwidth::B32,
|
||||||
|
64 => UBitwidth::B64,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "zokrates_core_test"
|
name = "zokrates_core_test"
|
||||||
version = "0.1.5"
|
version = "0.2.0"
|
||||||
authors = ["schaeff <thibaut@schaeff.fr>"]
|
authors = ["schaeff <thibaut@schaeff.fr>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|
15
zokrates_core_test/tests/tests/neg_pos.json
Normal file
15
zokrates_core_test/tests/tests/neg_pos.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/neg_pos.zok",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["1", "2", "1", "2"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["21888242871839275222246405745257275088548364400416034343698204186575808495615", "21888242871839275222246405745257275088548364400416034343698204186575808495616", "21888242871839275222246405745257275088548364400416034343698204186575808495616", "21888242871839275222246405745257275088548364400416034343698204186575808495616", "254", "255", "255", "255"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
15
zokrates_core_test/tests/tests/neg_pos.zok
Normal file
15
zokrates_core_test/tests/tests/neg_pos.zok
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
def main(field x, field y, u8 z, u8 t) -> (field[4], u8[4]):
|
||||||
|
field a = -y // should parse to neg
|
||||||
|
field b = x - y // should parse to sub
|
||||||
|
field c = x + - y // should parse to add(neg)
|
||||||
|
field d = x - + y // should parse to sub(pos)
|
||||||
|
|
||||||
|
u8 e = -t // should parse to neg
|
||||||
|
u8 f = z - t // should parse to sub
|
||||||
|
u8 g = z + - t // should parse to add(neg)
|
||||||
|
u8 h = z - + t // should parse to sub(pos)
|
||||||
|
|
||||||
|
assert(-0x00 == 0x00)
|
||||||
|
assert(-0f == 0)
|
||||||
|
|
||||||
|
return [a, b, c, d], [e, f, g, h]
|
|
@ -13,6 +13,9 @@ def main():
|
||||||
|
|
||||||
assert(0x00 ^ 0x00 == 0x00)
|
assert(0x00 ^ 0x00 == 0x00)
|
||||||
|
|
||||||
|
assert(0 - 2 ** 2 == -4)
|
||||||
|
assert(-2**2 == -4)
|
||||||
|
|
||||||
//check if all statements have evalutated to true
|
//check if all statements have evalutated to true
|
||||||
assert(a * b * c * d * e * f == 1)
|
assert(a * b * c * d * e * f == 1)
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/add.zok",
|
|
||||||
"max_constraint_count": 29,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0xff", "0x01"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0x00"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0x00", "0x01"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0x01"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0xff", "0xff"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0xfe"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/and.zok",
|
|
||||||
"max_constraint_count": 27,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0xff", "0xff"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0xff"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0xff", "0x00"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0x00"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0x23", "0x34"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0x20"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/div.zok",
|
|
||||||
"max_constraint_count": 43,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["255", "1"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["255"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["42", "10"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["4"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
def main(u8 x, u8 y) -> u8:
|
|
||||||
assert(0x02 / 0x02 == 0x01)
|
|
||||||
assert(0x04 / 0x02 == 0x02)
|
|
||||||
assert(0x05 / 0x02 == 0x02)
|
|
||||||
assert(0xff / 0x03 == 0x55)
|
|
||||||
return x / y
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/div_rem.zok",
|
|
||||||
"max_constraint_count": 43,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["255", "1"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["255", "0"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["42", "10"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["4", "2"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
def main(u8 n, u8 d) -> (u8, u8):
|
|
||||||
return n / d, n % d
|
|
|
@ -1,34 +1,34 @@
|
||||||
{
|
{
|
||||||
"entry_point": "./tests/tests/uint/from_to_bits.zok",
|
"entry_point": "./tests/tests/uint/from_to_bits.zok",
|
||||||
"max_constraint_count": 34,
|
"max_constraint_count": 128,
|
||||||
"tests": [
|
"tests": [
|
||||||
{
|
{
|
||||||
"input": {
|
"input": {
|
||||||
"values": ["0x00000000", "0x0000", "0x00"]
|
"values": ["0x0000000000000000", "0x00000000", "0x0000", "0x00"]
|
||||||
},
|
},
|
||||||
"output": {
|
"output": {
|
||||||
"Ok": {
|
"Ok": {
|
||||||
"values": ["0x00000000", "0x0000", "0x00"]
|
"values": ["0x0000000000000000", "0x00000000", "0x0000", "0x00"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": {
|
"input": {
|
||||||
"values": ["0xffffffff", "0xffff", "0xff"]
|
"values": ["0xffffffffffffffff", "0xffffffff", "0xffff", "0xff"]
|
||||||
},
|
},
|
||||||
"output": {
|
"output": {
|
||||||
"Ok": {
|
"Ok": {
|
||||||
"values": ["0xffffffff", "0xffff", "0xff"]
|
"values": ["0xffffffffffffffff", "0xffffffff", "0xffff", "0xff"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": {
|
"input": {
|
||||||
"values": ["0x12345678", "0x1234", "0x12"]
|
"values": ["0x1234567812345678", "0x12345678", "0x1234", "0x12"]
|
||||||
},
|
},
|
||||||
"output": {
|
"output": {
|
||||||
"Ok": {
|
"Ok": {
|
||||||
"values": ["0x12345678", "0x1234", "0x12"]
|
"values": ["0x1234567812345678", "0x12345678", "0x1234", "0x12"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import "EMBED/u64_to_bits" as to_bits_64
|
||||||
|
import "EMBED/u64_from_bits" as from_bits_64
|
||||||
import "EMBED/u32_to_bits" as to_bits_32
|
import "EMBED/u32_to_bits" as to_bits_32
|
||||||
import "EMBED/u32_from_bits" as from_bits_32
|
import "EMBED/u32_from_bits" as from_bits_32
|
||||||
import "EMBED/u16_to_bits" as to_bits_16
|
import "EMBED/u16_to_bits" as to_bits_16
|
||||||
|
@ -5,8 +7,9 @@ import "EMBED/u16_from_bits" as from_bits_16
|
||||||
import "EMBED/u8_to_bits" as to_bits_8
|
import "EMBED/u8_to_bits" as to_bits_8
|
||||||
import "EMBED/u8_from_bits" as from_bits_8
|
import "EMBED/u8_from_bits" as from_bits_8
|
||||||
|
|
||||||
def main(u32 e, u16 f, u8 g) -> (u32, u16, u8):
|
def main(u64 d, u32 e, u16 f, u8 g) -> (u64, u32, u16, u8):
|
||||||
|
bool[64] d_bits = to_bits_64(d)
|
||||||
bool[32] e_bits = to_bits_32(e)
|
bool[32] e_bits = to_bits_32(e)
|
||||||
bool[16] f_bits = to_bits_16(f)
|
bool[16] f_bits = to_bits_16(f)
|
||||||
bool[8] g_bits = to_bits_8(g)
|
bool[8] g_bits = to_bits_8(g)
|
||||||
return from_bits_32(e_bits), from_bits_16(f_bits), from_bits_8(g_bits)
|
return from_bits_64(d_bits), from_bits_32(e_bits), from_bits_16(f_bits), from_bits_8(g_bits)
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/mul.zok",
|
|
||||||
"max_constraint_count": 37,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["2", "2"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["4"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/or.zok",
|
|
||||||
"max_constraint_count": 27,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0xff", "0xff"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0xff"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0xff", "0x00"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0xff"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0x23", "0x34"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0x37"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/rem.zok",
|
|
||||||
"max_constraint_count": 43,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["255", "1"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["42", "10"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["2"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
def main(u8 x, u8 y) -> u8:
|
|
||||||
assert(0x02 % 0x02 == 0x00)
|
|
||||||
assert(0x04 % 0x02 == 0x00)
|
|
||||||
assert(0x05 % 0x02 == 0x01)
|
|
||||||
assert(0xff % 0x03 == 0x00)
|
|
||||||
assert(0xff % 0x01 == 0x00)
|
|
||||||
return x % y
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
"entry_point": "./tests/tests/uint/shift.zok",
|
|
||||||
"max_constraint_count": 34,
|
|
||||||
"tests": [
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0x12345678"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0x01234567"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"input": {
|
|
||||||
"values": ["0x01234567"]
|
|
||||||
},
|
|
||||||
"output": {
|
|
||||||
"Ok": {
|
|
||||||
"values": ["0x00123456"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
36
zokrates_core_test/tests/tests/uint/u16/add.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/add.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/add.zok",
|
||||||
|
"max_constraint_count": 53,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0x0001"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1000", "0x1000"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x2000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0xffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xfffe"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/add.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/add.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> u16:
|
||||||
|
return a + b
|
36
zokrates_core_test/tests/tests/uint/u16/and.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/and.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/and.zok",
|
||||||
|
"max_constraint_count": 51,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0xffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0x0000"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1234", "0x5678"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x1230"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/and.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/and.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> u16:
|
||||||
|
return a & b
|
36
zokrates_core_test/tests/tests/uint/u16/div.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/div.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/div.zok",
|
||||||
|
"max_constraint_count": 88,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1000", "0x1000"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0001"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1000", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0800"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1001", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0800"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/div.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/div.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 x, u16 y) -> u16:
|
||||||
|
return x / y
|
26
zokrates_core_test/tests/tests/uint/u16/eq.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/eq.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/eq.zok",
|
||||||
|
"max_constraint_count": 37,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0004"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/eq.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/eq.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> bool:
|
||||||
|
return a == b
|
26
zokrates_core_test/tests/tests/uint/u16/gt.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/gt.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/gt.zok",
|
||||||
|
"max_constraint_count": 697,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0004", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/gt.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/gt.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> bool:
|
||||||
|
return a > b
|
36
zokrates_core_test/tests/tests/uint/u16/gte.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/gte.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/gte.zok",
|
||||||
|
"max_constraint_count": 699,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0004", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0001", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/gte.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/gte.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> bool:
|
||||||
|
return a >= b
|
26
zokrates_core_test/tests/tests/uint/u16/lshift.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/lshift.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/lshift.zok",
|
||||||
|
"max_constraint_count": 18,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0004"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xfffe"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/lshift.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/lshift.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 x) -> u16:
|
||||||
|
return x << 1
|
26
zokrates_core_test/tests/tests/uint/u16/lt.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/lt.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/lt.zok",
|
||||||
|
"max_constraint_count": 697,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0004"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/lt.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/lt.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> bool:
|
||||||
|
return a < b
|
36
zokrates_core_test/tests/tests/uint/u16/lte.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/lte.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/lte.zok",
|
||||||
|
"max_constraint_count": 699,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0004"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0003", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/lte.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/lte.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> bool:
|
||||||
|
return a <= b
|
26
zokrates_core_test/tests/tests/uint/u16/mul.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/mul.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/mul.zok",
|
||||||
|
"max_constraint_count": 69,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0008"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0010"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xfffe"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/mul.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/mul.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> u16:
|
||||||
|
return a * b
|
26
zokrates_core_test/tests/tests/uint/u16/neq.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/neq.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/neq.zok",
|
||||||
|
"max_constraint_count": 37,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0004"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/neq.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/neq.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> bool:
|
||||||
|
return a != b
|
26
zokrates_core_test/tests/tests/uint/u16/not.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/not.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/not.zok",
|
||||||
|
"max_constraint_count": 18,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0001"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xfffe"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/not.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/not.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a) -> u16:
|
||||||
|
return !a
|
36
zokrates_core_test/tests/tests/uint/u16/or.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/or.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/or.zok",
|
||||||
|
"max_constraint_count": 51,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0xffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0x0000"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1234", "0x5678"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x567c"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/or.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/or.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 x, u16 y) -> u16:
|
||||||
|
return x | y
|
36
zokrates_core_test/tests/tests/uint/u16/rem.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/rem.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/rem.zok",
|
||||||
|
"max_constraint_count": 88,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0002", "0x0004"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0002"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0x0001"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1001", "0x0002"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0001"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/rem.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/rem.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 x, u16 y) -> u16:
|
||||||
|
return x % y
|
26
zokrates_core_test/tests/tests/uint/u16/rshift.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/rshift.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/rshift.zok",
|
||||||
|
"max_constraint_count": 18,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1000"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0800"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x7fff"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/rshift.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/rshift.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 x) -> u16:
|
||||||
|
return x >> 1
|
26
zokrates_core_test/tests/tests/uint/u16/sub.json
Normal file
26
zokrates_core_test/tests/tests/uint/u16/sub.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/sub.zok",
|
||||||
|
"max_constraint_count": 53,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0x0001"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xfffe"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x0000", "0x0001"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/sub.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/sub.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> u16:
|
||||||
|
return a - b
|
36
zokrates_core_test/tests/tests/uint/u16/xor.json
Normal file
36
zokrates_core_test/tests/tests/uint/u16/xor.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u16/xor.zok",
|
||||||
|
"max_constraint_count": 51,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0xffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x0000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffff", "0x0000"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xffff"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x1234", "0x5678"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x444c"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
zokrates_core_test/tests/tests/uint/u16/xor.zok
Normal file
2
zokrates_core_test/tests/tests/uint/u16/xor.zok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
def main(u16 a, u16 b) -> u16:
|
||||||
|
return a ^ b
|
36
zokrates_core_test/tests/tests/uint/u32/add.json
Normal file
36
zokrates_core_test/tests/tests/uint/u32/add.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"entry_point": "./tests/tests/uint/u32/add.zok",
|
||||||
|
"max_constraint_count": 101,
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffffffff", "0x00000001"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x00000000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0x10000000", "0x10000000"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0x20000000"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"input": {
|
||||||
|
"values": ["0xffffffff", "0xffffffff"]
|
||||||
|
},
|
||||||
|
"output": {
|
||||||
|
"Ok": {
|
||||||
|
"values": ["0xfffffffe"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue