merge dev, fix conflicts
This commit is contained in:
commit
36362101f4
112 changed files with 8958 additions and 2656 deletions
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file.
|
|||
## [Unreleased]
|
||||
https://github.com/Zokrates/ZoKrates/compare/latest...develop
|
||||
|
||||
## [0.7.8] - 2021-11-23
|
||||
|
||||
### Release
|
||||
- https://github.com/Zokrates/ZoKrates/releases/tag/0.7.8 <!-- markdown-link-check-disable-line -->
|
||||
|
||||
### Changes
|
||||
- Fix reduction of constants (#1050, @schaeff)
|
||||
- Implement type aliasing (#982, @dark64)
|
||||
- Remove confusing returns (#1037, @schaeff)
|
||||
- Reduce cost of dynamic comparison (#1025, @schaeff)
|
||||
- Fix false positives and false negatives in struct generic inference (#1016, @schaeff)
|
||||
- Make field to uint casts truncate values bigger than uint max (#997, @dark64)
|
||||
- Add Marlin proving scheme to the backend table in the book (#1034, @schaeff)
|
||||
- Fail at compile time when complex types are known not to be equal (#1032, @schaeff)
|
||||
- Allow more postfix expressions, exit gracefully when trying to call anything else than an identifier (#1030, @schaeff)
|
||||
- Add optional message to assert statement (#1012, @dark64)
|
||||
- Introduce ternary operator (#1010, @dark64)
|
||||
|
||||
## [0.7.7] - 2021-10-04
|
||||
|
||||
### Release
|
||||
|
|
76
Cargo.lock
generated
76
Cargo.lock
generated
|
@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.5"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "991984e3fd003e7ba02eb724f87a0f997b78677c46c0e91f8424ad7394c9886a"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom 0.2.3",
|
||||
"once_cell",
|
||||
|
@ -286,7 +286,7 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ac3d78c750b01f5df5b2e76d106ed31487a93b3868f14a7f0eb3a74f45e1d8a"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
@ -354,9 +354,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
|||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.61"
|
||||
version = "0.3.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01"
|
||||
checksum = "091bcdf2da9950f96aa522681ce805e6857f6ca8df73833d35736ab2dc78e152"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
|
@ -495,9 +495,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.1"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
|
@ -756,7 +756,7 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
@ -870,7 +870,7 @@ version = "0.1.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"synstructure",
|
||||
|
@ -914,7 +914,7 @@ dependencies = [
|
|||
"num-bigint 0.2.6",
|
||||
"num-integer",
|
||||
"num-traits 0.2.14",
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
@ -1200,9 +1200,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.103"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
|
@ -1387,9 +1387,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.26.2"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"
|
||||
checksum = "c821014c18301591b89b843809ef953af9e3df0496c232d5c0611b0a52aac363"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -1497,7 +1497,7 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
|||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
@ -1549,9 +1549,9 @@ checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
|
|||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||
checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
|
@ -1576,9 +1576,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.29"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
@ -1609,7 +1609,7 @@ version = "1.0.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1940,7 +1940,7 @@ version = "1.0.130"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
@ -2019,9 +2019,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
|
||||
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
|
@ -2058,7 +2058,7 @@ version = "1.0.80"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
@ -2069,7 +2069,7 @@ version = "0.12.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"unicode-xid 0.2.2",
|
||||
|
@ -2178,7 +2178,7 @@ version = "0.1.18"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
@ -2339,7 +2339,7 @@ dependencies = [
|
|||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"wasm-bindgen-shared",
|
||||
|
@ -2373,7 +2373,7 @@ version = "0.2.78"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"wasm-bindgen-backend",
|
||||
|
@ -2406,7 +2406,7 @@ version = "0.3.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6006f79628dfeb96a86d4db51fbf1344cd7fd8408f06fc9aa3c84913a4789688"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
]
|
||||
|
||||
|
@ -2466,7 +2466,7 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.29",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"synstructure",
|
||||
|
@ -2485,7 +2485,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_cli"
|
||||
version = "0.7.7"
|
||||
version = "0.7.8"
|
||||
dependencies = [
|
||||
"assert_cli",
|
||||
"bincode",
|
||||
|
@ -2517,7 +2517,7 @@ version = "0.1.0"
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_core"
|
||||
version = "0.6.7"
|
||||
version = "0.6.8"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-bn254",
|
||||
|
@ -2565,7 +2565,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_core_test"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"zokrates_test",
|
||||
"zokrates_test_derive",
|
||||
|
@ -2573,7 +2573,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_embed"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-bw6-761",
|
||||
|
@ -2621,7 +2621,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_parser"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"glob 0.2.11",
|
||||
"pest",
|
||||
|
@ -2630,7 +2630,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_pest_ast"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
dependencies = [
|
||||
"from-pest",
|
||||
"glob 0.2.11",
|
||||
|
@ -2642,7 +2642,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_stdlib"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"fs_extra",
|
||||
"zokrates_test",
|
||||
|
@ -2651,7 +2651,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_test"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Introduce ternary operator
|
|
@ -1 +0,0 @@
|
|||
Add optional message to assert statement
|
|
@ -1 +0,0 @@
|
|||
Allow more postfix expressions, exit gracefully when trying to call anything else than an identifier
|
|
@ -1 +0,0 @@
|
|||
Fail at compile time when complex types are known not to be equal
|
|
@ -1 +0,0 @@
|
|||
Add Marlin proving scheme to the backend table in the book
|
|
@ -1 +0,0 @@
|
|||
Make field to uint casts truncate values bigger than uint max
|
|
@ -413,11 +413,8 @@ mod tests {
|
|||
fn array() {
|
||||
let s = "[[true, false]]";
|
||||
assert_eq!(
|
||||
parse_strict::<Bn128Field>(
|
||||
s,
|
||||
vec![ConcreteType::array((ConcreteType::Boolean, 2usize))]
|
||||
)
|
||||
.unwrap(),
|
||||
parse_strict::<Bn128Field>(s, vec![ConcreteType::array((ConcreteType::Boolean, 2u32))])
|
||||
.unwrap(),
|
||||
Values(vec![Value::Array(vec![
|
||||
Value::Boolean(true),
|
||||
Value::Boolean(false)
|
||||
|
|
|
@ -2,26 +2,26 @@
|
|||
|
||||
The following table lists the precedence and associativity of all operators. Operators are listed top to bottom, in ascending precedence. Operators in the same cell have the same precedence. Operators are binary, unless the syntax is provided.
|
||||
|
||||
| Operator | Description | `field` | `u8/u16` `u32/u64` | `bool` | Associativity | Remarks |
|
||||
|----------------------------|------------------------------------------------------------|------------------------------|-------------------------------|-----------------------------|---------------|---------|
|
||||
| `**`<br> | Power | ✓ | | | Left | [^1] |
|
||||
| `+x`<br>`-x`<br>`!x`<br> | Positive<br>Negative<br>Negation<br> | ✓<br>✓<br> | ✓<br>✓<br> | <br> <br>✓ | Right | |
|
||||
| `*`<br>`/`<br>`%`<br> | Multiplication<br> Division<br> Remainder<br> | ✓<br>✓<br> | ✓<br>✓<br>✓ | <br> <br> | Left | |
|
||||
| `+`<br>`-`<br> | Addition<br> Subtraction<br> | ✓ | ✓ | | Left | |
|
||||
| `<<`<br>`>>`<br> | Left shift<br> Right shift<br> | | ✓ | | Left | [^2] |
|
||||
| `&` | Bitwise AND | | ✓ | | Left | |
|
||||
| <code>|</code> | Bitwise OR | | ✓ | | Left | |
|
||||
| `^` | Bitwise XOR | | ✓ | | Left | |
|
||||
| `>=`<br>`>`<br>`<=`<br>`<` | Greater or equal<br>Greater<br>Lower or equal<br>Lower<br> | ✓ | ✓ | | Left | [^3] |
|
||||
| `!=`<br>`==`<br> | Not Equal<br>Equal<br> | ✓ | ✓ | ✓ | Left | |
|
||||
| `&&` | Boolean AND | | | ✓ | Left | |
|
||||
| <code>||</code> | Boolean OR | | | ✓ | Left | |
|
||||
| `if c then x else y fi` | Conditional expression | ✓ | ✓ | ✓ | Right | [^4] |
|
||||
|
||||
| Operator | Description | `field` | `u8/u16` `u32/u64` | `bool` | Associativity |
|
||||
|----------------------------|------------------------------------------------------------|------------------------------|-------------------------------|-----------------------------|---------------|
|
||||
| `**`<br> | Power | ✓[^1] | | | Left |
|
||||
| `+x`<br>`-x`<br>`!x`<br> | Positive<br>Negative<br>Negation<br> | ✓<br>✓<br> | ✓<br>✓<br>✓ | <br> <br>✓ | Right |
|
||||
| `*`<br>`/`<br>`%`<br> | Multiplication<br> Division<br> Remainder<br> | ✓<br>✓<br> | ✓<br>✓<br>✓ | <br> <br> | Left |
|
||||
| `+`<br>`-`<br> | Addition<br> Subtraction<br> | ✓ | ✓ | | Left |
|
||||
| `<<`<br>`>>`<br> | Left shift<br> Right shift<br> | | ✓[^2] | | Left |
|
||||
| `&` | Bitwise AND | | ✓ | | Left |
|
||||
| <code>|</code> | Bitwise OR | | ✓ | | Left |
|
||||
| `^` | Bitwise XOR | | ✓ | | Left |
|
||||
| `>=`<br>`>`<br>`<=`<br>`<` | Greater or equal<br>Greater<br>Lower or equal<br>Lower<br> | ✓[^3] | ✓ | | Left |
|
||||
| `!=`<br>`==`<br> | Not Equal<br>Equal<br> | ✓ | ✓ | ✓ | Left |
|
||||
| `&&` | Boolean AND | | | ✓ | Left |
|
||||
| <code>||</code> | Boolean OR | | | ✓ | Left |
|
||||
| `c ? x : y`<br><br>`if c then x else y fi` | Conditional expression | ✓ | ✓ | ✓ | Right | |
|
||||
|
||||
[^1]: The exponent must be a compile-time constant of type `u32`
|
||||
|
||||
[^2]: The right operand must be a compile time constant of type `u32`
|
||||
|
||||
[^3]: Both operands are asserted to be strictly lower than the biggest power of 2 lower than `p/2`, unless one of them can be determined to be a compile-time constant
|
||||
|
||||
[^4]: Conditional expression can also be written using a ternary operator: `c ? x : y`
|
||||
[^3]: If neither of the operands can be determined to be a compile-time constant, then we have a restriction: for the check `a < b`, if the field prime `p` is represented on `N` bits, `|a - b|` must fit in `N - 2` bits.
|
||||
Failing to respect this condition will lead to a runtime error.
|
||||
|
|
|
@ -128,6 +128,8 @@ struct Point {
|
|||
}
|
||||
```
|
||||
|
||||
Note that two struct definitions with the same members still introduce two entirely different types. For example, they cannot be compared with each other.
|
||||
|
||||
#### Declaration and Initialization
|
||||
|
||||
Initialization of a variable of a struct type always needs to happen in the same statement as a declaration, unless the struct-typed variable is declared within a function's signature.
|
||||
|
@ -144,3 +146,13 @@ The variables within a struct instance, the so called members, can be accessed t
|
|||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/struct_assign.zok}}
|
||||
```
|
||||
|
||||
### Type aliases
|
||||
|
||||
Type aliases can be defined for any existing type. This can be useful for readability, or to specialize generic types.
|
||||
|
||||
Note that type aliases are just syntactic sugar: in the type system, a type and its alias are exactly equivalent. For example, they can be compared.
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/type_aliases.zok}}
|
||||
```
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_cli"
|
||||
version = "0.7.7"
|
||||
version = "0.7.8"
|
||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>", "Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||
repository = "https://github.com/Zokrates/ZoKrates.git"
|
||||
edition = "2018"
|
||||
|
|
13
zokrates_cli/examples/alias/basic_aliasing.zok
Normal file
13
zokrates_cli/examples/alias/basic_aliasing.zok
Normal file
|
@ -0,0 +1,13 @@
|
|||
type byte = u8
|
||||
type uint32 = u32
|
||||
type UInt32Array<N> = uint32[N]
|
||||
|
||||
type matrix<R, C> = field[R][C]
|
||||
|
||||
def fill<R, C>(field v) -> matrix<R, C>:
|
||||
return [[v; C]; R]
|
||||
|
||||
def main(uint32 a, uint32 b) -> (UInt32Array<2>, matrix<2, 4>):
|
||||
UInt32Array<2> res = [a, b]
|
||||
matrix<2, 4> m = fill(1)
|
||||
return res, m
|
14
zokrates_cli/examples/alias/import_alias.zok
Normal file
14
zokrates_cli/examples/alias/import_alias.zok
Normal file
|
@ -0,0 +1,14 @@
|
|||
from "./basic_aliasing.zok" import matrix
|
||||
from "./struct_aliasing.zok" import Buzz
|
||||
|
||||
const u32 R = 2
|
||||
const u32 C = 4
|
||||
|
||||
type matrix_2x4 = matrix<R, C>
|
||||
|
||||
def buzz<N>() -> Buzz<N>:
|
||||
return Buzz { a: [0; N], b: [0; N] }
|
||||
|
||||
def main(matrix_2x4 m) -> (Buzz<2>, matrix_2x4):
|
||||
Buzz<2> b = buzz::<2>()
|
||||
return b, m
|
15
zokrates_cli/examples/alias/struct_aliasing.zok
Normal file
15
zokrates_cli/examples/alias/struct_aliasing.zok
Normal file
|
@ -0,0 +1,15 @@
|
|||
type FieldArray<N> = field[N]
|
||||
|
||||
struct Foo<A, B> {
|
||||
FieldArray<A> a
|
||||
FieldArray<B> b
|
||||
}
|
||||
|
||||
type Bar = Foo<2, 2>
|
||||
type Buzz<A> = Foo<A, A>
|
||||
|
||||
def main(Bar a) -> Buzz<2>:
|
||||
Bar bar = Bar { a: [1, 2], b: [1, 2] }
|
||||
Buzz<2> buzz = Buzz { a: [1, 2], b: [1, 2] }
|
||||
assert(bar == buzz)
|
||||
return buzz
|
|
@ -1,2 +1,3 @@
|
|||
def main(private field a, field b) -> bool:
|
||||
return a * a == b
|
||||
def main(private field a, field b):
|
||||
assert(a * a == b)
|
||||
return
|
|
@ -1,9 +1,9 @@
|
|||
def foo() -> (field, field):
|
||||
return 21, 42
|
||||
|
||||
def main() -> field:
|
||||
def main():
|
||||
// a is declared here
|
||||
field a = 1
|
||||
// b is declared here
|
||||
a, field b = foo()
|
||||
return 1
|
||||
return
|
11
zokrates_cli/examples/book/type_aliases.zok
Normal file
11
zokrates_cli/examples/book/type_aliases.zok
Normal file
|
@ -0,0 +1,11 @@
|
|||
type MyField = field
|
||||
|
||||
type Rectangle<L, W> = bool[L][W]
|
||||
|
||||
type Square<S> = Rectangle<S, S>
|
||||
|
||||
def main():
|
||||
MyField f = 42
|
||||
Rectangle<2, 2> r = [[true; 2]; 2]
|
||||
Square<2> s = r
|
||||
return
|
|
@ -1,7 +1,7 @@
|
|||
def foo() -> field:
|
||||
return 1
|
||||
|
||||
def main() -> field:
|
||||
def main():
|
||||
field a = 2
|
||||
field a = foo()
|
||||
return 1
|
||||
return
|
|
@ -2,4 +2,4 @@ from "EMBED" import bit_array_le
|
|||
|
||||
// Calling the `bit_array_le` embed on a non-constant second argument should fail at compile-time
|
||||
def main(bool[1] a, bool[1] b) -> bool:
|
||||
return bit_array_le::<1>(a, b)
|
||||
return bit_array_le(a, b)
|
|
@ -1,6 +1,6 @@
|
|||
from "field" import FIELD_SIZE_IN_BITS
|
||||
|
||||
// we can compare numbers up to 2^(pbits - 2) - 1, ie any number which fits in (pbits - 2) bits
|
||||
// we can compare numbers whose difference fits in (pbits - 2) bits
|
||||
// It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one
|
||||
// /!\ should be called with a = 0
|
||||
|
||||
|
@ -8,4 +8,4 @@ def main(field a) -> bool:
|
|||
u32 pbits = FIELD_SIZE_IN_BITS
|
||||
// we added a = 0 to prevent the condition to be evaluated at compile time
|
||||
field maxvalue = a + (2**(pbits - 2) - 1)
|
||||
return a < (maxvalue + 1)
|
||||
return a < maxvalue + 1
|
|
@ -0,0 +1,11 @@
|
|||
from "field" import FIELD_SIZE_IN_BITS
|
||||
|
||||
// we can compare numbers whose difference fits in (pbits - 2) bits
|
||||
// It should not work for the maxvalue = 2^(pbits - 2) - 1 augmented by one
|
||||
// /!\ should be called with a = 0
|
||||
|
||||
def main(field a) -> bool:
|
||||
u32 pbits = FIELD_SIZE_IN_BITS
|
||||
// we added a = 0 to prevent the condition to be evaluated at compile time
|
||||
field maxvalue = a + (2**(pbits - 2) - 1)
|
||||
return maxvalue + 1 < a
|
|
@ -8,6 +8,9 @@
|
|||
// --------------------------
|
||||
// | c21 | c22 || d21 | d22 |
|
||||
|
||||
type Grid<N> = field[N][N]
|
||||
const field[4] PRIMES = [2, 3, 5, 7]
|
||||
|
||||
// We encode values in the following way:
|
||||
// 1 -> 2
|
||||
// 2 -> 3
|
||||
|
@ -18,16 +21,22 @@
|
|||
// assumption: `a, b, c, d` are all in `{ 2, 3, 5, 7 }`
|
||||
def checkNoDuplicates(field a, field b, field c, field d) -> bool:
|
||||
// as `{ 2, 3, 5, 7 }` are primes, the set `{ a, b, c, d }` is equal to the set `{ 2, 3, 5, 7}` if and only if the products match
|
||||
return a * b * c * d == 2 * 3 * 5 * 7
|
||||
return a * b * c * d == PRIMES[0] * PRIMES[1] * PRIMES[2] * PRIMES[3]
|
||||
|
||||
// returns `0` if and only if `x` in `{ 2, 3, 5, 7 }`
|
||||
// returns true if and only if `x` is one of the `4` primes
|
||||
def validateInput(field x) -> bool:
|
||||
return (x-2) * (x-3) * (x-5) * (x-7) == 0
|
||||
field res = 1
|
||||
|
||||
for u32 i in 0..4 do
|
||||
res = res * (x - PRIMES[i])
|
||||
endfor
|
||||
|
||||
return res == 0
|
||||
|
||||
// variables naming: box'row''column'
|
||||
def main(field a21, field b11, field b22, field c11, field c22, field d21, private field a11, private field a12, private field a22, private field b12, private field b21, private field c12, private field c21, private field d11, private field d12, private field d22) -> bool:
|
||||
|
||||
field[4][4] a = [[a11, a12, b11, b12], [a21, a22, b21, b22], [c11, c12, d11, d12], [c21, c22, d21, d22]]
|
||||
Grid<4> a = [[a11, a12, b11, b12], [a21, a22, b21, b22], [c11, c12, d11, d12], [c21, c22, d21, d22]]
|
||||
|
||||
bool res = true
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_core"
|
||||
version = "0.6.7"
|
||||
version = "0.6.8"
|
||||
edition = "2018"
|
||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>"]
|
||||
repository = "https://github.com/Zokrates/ZoKrates"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::absy;
|
||||
|
||||
use crate::absy::SymbolDefinition;
|
||||
use num_bigint::BigUint;
|
||||
use std::path::Path;
|
||||
use zokrates_pest_ast as pest;
|
||||
|
@ -10,6 +11,7 @@ impl<'ast> From<pest::File<'ast>> for absy::Module<'ast> {
|
|||
pest::SymbolDeclaration::Import(i) => import_directive_to_symbol_vec(i),
|
||||
pest::SymbolDeclaration::Constant(c) => vec![c.into()],
|
||||
pest::SymbolDeclaration::Struct(s) => vec![s.into()],
|
||||
pest::SymbolDeclaration::Type(t) => vec![t.into()],
|
||||
pest::SymbolDeclaration::Function(f) => vec![f.into()],
|
||||
}))
|
||||
}
|
||||
|
@ -135,6 +137,31 @@ impl<'ast> From<pest::ConstantDefinition<'ast>> for absy::SymbolDeclarationNode<
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<pest::TypeDefinition<'ast>> for absy::SymbolDeclarationNode<'ast> {
|
||||
fn from(definition: pest::TypeDefinition<'ast>) -> absy::SymbolDeclarationNode<'ast> {
|
||||
use crate::absy::NodeValue;
|
||||
|
||||
let span = definition.span;
|
||||
let id = definition.id.span.as_str();
|
||||
|
||||
let ty = absy::TypeDefinition {
|
||||
generics: definition
|
||||
.generics
|
||||
.into_iter()
|
||||
.map(absy::ConstantGenericNode::from)
|
||||
.collect(),
|
||||
ty: definition.ty.into(),
|
||||
}
|
||||
.span(span.clone());
|
||||
|
||||
absy::SymbolDeclaration {
|
||||
id,
|
||||
symbol: absy::Symbol::Here(SymbolDefinition::Type(ty)),
|
||||
}
|
||||
.span(span)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> From<pest::FunctionDefinition<'ast>> for absy::SymbolDeclarationNode<'ast> {
|
||||
fn from(function: pest::FunctionDefinition<'ast>) -> absy::SymbolDeclarationNode<'ast> {
|
||||
use crate::absy::NodeValue;
|
||||
|
|
|
@ -133,6 +133,7 @@ pub enum SymbolDefinition<'ast> {
|
|||
Import(CanonicalImportNode<'ast>),
|
||||
Struct(StructDefinitionNode<'ast>),
|
||||
Constant(ConstantDefinitionNode<'ast>),
|
||||
Type(TypeDefinitionNode<'ast>),
|
||||
Function(FunctionNode<'ast>),
|
||||
}
|
||||
|
||||
|
@ -153,12 +154,28 @@ impl<'ast> fmt::Display for SymbolDeclaration<'ast> {
|
|||
i.value.source.display(),
|
||||
i.value.id
|
||||
),
|
||||
SymbolDefinition::Struct(ref t) => write!(f, "struct {}{}", self.id, t),
|
||||
SymbolDefinition::Struct(ref s) => write!(f, "struct {}{}", self.id, s),
|
||||
SymbolDefinition::Constant(ref c) => write!(
|
||||
f,
|
||||
"const {} {} = {}",
|
||||
c.value.ty, self.id, c.value.expression
|
||||
),
|
||||
SymbolDefinition::Type(ref t) => {
|
||||
write!(f, "type {}", self.id)?;
|
||||
if !t.value.generics.is_empty() {
|
||||
write!(
|
||||
f,
|
||||
"<{}>",
|
||||
t.value
|
||||
.generics
|
||||
.iter()
|
||||
.map(|g| g.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)?;
|
||||
}
|
||||
write!(f, " = {}", t.value.ty)
|
||||
}
|
||||
SymbolDefinition::Function(ref func) => {
|
||||
write!(f, "def {}{}", self.id, func)
|
||||
}
|
||||
|
@ -205,15 +222,18 @@ pub struct StructDefinition<'ast> {
|
|||
|
||||
impl<'ast> fmt::Display for StructDefinition<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(
|
||||
f,
|
||||
"<{}> {{",
|
||||
self.generics
|
||||
.iter()
|
||||
.map(|g| g.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
)?;
|
||||
if !self.generics.is_empty() {
|
||||
write!(
|
||||
f,
|
||||
"<{}> ",
|
||||
self.generics
|
||||
.iter()
|
||||
.map(|g| g.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)?;
|
||||
}
|
||||
writeln!(f, "{{")?;
|
||||
for field in &self.fields {
|
||||
writeln!(f, " {}", field)?;
|
||||
}
|
||||
|
@ -248,7 +268,34 @@ pub type ConstantDefinitionNode<'ast> = Node<ConstantDefinition<'ast>>;
|
|||
|
||||
impl<'ast> fmt::Display for ConstantDefinition<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "const {}({})", self.ty, self.expression)
|
||||
write!(f, "const {} _ = {}", self.ty, self.expression)
|
||||
}
|
||||
}
|
||||
|
||||
/// A type definition
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TypeDefinition<'ast> {
|
||||
pub generics: Vec<ConstantGenericNode<'ast>>,
|
||||
pub ty: UnresolvedTypeNode<'ast>,
|
||||
}
|
||||
|
||||
pub type TypeDefinitionNode<'ast> = Node<TypeDefinition<'ast>>;
|
||||
|
||||
impl<'ast> fmt::Display for TypeDefinition<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "type _")?;
|
||||
if !self.generics.is_empty() {
|
||||
write!(
|
||||
f,
|
||||
"<{}>",
|
||||
self.generics
|
||||
.iter()
|
||||
.map(|g| g.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)?;
|
||||
}
|
||||
write!(f, " = {}", self.ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ impl<'ast> NodeValue for UnresolvedType<'ast> {}
|
|||
impl<'ast> NodeValue for StructDefinition<'ast> {}
|
||||
impl<'ast> NodeValue for StructDefinitionField<'ast> {}
|
||||
impl<'ast> NodeValue for ConstantDefinition<'ast> {}
|
||||
impl<'ast> NodeValue for TypeDefinition<'ast> {}
|
||||
impl<'ast> NodeValue for Function<'ast> {}
|
||||
impl<'ast> NodeValue for Module<'ast> {}
|
||||
impl<'ast> NodeValue for CanonicalImport<'ast> {}
|
||||
|
|
|
@ -196,14 +196,17 @@ pub fn compile<T: Field, E: Into<imports::Error>>(
|
|||
// flatten input program
|
||||
log::debug!("Flatten");
|
||||
let program_flattened = Flattener::flatten(typed_ast, config);
|
||||
log::trace!("\n{}", program_flattened);
|
||||
|
||||
// constant propagation after call resolution
|
||||
log::debug!("Propagate flat program");
|
||||
let program_flattened = program_flattened.propagate();
|
||||
log::trace!("\n{}", program_flattened);
|
||||
|
||||
// convert to ir
|
||||
log::debug!("Convert to IR");
|
||||
let ir_prog = ir::Prog::from(program_flattened);
|
||||
log::trace!("\n{}", ir_prog);
|
||||
|
||||
// optimize
|
||||
log::debug!("Optimise IR");
|
||||
|
|
|
@ -177,128 +177,105 @@ impl FlatEmbed {
|
|||
match self {
|
||||
FlatEmbed::BitArrayLe => DeclarationSignature::new()
|
||||
.generics(vec![Some(DeclarationConstant::Generic(
|
||||
GenericIdentifier {
|
||||
name: "N",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("N").with_index(0),
|
||||
))])
|
||||
.inputs(vec![
|
||||
DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
GenericIdentifier {
|
||||
name: "N",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("N").with_index(0),
|
||||
)),
|
||||
DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
GenericIdentifier {
|
||||
name: "N",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("N").with_index(0),
|
||||
)),
|
||||
])
|
||||
.outputs(vec![DeclarationType::Boolean]),
|
||||
FlatEmbed::Unpack => DeclarationSignature::new()
|
||||
.generics(vec![Some(DeclarationConstant::Generic(
|
||||
GenericIdentifier {
|
||||
name: "N",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("N").with_index(0),
|
||||
))])
|
||||
.inputs(vec![DeclarationType::FieldElement])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
GenericIdentifier {
|
||||
name: "N",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("N").with_index(0),
|
||||
))]),
|
||||
FlatEmbed::U8ToBits => DeclarationSignature::new()
|
||||
.inputs(vec![DeclarationType::uint(8)])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
8usize,
|
||||
8u32,
|
||||
))]),
|
||||
FlatEmbed::U16ToBits => DeclarationSignature::new()
|
||||
.inputs(vec![DeclarationType::uint(16)])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
16usize,
|
||||
16u32,
|
||||
))]),
|
||||
FlatEmbed::U32ToBits => DeclarationSignature::new()
|
||||
.inputs(vec![DeclarationType::uint(32)])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
32usize,
|
||||
32u32,
|
||||
))]),
|
||||
FlatEmbed::U64ToBits => DeclarationSignature::new()
|
||||
.inputs(vec![DeclarationType::uint(64)])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
64usize,
|
||||
64u32,
|
||||
))]),
|
||||
FlatEmbed::U8FromBits => DeclarationSignature::new()
|
||||
.outputs(vec![DeclarationType::uint(8)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
8usize,
|
||||
8u32,
|
||||
))]),
|
||||
FlatEmbed::U16FromBits => DeclarationSignature::new()
|
||||
.outputs(vec![DeclarationType::uint(16)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
16usize,
|
||||
16u32,
|
||||
))]),
|
||||
FlatEmbed::U32FromBits => DeclarationSignature::new()
|
||||
.outputs(vec![DeclarationType::uint(32)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
32usize,
|
||||
32u32,
|
||||
))]),
|
||||
FlatEmbed::U64FromBits => DeclarationSignature::new()
|
||||
.outputs(vec![DeclarationType::uint(64)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
64usize,
|
||||
64u32,
|
||||
))]),
|
||||
#[cfg(feature = "bellman")]
|
||||
FlatEmbed::Sha256Round => DeclarationSignature::new()
|
||||
.inputs(vec![
|
||||
DeclarationType::array((DeclarationType::Boolean, 512usize)),
|
||||
DeclarationType::array((DeclarationType::Boolean, 256usize)),
|
||||
DeclarationType::array((DeclarationType::Boolean, 512u32)),
|
||||
DeclarationType::array((DeclarationType::Boolean, 256u32)),
|
||||
])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::Boolean,
|
||||
256usize,
|
||||
256u32,
|
||||
))]),
|
||||
#[cfg(feature = "ark")]
|
||||
FlatEmbed::SnarkVerifyBls12377 => DeclarationSignature::new()
|
||||
.generics(vec![
|
||||
Some(DeclarationConstant::Generic(GenericIdentifier {
|
||||
name: "N",
|
||||
index: 0,
|
||||
})),
|
||||
Some(DeclarationConstant::Generic(GenericIdentifier {
|
||||
name: "V",
|
||||
index: 1,
|
||||
})),
|
||||
Some(DeclarationConstant::Generic(
|
||||
GenericIdentifier::with_name("N").with_index(0),
|
||||
)),
|
||||
Some(DeclarationConstant::Generic(
|
||||
GenericIdentifier::with_name("V").with_index(1),
|
||||
)),
|
||||
])
|
||||
.inputs(vec![
|
||||
DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier {
|
||||
name: "N",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("N").with_index(0),
|
||||
)), // inputs
|
||||
DeclarationType::array((DeclarationType::FieldElement, 8usize)), // proof
|
||||
DeclarationType::array((DeclarationType::FieldElement, 8u32)), // proof
|
||||
DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier {
|
||||
name: "V",
|
||||
index: 1,
|
||||
},
|
||||
GenericIdentifier::with_name("V").with_index(1),
|
||||
)), // 18 + (2 * n) // vk
|
||||
])
|
||||
.outputs(vec![DeclarationType::Boolean]),
|
||||
|
|
|
@ -37,6 +37,7 @@ pub enum RuntimeError {
|
|||
LtSum,
|
||||
LtFinalBitness,
|
||||
LtFinalSum,
|
||||
LtSymetric,
|
||||
Or,
|
||||
Xor,
|
||||
Inverse,
|
||||
|
@ -81,6 +82,7 @@ impl fmt::Display for RuntimeError {
|
|||
LtSum => "Sum check failed in Lt check",
|
||||
LtFinalBitness => "Bitness check failed in final Lt check",
|
||||
LtFinalSum => "Sum check failed in final Lt check",
|
||||
LtSymetric => "Symetrical check failed in Lt check",
|
||||
Or => "Or check failed",
|
||||
Xor => "Xor check failed",
|
||||
Inverse => "Division by zero",
|
||||
|
|
|
@ -641,6 +641,103 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
)
|
||||
}
|
||||
|
||||
fn lt_check(
|
||||
&mut self,
|
||||
statements_flattened: &mut FlatStatements<T>,
|
||||
lhs_flattened: FlatExpression<T>,
|
||||
rhs_flattened: FlatExpression<T>,
|
||||
bit_width: usize,
|
||||
) -> FlatExpression<T> {
|
||||
match (lhs_flattened, rhs_flattened) {
|
||||
(x, FlatExpression::Number(constant)) => {
|
||||
self.constant_lt_check(statements_flattened, x, constant)
|
||||
}
|
||||
// (c < x <= p - 1) <=> (0 <= p - 1 - x < p - 1 - c)
|
||||
(FlatExpression::Number(constant), x) => self.constant_lt_check(
|
||||
statements_flattened,
|
||||
FlatExpression::Sub(box T::max_value().into(), box x),
|
||||
T::max_value() - constant,
|
||||
),
|
||||
(lhs_flattened, rhs_flattened) => {
|
||||
let lhs_id = self.define(lhs_flattened, statements_flattened);
|
||||
let rhs_id = self.define(rhs_flattened, statements_flattened);
|
||||
|
||||
// shifted_sub := 2**safe_width + lhs - rhs
|
||||
let shifted_sub = FlatExpression::Add(
|
||||
box FlatExpression::Number(T::from(2).pow(bit_width)),
|
||||
box FlatExpression::Sub(
|
||||
box FlatExpression::Identifier(lhs_id),
|
||||
box FlatExpression::Identifier(rhs_id),
|
||||
),
|
||||
);
|
||||
|
||||
let sub_width = bit_width + 1;
|
||||
|
||||
// define variables for the bits
|
||||
let shifted_sub_bits_be: Vec<FlatVariable> =
|
||||
(0..sub_width).map(|_| self.use_sym()).collect();
|
||||
|
||||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(FlatDirective::new(
|
||||
shifted_sub_bits_be.clone(),
|
||||
Solver::bits(sub_width),
|
||||
vec![shifted_sub.clone()],
|
||||
)));
|
||||
|
||||
// bitness checks
|
||||
for bit in shifted_sub_bits_be.iter() {
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(*bit),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Identifier(*bit),
|
||||
),
|
||||
RuntimeError::LtFinalBitness,
|
||||
));
|
||||
}
|
||||
|
||||
// sum(sym_b{i} * 2**i)
|
||||
let mut expr = FlatExpression::Number(T::from(0));
|
||||
|
||||
for (i, bit) in shifted_sub_bits_be.iter().take(sub_width).enumerate() {
|
||||
expr = FlatExpression::Add(
|
||||
box expr,
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Number(T::from(2).pow(sub_width - i - 1)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
shifted_sub,
|
||||
expr,
|
||||
RuntimeError::LtFinalSum,
|
||||
));
|
||||
|
||||
// to make this check symetric, we ban the value `a - b == -2**N`, as the value `a - b == 2**N` is already banned
|
||||
let fail = self.eq_check(
|
||||
statements_flattened,
|
||||
FlatExpression::Sub(
|
||||
box FlatExpression::Identifier(rhs_id),
|
||||
box FlatExpression::Identifier(lhs_id),
|
||||
),
|
||||
FlatExpression::Number(T::from(2).pow(bit_width)),
|
||||
);
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
fail,
|
||||
FlatExpression::Number(T::from(0)),
|
||||
RuntimeError::LtSymetric,
|
||||
));
|
||||
|
||||
FlatExpression::Sub(
|
||||
box FlatExpression::Number(T::one()),
|
||||
box FlatExpression::Identifier(shifted_sub_bits_be[0]),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Flattens a boolean expression
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -673,195 +770,17 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
// Get the bit width to know the size of the binary decompositions for this Field
|
||||
let bit_width = T::get_required_bits();
|
||||
|
||||
// We know from semantic checking that lhs and rhs have the same type
|
||||
// What the expression will flatten to depends on that type
|
||||
let safe_width = bit_width - 2; // dynamic comparison is not complete, it only applies to field elements whose difference is strictly smaller than 2**(bitwidth - 2)
|
||||
|
||||
let lhs_flattened = self.flatten_field_expression(statements_flattened, lhs);
|
||||
let rhs_flattened = self.flatten_field_expression(statements_flattened, rhs);
|
||||
|
||||
match (lhs_flattened, rhs_flattened) {
|
||||
(x, FlatExpression::Number(constant)) => {
|
||||
self.constant_lt_check(statements_flattened, x, constant)
|
||||
}
|
||||
// (c < x <= p - 1) <=> (0 <= p - 1 - x < p - 1 - c)
|
||||
(FlatExpression::Number(constant), x) => self.constant_lt_check(
|
||||
statements_flattened,
|
||||
FlatExpression::Sub(box T::max_value().into(), box x),
|
||||
T::max_value() - constant,
|
||||
),
|
||||
(lhs_flattened, rhs_flattened) => {
|
||||
let safe_width = bit_width - 2; // dynamic comparison is not complete, it only applies to words of width `bit_width - 2`
|
||||
|
||||
// lhs
|
||||
let lhs_id = self.define(lhs_flattened, statements_flattened);
|
||||
|
||||
// check that lhs and rhs are within the right range, i.e., their higher two bits are zero. We use big-endian so they are at positions 0 and 1
|
||||
|
||||
// lhs
|
||||
{
|
||||
// define variables for the bits
|
||||
let lhs_bits_be: Vec<FlatVariable> =
|
||||
(0..safe_width).map(|_| self.use_sym()).collect();
|
||||
|
||||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(
|
||||
FlatDirective::new(
|
||||
lhs_bits_be.clone(),
|
||||
Solver::bits(safe_width),
|
||||
vec![lhs_id],
|
||||
),
|
||||
));
|
||||
|
||||
// bitness checks
|
||||
for bit in lhs_bits_be.iter().take(safe_width) {
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(*bit),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Identifier(*bit),
|
||||
),
|
||||
RuntimeError::LtBitness,
|
||||
));
|
||||
}
|
||||
|
||||
// bit decomposition check
|
||||
let mut lhs_sum = FlatExpression::Number(T::from(0));
|
||||
|
||||
for (i, bit) in lhs_bits_be.iter().take(safe_width).enumerate() {
|
||||
lhs_sum = FlatExpression::Add(
|
||||
box lhs_sum,
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Number(
|
||||
T::from(2).pow(safe_width - i - 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(lhs_id),
|
||||
lhs_sum,
|
||||
RuntimeError::LtSum,
|
||||
));
|
||||
}
|
||||
|
||||
// rhs
|
||||
let rhs_id = self.define(rhs_flattened, statements_flattened);
|
||||
|
||||
// rhs
|
||||
{
|
||||
// define variables for the bits
|
||||
let rhs_bits_be: Vec<FlatVariable> =
|
||||
(0..safe_width).map(|_| self.use_sym()).collect();
|
||||
|
||||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(
|
||||
FlatDirective::new(
|
||||
rhs_bits_be.clone(),
|
||||
Solver::bits(safe_width),
|
||||
vec![rhs_id],
|
||||
),
|
||||
));
|
||||
|
||||
// bitness checks
|
||||
for bit in rhs_bits_be.iter().take(safe_width) {
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(*bit),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Identifier(*bit),
|
||||
),
|
||||
RuntimeError::LtBitness,
|
||||
));
|
||||
}
|
||||
|
||||
// bit decomposition check
|
||||
let mut rhs_sum = FlatExpression::Number(T::from(0));
|
||||
|
||||
for (i, bit) in rhs_bits_be.iter().take(safe_width).enumerate() {
|
||||
rhs_sum = FlatExpression::Add(
|
||||
box rhs_sum,
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Number(
|
||||
T::from(2).pow(safe_width - i - 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(rhs_id),
|
||||
rhs_sum,
|
||||
RuntimeError::LtSum,
|
||||
));
|
||||
}
|
||||
|
||||
// sym := (lhs * 2) - (rhs * 2)
|
||||
let subtraction_result = FlatExpression::Sub(
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(lhs_id),
|
||||
),
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(rhs_id),
|
||||
),
|
||||
);
|
||||
|
||||
// define variables for the bits
|
||||
let sub_bits_be: Vec<FlatVariable> =
|
||||
(0..bit_width).map(|_| self.use_sym()).collect();
|
||||
|
||||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(FlatDirective::new(
|
||||
sub_bits_be.clone(),
|
||||
Solver::bits(bit_width),
|
||||
vec![subtraction_result.clone()],
|
||||
)));
|
||||
|
||||
// bitness checks
|
||||
for bit in sub_bits_be.iter().take(bit_width) {
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(*bit),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Identifier(*bit),
|
||||
),
|
||||
RuntimeError::LtFinalBitness,
|
||||
));
|
||||
}
|
||||
|
||||
// check that the decomposition is in the field with a strict `< p` checks
|
||||
self.enforce_constant_le_check(
|
||||
statements_flattened,
|
||||
&sub_bits_be,
|
||||
&T::max_value().bit_vector_be(),
|
||||
);
|
||||
|
||||
// sum(sym_b{i} * 2**i)
|
||||
let mut expr = FlatExpression::Number(T::from(0));
|
||||
|
||||
for (i, bit) in sub_bits_be.iter().take(bit_width).enumerate() {
|
||||
expr = FlatExpression::Add(
|
||||
box expr,
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Number(T::from(2).pow(bit_width - i - 1)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
subtraction_result,
|
||||
expr,
|
||||
RuntimeError::LtFinalSum,
|
||||
));
|
||||
|
||||
FlatExpression::Identifier(sub_bits_be[bit_width - 1])
|
||||
}
|
||||
}
|
||||
self.lt_check(
|
||||
statements_flattened,
|
||||
lhs_flattened,
|
||||
rhs_flattened,
|
||||
safe_width,
|
||||
)
|
||||
}
|
||||
BooleanExpression::BoolEq(box lhs, box rhs) => {
|
||||
// lhs and rhs are booleans, they flatten to 0 or 1
|
||||
|
@ -944,79 +863,23 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
BooleanExpression::FieldLe(rhs, lhs),
|
||||
),
|
||||
BooleanExpression::UintLt(box lhs, box rhs) => {
|
||||
let lhs_flattened = self.flatten_uint_expression(statements_flattened, lhs);
|
||||
let rhs_flattened = self.flatten_uint_expression(statements_flattened, rhs);
|
||||
let bit_width = lhs.bitwidth.to_usize();
|
||||
assert!(lhs.metadata.as_ref().unwrap().should_reduce.to_bool());
|
||||
assert!(rhs.metadata.as_ref().unwrap().should_reduce.to_bool());
|
||||
|
||||
// Get the bit width to know the size of the binary decompositions for this Field
|
||||
// This is not this uint bitwidth
|
||||
let bit_width = T::get_required_bits();
|
||||
let lhs_flattened = self
|
||||
.flatten_uint_expression(statements_flattened, lhs)
|
||||
.get_field_unchecked();
|
||||
let rhs_flattened = self
|
||||
.flatten_uint_expression(statements_flattened, rhs)
|
||||
.get_field_unchecked();
|
||||
|
||||
// lhs
|
||||
let lhs_id = self.define(lhs_flattened.get_field_unchecked(), statements_flattened);
|
||||
let rhs_id = self.define(rhs_flattened.get_field_unchecked(), statements_flattened);
|
||||
|
||||
// sym := (lhs * 2) - (rhs * 2)
|
||||
let subtraction_result = FlatExpression::Sub(
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(lhs_id),
|
||||
),
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(T::from(2)),
|
||||
box FlatExpression::Identifier(rhs_id),
|
||||
),
|
||||
);
|
||||
|
||||
// define variables for the bits
|
||||
let sub_bits_be: Vec<FlatVariable> =
|
||||
(0..bit_width).map(|_| self.use_sym()).collect();
|
||||
|
||||
// add a directive to get the bits
|
||||
statements_flattened.push(FlatStatement::Directive(FlatDirective::new(
|
||||
sub_bits_be.clone(),
|
||||
Solver::bits(bit_width),
|
||||
vec![subtraction_result.clone()],
|
||||
)));
|
||||
|
||||
// bitness checks
|
||||
for bit in sub_bits_be.iter().take(bit_width) {
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
FlatExpression::Identifier(*bit),
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Identifier(*bit),
|
||||
),
|
||||
RuntimeError::LtFinalBitness,
|
||||
));
|
||||
}
|
||||
|
||||
// check that the decomposition is in the field with a strict `< p` checks
|
||||
self.enforce_constant_le_check(
|
||||
self.lt_check(
|
||||
statements_flattened,
|
||||
&sub_bits_be,
|
||||
&T::max_value().bit_vector_be(),
|
||||
);
|
||||
|
||||
// sum(sym_b{i} * 2**i)
|
||||
let mut expr = FlatExpression::Number(T::from(0));
|
||||
|
||||
for (i, bit) in sub_bits_be.iter().enumerate().take(bit_width) {
|
||||
expr = FlatExpression::Add(
|
||||
box expr,
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(*bit),
|
||||
box FlatExpression::Number(T::from(2).pow(bit_width - i - 1)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
statements_flattened.push(FlatStatement::Condition(
|
||||
subtraction_result,
|
||||
expr,
|
||||
RuntimeError::LtFinalSum,
|
||||
));
|
||||
|
||||
FlatExpression::Identifier(sub_bits_be[bit_width - 1])
|
||||
lhs_flattened,
|
||||
rhs_flattened,
|
||||
bit_width,
|
||||
)
|
||||
}
|
||||
BooleanExpression::UintLe(box lhs, box rhs) => {
|
||||
let lt = self.flatten_boolean_expression(
|
||||
|
|
|
@ -24,25 +24,25 @@ impl<T: Field> Prog<T> {
|
|||
log::debug!("Constraints: {}", self.constraint_count());
|
||||
log::debug!("Optimizer: Remove redefinitions");
|
||||
let r = RedefinitionOptimizer::optimize(self);
|
||||
log::debug!("Done");
|
||||
log::trace!("\n{}\n", r);
|
||||
|
||||
// remove constraints that are always satisfied
|
||||
log::debug!("Constraints: {}", r.constraint_count());
|
||||
log::debug!("Optimizer: Remove tautologies");
|
||||
let r = TautologyOptimizer::optimize(r);
|
||||
log::debug!("Done");
|
||||
log::trace!("\n{}\n", r);
|
||||
|
||||
// deduplicate directives which take the same input
|
||||
log::debug!("Constraints: {}", r.constraint_count());
|
||||
log::debug!("Optimizer: Remove duplicate directive");
|
||||
let r = DirectiveOptimizer::optimize(r);
|
||||
log::debug!("Done");
|
||||
log::trace!("\n{}\n", r);
|
||||
|
||||
// remove duplicate constraints
|
||||
log::debug!("Constraints: {}", r.constraint_count());
|
||||
log::debug!("Optimizer: Remove duplicate constraints");
|
||||
let r = DuplicateOptimizer::optimize(r);
|
||||
log::debug!("Done");
|
||||
log::trace!("\n{}\n", r);
|
||||
|
||||
log::debug!("Constraints: {}", r.constraint_count());
|
||||
r
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use crate::absy::Identifier;
|
||||
use crate::absy::*;
|
||||
use crate::typed_absy::types::GGenericsAssignment;
|
||||
use crate::typed_absy::types::{GGenericsAssignment, GenericsAssignment};
|
||||
use crate::typed_absy::*;
|
||||
use crate::typed_absy::{DeclarationParameter, DeclarationVariable, Variable};
|
||||
use num_bigint::BigUint;
|
||||
|
@ -55,7 +55,33 @@ impl ErrorInner {
|
|||
}
|
||||
}
|
||||
|
||||
type TypeMap<'ast, T> = BTreeMap<OwnedModuleId, BTreeMap<UserTypeId, DeclarationType<'ast, T>>>;
|
||||
// a single struct to cover all cases of user-defined types
|
||||
#[derive(Debug, Clone)]
|
||||
struct UserDeclarationType<'ast, T> {
|
||||
generics: Vec<DeclarationConstant<'ast, T>>,
|
||||
ty: DeclarationType<'ast, T>,
|
||||
}
|
||||
|
||||
impl<'ast, T> UserDeclarationType<'ast, T> {
|
||||
// returns the declared generics for this user type
|
||||
// for alias of basic types this is empty
|
||||
// for structs this is the same as the used generics
|
||||
// for aliases of structs this is the names of the generics declared on the left side of the type declaration
|
||||
fn declaration_generics(&self) -> Vec<&'ast str> {
|
||||
self.generics
|
||||
.iter()
|
||||
.filter_map(|g| match g {
|
||||
DeclarationConstant::Generic(g) => Some(g),
|
||||
_ => None,
|
||||
})
|
||||
.collect::<BTreeSet<_>>() // we collect into a BTreeSet because draining it after yields the element in the right order defined by Ord
|
||||
.into_iter()
|
||||
.map(|g| g.name())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
type TypeMap<'ast, T> = BTreeMap<OwnedModuleId, BTreeMap<UserTypeId, UserDeclarationType<'ast, T>>>;
|
||||
type ConstantMap<'ast, T> =
|
||||
BTreeMap<OwnedModuleId, BTreeMap<ConstantIdentifier<'ast>, DeclarationType<'ast, T>>>;
|
||||
|
||||
|
@ -366,6 +392,84 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
})
|
||||
}
|
||||
|
||||
fn check_type_definition(
|
||||
&mut self,
|
||||
ty: TypeDefinitionNode<'ast>,
|
||||
module_id: &ModuleId,
|
||||
state: &State<'ast, T>,
|
||||
) -> Result<UserDeclarationType<'ast, T>, Vec<ErrorInner>> {
|
||||
let pos = ty.pos();
|
||||
let ty = ty.value;
|
||||
|
||||
let mut errors = vec![];
|
||||
|
||||
let mut generics = vec![];
|
||||
let mut generics_map = BTreeMap::new();
|
||||
|
||||
for (index, g) in ty.generics.iter().enumerate() {
|
||||
if state
|
||||
.constants
|
||||
.get(module_id)
|
||||
.and_then(|m| m.get(g.value))
|
||||
.is_some()
|
||||
{
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(g.pos()),
|
||||
message: format!(
|
||||
"Generic parameter {p} conflicts with constant symbol {p}",
|
||||
p = g.value
|
||||
),
|
||||
});
|
||||
} else {
|
||||
match generics_map.insert(g.value, index).is_none() {
|
||||
true => {
|
||||
generics.push(DeclarationConstant::Generic(
|
||||
GenericIdentifier::with_name(g.value).with_index(index),
|
||||
));
|
||||
}
|
||||
false => {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(g.pos()),
|
||||
message: format!("Generic parameter {} is already declared", g.value),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut used_generics = HashSet::new();
|
||||
|
||||
match self.check_declaration_type(
|
||||
ty.ty,
|
||||
module_id,
|
||||
state,
|
||||
&generics_map,
|
||||
&mut used_generics,
|
||||
) {
|
||||
Ok(ty) => {
|
||||
// check that all declared generics were used
|
||||
for declared_generic in generics_map.keys() {
|
||||
if !used_generics.contains(declared_generic) {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!("Generic parameter {} must be used", declared_generic),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
Ok(UserDeclarationType { generics, ty })
|
||||
}
|
||||
Err(e) => {
|
||||
errors.push(e);
|
||||
Err(errors)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_constant_definition(
|
||||
&mut self,
|
||||
id: ConstantIdentifier<'ast>,
|
||||
|
@ -422,7 +526,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
s: StructDefinitionNode<'ast>,
|
||||
module_id: &ModuleId,
|
||||
state: &State<'ast, T>,
|
||||
) -> Result<DeclarationType<'ast, T>, Vec<ErrorInner>> {
|
||||
) -> Result<DeclarationStructType<'ast, T>, Vec<ErrorInner>> {
|
||||
let pos = s.pos();
|
||||
let s = s.value;
|
||||
|
||||
|
@ -450,10 +554,9 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
} else {
|
||||
match generics_map.insert(g.value, index).is_none() {
|
||||
true => {
|
||||
generics.push(Some(DeclarationConstant::Generic(GenericIdentifier {
|
||||
name: g.value,
|
||||
index,
|
||||
})));
|
||||
generics.push(Some(DeclarationConstant::Generic(
|
||||
GenericIdentifier::with_name(g.value).with_index(index),
|
||||
)));
|
||||
}
|
||||
false => {
|
||||
errors.push(ErrorInner {
|
||||
|
@ -506,7 +609,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
return Err(errors);
|
||||
}
|
||||
|
||||
Ok(DeclarationType::Struct(DeclarationStructType::new(
|
||||
Ok(DeclarationStructType::new(
|
||||
module_id.to_path_buf(),
|
||||
id,
|
||||
generics,
|
||||
|
@ -514,7 +617,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
.iter()
|
||||
.map(|f| DeclarationStructMember::new(f.0.clone(), f.1.clone()))
|
||||
.collect(),
|
||||
)))
|
||||
))
|
||||
}
|
||||
|
||||
fn check_symbol_declaration(
|
||||
|
@ -556,7 +659,18 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
.types
|
||||
.entry(module_id.to_path_buf())
|
||||
.or_default()
|
||||
.insert(declaration.id.to_string(), ty)
|
||||
.insert(
|
||||
declaration.id.to_string(),
|
||||
UserDeclarationType {
|
||||
generics: ty
|
||||
.generics
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|g| g.unwrap())
|
||||
.collect(),
|
||||
ty: DeclarationType::Struct(ty)
|
||||
}
|
||||
)
|
||||
.is_none());
|
||||
}
|
||||
};
|
||||
|
@ -613,6 +727,35 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Symbol::Here(SymbolDefinition::Type(t)) => {
|
||||
match self.check_type_definition(t, module_id, state) {
|
||||
Ok(ty) => {
|
||||
match symbol_unifier.insert_type(declaration.id) {
|
||||
false => errors.push(
|
||||
ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"{} conflicts with another symbol",
|
||||
declaration.id,
|
||||
),
|
||||
}
|
||||
.in_file(module_id),
|
||||
),
|
||||
true => {
|
||||
assert!(state
|
||||
.types
|
||||
.entry(module_id.to_path_buf())
|
||||
.or_default()
|
||||
.insert(declaration.id.to_string(), ty)
|
||||
.is_none());
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(e) => {
|
||||
errors.extend(e.into_iter().map(|inner| inner.in_file(module_id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Symbol::Here(SymbolDefinition::Function(f)) => {
|
||||
match self.check_function(f, module_id, state) {
|
||||
Ok(funct) => {
|
||||
|
@ -696,17 +839,19 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
|
||||
match (function_candidates.len(), type_candidate, const_candidate) {
|
||||
(0, Some(t), None) => {
|
||||
|
||||
// rename the type to the declared symbol
|
||||
let t = match t {
|
||||
DeclarationType::Struct(t) => DeclarationType::Struct(DeclarationStructType {
|
||||
location: Some(StructLocation {
|
||||
name: declaration.id.into(),
|
||||
module: module_id.to_path_buf()
|
||||
let t = UserDeclarationType {
|
||||
ty: match t.ty {
|
||||
DeclarationType::Struct(t) => DeclarationType::Struct(DeclarationStructType {
|
||||
location: Some(StructLocation {
|
||||
name: declaration.id.into(),
|
||||
module: module_id.to_path_buf()
|
||||
}),
|
||||
..t
|
||||
}),
|
||||
..t
|
||||
}),
|
||||
_ => unreachable!()
|
||||
_ => t.ty // all other cases
|
||||
},
|
||||
..t
|
||||
};
|
||||
|
||||
// we imported a type, so the symbol it gets bound to should not already exist
|
||||
|
@ -954,17 +1099,26 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
|
||||
match self.check_signature(funct.signature, module_id, state) {
|
||||
Ok(s) => {
|
||||
// initialise generics map
|
||||
let mut generics: GenericsAssignment<'ast, T> = GGenericsAssignment::default();
|
||||
|
||||
// define variables for the constants
|
||||
for generic in &s.generics {
|
||||
let generic = generic.clone().unwrap(); // for declaration signatures, generics cannot be ignored
|
||||
let generic = match generic.clone().unwrap() {
|
||||
DeclarationConstant::Generic(g) => g,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let v = Variable::with_id_and_type(
|
||||
match generic {
|
||||
DeclarationConstant::Generic(g) => g.name,
|
||||
_ => unreachable!(),
|
||||
},
|
||||
Type::Uint(UBitwidth::B32),
|
||||
// for declaration signatures, generics cannot be ignored
|
||||
|
||||
let v = Variable::with_id_and_type(generic.name(), Type::Uint(UBitwidth::B32));
|
||||
|
||||
generics.0.insert(
|
||||
generic.clone(),
|
||||
UExpressionInner::Identifier(generic.name().into())
|
||||
.annotate(UBitwidth::B32),
|
||||
);
|
||||
|
||||
// we don't have to check for conflicts here, because this was done when checking the signature
|
||||
self.insert_into_scope(v.clone());
|
||||
}
|
||||
|
@ -977,9 +1131,12 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
let decl_v =
|
||||
DeclarationVariable::with_id_and_type(arg.id.value.id, decl_ty.clone());
|
||||
|
||||
match self.insert_into_scope(
|
||||
crate::typed_absy::variable::try_from_g_variable(decl_v.clone()).unwrap(),
|
||||
) {
|
||||
let ty = specialize_declaration_type(decl_v.clone()._type, &generics).unwrap();
|
||||
|
||||
match self.insert_into_scope(crate::typed_absy::variable::Variable {
|
||||
id: decl_v.clone().id,
|
||||
_type: ty,
|
||||
}) {
|
||||
true => {}
|
||||
false => {
|
||||
errors.push(ErrorInner {
|
||||
|
@ -1103,10 +1260,9 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
} else {
|
||||
match generics_map.insert(g.value, index).is_none() {
|
||||
true => {
|
||||
generics.push(Some(DeclarationConstant::Generic(GenericIdentifier {
|
||||
name: g.value,
|
||||
index,
|
||||
})));
|
||||
generics.push(Some(DeclarationConstant::Generic(
|
||||
GenericIdentifier::with_name(g.value).with_index(index),
|
||||
)));
|
||||
}
|
||||
false => {
|
||||
errors.push(ErrorInner {
|
||||
|
@ -1220,7 +1376,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
)))
|
||||
}
|
||||
UnresolvedType::User(id, generics) => {
|
||||
let declaration_type =
|
||||
let declared_ty =
|
||||
types
|
||||
.get(module_id)
|
||||
.unwrap()
|
||||
|
@ -1231,72 +1387,60 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
message: format!("Undefined type {}", id),
|
||||
})?;
|
||||
|
||||
let generic_identifiers = declared_ty.declaration_generics();
|
||||
|
||||
let declaration_type = declared_ty.ty;
|
||||
|
||||
// absence of generics is treated as 0 generics, as we do not provide inference for now
|
||||
let generics = generics.unwrap_or_default();
|
||||
|
||||
// check generics
|
||||
match declaration_type {
|
||||
DeclarationType::Struct(struct_type) => {
|
||||
match struct_type.generics.len() == generics.len() {
|
||||
true => {
|
||||
// downcast the generics to identifiers, as this is the only possibility here
|
||||
let generic_identifiers = struct_type.generics.iter().map(|c| {
|
||||
match c.as_ref().unwrap() {
|
||||
DeclarationConstant::Generic(g) => g.clone(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
|
||||
// build the generic assignment for this type
|
||||
let assignment = GGenericsAssignment(generics
|
||||
.into_iter()
|
||||
.zip(generic_identifiers)
|
||||
.map(|(e, g)| match e {
|
||||
Some(e) => {
|
||||
self
|
||||
.check_expression(e, module_id, types)
|
||||
.and_then(|e| {
|
||||
UExpression::try_from_typed(e, &UBitwidth::B32)
|
||||
.map(|e| (g, e))
|
||||
.map_err(|e| ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!("Expected u32 expression, but got expression of type {}", e.get_type()),
|
||||
})
|
||||
match generic_identifiers.len() == generics.len() {
|
||||
true => {
|
||||
// build the generic assignment for this type
|
||||
let assignment = GGenericsAssignment(generics
|
||||
.into_iter()
|
||||
.zip(generic_identifiers)
|
||||
.enumerate()
|
||||
.map(|(i, (e, g))| match e {
|
||||
Some(e) => {
|
||||
self
|
||||
.check_expression(e, module_id, types)
|
||||
.and_then(|e| {
|
||||
UExpression::try_from_typed(e, &UBitwidth::B32)
|
||||
.map(|e| (GenericIdentifier::with_name(g).with_index(i), e))
|
||||
.map_err(|e| ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!("Expected u32 expression, but got expression of type {}", e.get_type()),
|
||||
})
|
||||
},
|
||||
None => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message:
|
||||
"Expected u32 constant or identifier, but found `_`. Generic inference is not supported yet."
|
||||
.into(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<_, _>>()?);
|
||||
},
|
||||
None => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message:
|
||||
"Expected u32 constant or identifier, but found `_`. Generic inference is not supported yet."
|
||||
.into(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<_, _>>()?);
|
||||
|
||||
// specialize the declared type using the generic assignment
|
||||
Ok(specialize_declaration_type(
|
||||
DeclarationType::Struct(struct_type),
|
||||
&assignment,
|
||||
)
|
||||
.unwrap())
|
||||
}
|
||||
false => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"Expected {} generic argument{} on type {}, but got {}",
|
||||
struct_type.generics.len(),
|
||||
if struct_type.generics.len() == 1 {
|
||||
""
|
||||
} else {
|
||||
"s"
|
||||
},
|
||||
id,
|
||||
generics.len()
|
||||
),
|
||||
}),
|
||||
}
|
||||
// specialize the declared type using the generic assignment
|
||||
Ok(specialize_declaration_type(declaration_type, &assignment).unwrap())
|
||||
}
|
||||
_ => unreachable!("user defined types should always be structs"),
|
||||
false => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"Expected {} generic argument{} on type {}, but got {}",
|
||||
generic_identifiers.len(),
|
||||
if generic_identifiers.len() == 1 {
|
||||
""
|
||||
} else {
|
||||
"s"
|
||||
},
|
||||
id,
|
||||
generics.len()
|
||||
),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1344,7 +1488,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
})
|
||||
}
|
||||
}
|
||||
(None, Some(index)) => Ok(DeclarationConstant::Generic(GenericIdentifier { name, index: *index })),
|
||||
(None, Some(index)) => Ok(DeclarationConstant::Generic(GenericIdentifier::with_name(name).with_index(*index))),
|
||||
_ => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!("Undeclared symbol `{}`", name)
|
||||
|
@ -1391,7 +1535,7 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
)))
|
||||
}
|
||||
UnresolvedType::User(id, generics) => {
|
||||
let declared_ty = state
|
||||
let ty = state
|
||||
.types
|
||||
.get(module_id)
|
||||
.unwrap()
|
||||
|
@ -1402,79 +1546,63 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
message: format!("Undefined type {}", id),
|
||||
})?;
|
||||
|
||||
match declared_ty {
|
||||
DeclarationType::Struct(declared_struct_ty) => {
|
||||
let generics = generics.unwrap_or_default();
|
||||
match declared_struct_ty.generics.len() == generics.len() {
|
||||
true => {
|
||||
let checked_generics: Vec<_> = generics
|
||||
.into_iter()
|
||||
.map(|e| match e {
|
||||
Some(e) => self
|
||||
.check_generic_expression(
|
||||
e,
|
||||
module_id,
|
||||
state
|
||||
.constants
|
||||
.get(module_id)
|
||||
.unwrap_or(&BTreeMap::new()),
|
||||
generics_map,
|
||||
used_generics,
|
||||
)
|
||||
.map(Some),
|
||||
None => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message:
|
||||
"Expected u32 constant or identifier, but found `_`"
|
||||
.into(),
|
||||
}),
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
let generics = generics.unwrap_or_default();
|
||||
let checked_generics: Vec<_> = generics
|
||||
.into_iter()
|
||||
.map(|e| match e {
|
||||
Some(e) => self
|
||||
.check_generic_expression(
|
||||
e,
|
||||
module_id,
|
||||
state.constants.get(module_id).unwrap_or(&BTreeMap::new()),
|
||||
generics_map,
|
||||
used_generics,
|
||||
)
|
||||
.map(Some),
|
||||
None => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: "Expected u32 constant or identifier, but found `_`".into(),
|
||||
}),
|
||||
})
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
let mut assignment = GGenericsAssignment::default();
|
||||
match ty.generics.len() == checked_generics.len() {
|
||||
true => {
|
||||
let mut assignment = GGenericsAssignment::default();
|
||||
|
||||
assignment.0.extend(declared_struct_ty.generics.iter().zip(checked_generics.iter()).map(|(decl_g, g_val)| match decl_g.clone().unwrap() {
|
||||
DeclarationConstant::Generic(g) => (g, g_val.clone().unwrap()),
|
||||
_ => unreachable!("generic on declaration struct types must be generic identifiers")
|
||||
}));
|
||||
assignment.0.extend(ty.generics.iter().zip(checked_generics.iter()).map(|(decl_g, g_val)| match decl_g.clone() {
|
||||
DeclarationConstant::Generic(g) => (g, g_val.clone().unwrap()),
|
||||
_ => unreachable!("generic on declaration struct types must be generic identifiers")
|
||||
}));
|
||||
|
||||
// generate actual type based on generic type and concrete generics
|
||||
let members = declared_struct_ty
|
||||
.members
|
||||
.into_iter()
|
||||
.map(|m| {
|
||||
Ok(DeclarationStructMember {
|
||||
ty: box specialize_declaration_type(*m.ty, &assignment)
|
||||
.unwrap(),
|
||||
..m
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(DeclarationType::Struct(DeclarationStructType {
|
||||
canonical_location: declared_struct_ty.canonical_location,
|
||||
location: declared_struct_ty.location,
|
||||
generics: checked_generics,
|
||||
members,
|
||||
}))
|
||||
let res = match ty.ty {
|
||||
// if the type is a struct, we do not specialize in the members.
|
||||
// we only remap the generics
|
||||
DeclarationType::Struct(declared_struct_ty) => {
|
||||
DeclarationType::Struct(DeclarationStructType {
|
||||
generics: declared_struct_ty
|
||||
.generics
|
||||
.into_iter()
|
||||
.map(|g| g.map(|g| g.map(&assignment).unwrap()))
|
||||
.collect(),
|
||||
..declared_struct_ty
|
||||
})
|
||||
}
|
||||
false => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"Expected {} generic argument{} on type {}, but got {}",
|
||||
declared_struct_ty.generics.len(),
|
||||
if declared_struct_ty.generics.len() == 1 {
|
||||
""
|
||||
} else {
|
||||
"s"
|
||||
},
|
||||
id,
|
||||
generics.len()
|
||||
),
|
||||
}),
|
||||
}
|
||||
ty => specialize_declaration_type(ty, &assignment).unwrap(),
|
||||
};
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
_ => Ok(declared_ty),
|
||||
false => Err(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"Expected {} generic argument{} on type {}, but got {}",
|
||||
ty.generics.len(),
|
||||
if ty.generics.len() == 1 { "" } else { "s" },
|
||||
id,
|
||||
checked_generics.len()
|
||||
),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2995,11 +3123,19 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
Some(ty) => Ok(ty),
|
||||
}?;
|
||||
|
||||
let declared_struct_type = match ty {
|
||||
let mut declared_struct_type = match ty.ty {
|
||||
DeclarationType::Struct(struct_type) => struct_type,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
declared_struct_type.generics = (0..declared_struct_type.generics.len())
|
||||
.map(|index| {
|
||||
Some(DeclarationConstant::Generic(
|
||||
GenericIdentifier::without_name().with_index(index),
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
|
||||
// check that we provided the required number of values
|
||||
if declared_struct_type.members_count() != inline_members.len() {
|
||||
return Err(ErrorInner {
|
||||
|
@ -3560,7 +3696,7 @@ mod tests {
|
|||
"bar",
|
||||
DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into()
|
||||
GenericIdentifier::with_name("K").with_index(0).into()
|
||||
)])
|
||||
.inputs(vec![DeclarationType::FieldElement])
|
||||
));
|
||||
|
@ -3569,11 +3705,11 @@ mod tests {
|
|||
"bar",
|
||||
DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into()
|
||||
GenericIdentifier::with_name("K").with_index(0).into()
|
||||
)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("K").index(0)
|
||||
GenericIdentifier::with_name("K").with_index(0)
|
||||
))])
|
||||
));
|
||||
// a `bar` function with an equivalent signature, just renaming generic parameters
|
||||
|
@ -3581,11 +3717,11 @@ mod tests {
|
|||
"bar",
|
||||
DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("L").index(0).into()
|
||||
GenericIdentifier::with_name("L").with_index(0).into()
|
||||
)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("L").index(0)
|
||||
GenericIdentifier::with_name("L").with_index(0)
|
||||
))])
|
||||
));
|
||||
// a `bar` type isn't allowed as the name is already taken by at least one function
|
||||
|
@ -4149,16 +4285,16 @@ mod tests {
|
|||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("K").index(0)
|
||||
GenericIdentifier::with_name("K").with_index(0)
|
||||
)),
|
||||
GenericIdentifier::with_name("L").index(1)
|
||||
GenericIdentifier::with_name("L").with_index(1)
|
||||
))])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("L").index(1)
|
||||
GenericIdentifier::with_name("L").with_index(1)
|
||||
)),
|
||||
GenericIdentifier::with_name("K").index(0)
|
||||
GenericIdentifier::with_name("K").with_index(0)
|
||||
))]))
|
||||
);
|
||||
}
|
||||
|
@ -5442,12 +5578,8 @@ mod tests {
|
|||
}
|
||||
.mock();
|
||||
|
||||
let expected_type = DeclarationType::Struct(DeclarationStructType::new(
|
||||
"".into(),
|
||||
"Foo".into(),
|
||||
vec![],
|
||||
vec![],
|
||||
));
|
||||
let expected_type =
|
||||
DeclarationStructType::new("".into(), "Foo".into(), vec![], vec![]);
|
||||
|
||||
assert_eq!(
|
||||
Checker::<Bn128Field>::default().check_struct_type_declaration(
|
||||
|
@ -5483,7 +5615,7 @@ mod tests {
|
|||
}
|
||||
.mock();
|
||||
|
||||
let expected_type = DeclarationType::Struct(DeclarationStructType::new(
|
||||
let expected_type = DeclarationStructType::new(
|
||||
"".into(),
|
||||
"Foo".into(),
|
||||
vec![],
|
||||
|
@ -5491,7 +5623,7 @@ mod tests {
|
|||
DeclarationStructMember::new("foo".into(), DeclarationType::FieldElement),
|
||||
DeclarationStructMember::new("bar".into(), DeclarationType::Boolean),
|
||||
],
|
||||
));
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Checker::<Bn128Field>::default().check_struct_type_declaration(
|
||||
|
@ -5596,6 +5728,7 @@ mod tests {
|
|||
.get(&*MODULE_ID)
|
||||
.unwrap()
|
||||
.get(&"Bar".to_string())
|
||||
.map(|ty| &ty.ty)
|
||||
.unwrap(),
|
||||
&DeclarationType::Struct(DeclarationStructType::new(
|
||||
(*MODULE_ID).clone(),
|
||||
|
|
973
zokrates_core/src/static_analysis/constant_inliner.rs
Normal file
973
zokrates_core/src/static_analysis/constant_inliner.rs
Normal file
|
@ -0,0 +1,973 @@
|
|||
use crate::static_analysis::Propagator;
|
||||
use crate::typed_absy::result_folder::*;
|
||||
use crate::typed_absy::types::DeclarationConstant;
|
||||
use crate::typed_absy::*;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
use zokrates_field::Field;
|
||||
|
||||
type ProgramConstants<'ast, T> =
|
||||
HashMap<OwnedTypedModuleId, HashMap<Identifier<'ast>, TypedExpression<'ast, T>>>;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
Type(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Error::Type(s) => write!(f, "{}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct ConstantInliner<'ast, T> {
|
||||
modules: TypedModules<'ast, T>,
|
||||
location: OwnedTypedModuleId,
|
||||
constants: ProgramConstants<'ast, T>,
|
||||
}
|
||||
|
||||
impl<'ast, 'a, T: Field> ConstantInliner<'ast, T> {
|
||||
pub fn new(
|
||||
modules: TypedModules<'ast, T>,
|
||||
location: OwnedTypedModuleId,
|
||||
constants: ProgramConstants<'ast, T>,
|
||||
) -> Self {
|
||||
ConstantInliner {
|
||||
modules,
|
||||
location,
|
||||
constants,
|
||||
}
|
||||
}
|
||||
pub fn inline(p: TypedProgram<'ast, T>) -> Result<TypedProgram<'ast, T>, Error> {
|
||||
let constants = ProgramConstants::new();
|
||||
let mut inliner = ConstantInliner::new(p.modules.clone(), p.main.clone(), constants);
|
||||
inliner.fold_program(p)
|
||||
}
|
||||
|
||||
fn change_location(&mut self, location: OwnedTypedModuleId) -> OwnedTypedModuleId {
|
||||
let prev = self.location.clone();
|
||||
self.location = location;
|
||||
self.constants.entry(self.location.clone()).or_default();
|
||||
prev
|
||||
}
|
||||
|
||||
fn treated(&self, id: &TypedModuleId) -> bool {
|
||||
self.constants.contains_key(id)
|
||||
}
|
||||
|
||||
fn get_constant(
|
||||
&self,
|
||||
id: &CanonicalConstantIdentifier<'ast>,
|
||||
) -> Option<TypedExpression<'ast, T>> {
|
||||
self.constants
|
||||
.get(&id.module)
|
||||
.and_then(|constants| constants.get(&id.id.into()))
|
||||
.cloned()
|
||||
}
|
||||
|
||||
fn get_constant_for_identifier(
|
||||
&self,
|
||||
id: &Identifier<'ast>,
|
||||
) -> Option<TypedExpression<'ast, T>> {
|
||||
self.constants
|
||||
.get(&self.location)
|
||||
.and_then(|constants| constants.get(&id))
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantInliner<'ast, T> {
|
||||
type Error = Error;
|
||||
|
||||
fn fold_program(
|
||||
&mut self,
|
||||
p: TypedProgram<'ast, T>,
|
||||
) -> Result<TypedProgram<'ast, T>, Self::Error> {
|
||||
self.fold_module_id(p.main.clone())?;
|
||||
|
||||
Ok(TypedProgram {
|
||||
modules: std::mem::take(&mut self.modules),
|
||||
..p
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_module_id(
|
||||
&mut self,
|
||||
id: OwnedTypedModuleId,
|
||||
) -> Result<OwnedTypedModuleId, Self::Error> {
|
||||
// anytime we encounter a module id, visit the corresponding module if it hasn't been done yet
|
||||
if !self.treated(&id) {
|
||||
let current_m_id = self.change_location(id.clone());
|
||||
let m = self.modules.remove(&id).unwrap();
|
||||
let m = self.fold_module(m)?;
|
||||
self.modules.insert(id.clone(), m);
|
||||
self.change_location(current_m_id);
|
||||
}
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn fold_module(
|
||||
&mut self,
|
||||
m: TypedModule<'ast, T>,
|
||||
) -> Result<TypedModule<'ast, T>, Self::Error> {
|
||||
Ok(TypedModule {
|
||||
constants: m
|
||||
.constants
|
||||
.into_iter()
|
||||
.map(|(id, tc)| {
|
||||
|
||||
let id = self.fold_canonical_constant_identifier(id)?;
|
||||
|
||||
let constant = match tc {
|
||||
TypedConstantSymbol::There(imported_id) => {
|
||||
// visit the imported symbol. This triggers visiting the corresponding module if needed
|
||||
let imported_id = self.fold_canonical_constant_identifier(imported_id)?;
|
||||
// after that, the constant must have been defined defined in the global map. It is already reduced
|
||||
// to a literal, so running propagation isn't required
|
||||
self.get_constant(&imported_id).unwrap()
|
||||
}
|
||||
TypedConstantSymbol::Here(c) => {
|
||||
let non_propagated_constant = fold_constant(self, c)?.expression;
|
||||
// folding the constant above only reduces it to an expression containing only literals, not to a single literal.
|
||||
// propagating with an empty map of constants reduces it to a single literal
|
||||
Propagator::with_constants(&mut HashMap::default())
|
||||
.fold_expression(non_propagated_constant)
|
||||
.unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
if crate::typed_absy::types::try_from_g_type::<_, UExpression<'ast, T>>(*id.ty.clone()).unwrap() == constant.get_type() {
|
||||
// add to the constant map. The value added is always a single litteral
|
||||
self.constants
|
||||
.get_mut(&self.location)
|
||||
.unwrap()
|
||||
.insert(id.id.into(), constant.clone());
|
||||
|
||||
Ok((
|
||||
id,
|
||||
TypedConstantSymbol::Here(TypedConstant {
|
||||
expression: constant,
|
||||
}),
|
||||
))
|
||||
} else {
|
||||
Err(Error::Type(format!("Expression of type `{}` cannot be assigned to constant `{}` of type `{}`", constant.get_type(), id.id, id.ty)))
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
functions: m
|
||||
.functions
|
||||
.into_iter()
|
||||
.map::<Result<_, Self::Error>, _>(|(key, fun)| {
|
||||
Ok((
|
||||
self.fold_declaration_function_key(key)?,
|
||||
self.fold_function_symbol(fun)?,
|
||||
))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_declaration_constant(
|
||||
&mut self,
|
||||
c: DeclarationConstant<'ast>,
|
||||
) -> Result<DeclarationConstant<'ast>, Self::Error> {
|
||||
match c {
|
||||
// replace constants by their concrete value in declaration types
|
||||
DeclarationConstant::Constant(id) => {
|
||||
let id = CanonicalConstantIdentifier {
|
||||
module: self.fold_module_id(id.module)?,
|
||||
..id
|
||||
};
|
||||
|
||||
Ok(DeclarationConstant::Concrete(match self.get_constant(&id).unwrap() {
|
||||
TypedExpression::Uint(UExpression {
|
||||
inner: UExpressionInner::Value(v),
|
||||
..
|
||||
}) => v as u32,
|
||||
_ => unreachable!("all constants found in declaration types should be reduceable to u32 literals"),
|
||||
}))
|
||||
}
|
||||
c => Ok(c),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_field_expression(
|
||||
&mut self,
|
||||
e: FieldElementExpression<'ast, T>,
|
||||
) -> Result<FieldElementExpression<'ast, T>, Self::Error> {
|
||||
match e {
|
||||
FieldElementExpression::Identifier(ref id) => {
|
||||
match self.get_constant_for_identifier(id) {
|
||||
Some(c) => Ok(c.try_into().unwrap()),
|
||||
None => fold_field_expression(self, e),
|
||||
}
|
||||
}
|
||||
e => fold_field_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_boolean_expression(
|
||||
&mut self,
|
||||
e: BooleanExpression<'ast, T>,
|
||||
) -> Result<BooleanExpression<'ast, T>, Self::Error> {
|
||||
match e {
|
||||
BooleanExpression::Identifier(ref id) => match self.get_constant_for_identifier(id) {
|
||||
Some(c) => Ok(c.try_into().unwrap()),
|
||||
None => fold_boolean_expression(self, e),
|
||||
},
|
||||
e => fold_boolean_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_uint_expression_inner(
|
||||
&mut self,
|
||||
size: UBitwidth,
|
||||
e: UExpressionInner<'ast, T>,
|
||||
) -> Result<UExpressionInner<'ast, T>, Self::Error> {
|
||||
match e {
|
||||
UExpressionInner::Identifier(ref id) => match self.get_constant_for_identifier(id) {
|
||||
Some(c) => {
|
||||
let e: UExpression<'ast, T> = c.try_into().unwrap();
|
||||
Ok(e.into_inner())
|
||||
}
|
||||
None => fold_uint_expression_inner(self, size, e),
|
||||
},
|
||||
e => fold_uint_expression_inner(self, size, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_array_expression_inner(
|
||||
&mut self,
|
||||
ty: &ArrayType<'ast, T>,
|
||||
e: ArrayExpressionInner<'ast, T>,
|
||||
) -> Result<ArrayExpressionInner<'ast, T>, Self::Error> {
|
||||
match e {
|
||||
ArrayExpressionInner::Identifier(ref id) => {
|
||||
match self.get_constant_for_identifier(id) {
|
||||
Some(c) => {
|
||||
let e: ArrayExpression<'ast, T> = c.try_into().unwrap();
|
||||
Ok(e.into_inner())
|
||||
}
|
||||
None => fold_array_expression_inner(self, ty, e),
|
||||
}
|
||||
}
|
||||
e => fold_array_expression_inner(self, ty, e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_struct_expression_inner(
|
||||
&mut self,
|
||||
ty: &StructType<'ast, T>,
|
||||
e: StructExpressionInner<'ast, T>,
|
||||
) -> Result<StructExpressionInner<'ast, T>, Self::Error> {
|
||||
match e {
|
||||
StructExpressionInner::Identifier(ref id) => match self.get_constant_for_identifier(id)
|
||||
{
|
||||
Some(c) => {
|
||||
let e: StructExpression<'ast, T> = c.try_into().unwrap();
|
||||
Ok(e.into_inner())
|
||||
}
|
||||
None => fold_struct_expression_inner(self, ty, e),
|
||||
},
|
||||
e => fold_struct_expression_inner(self, ty, e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::typed_absy::types::DeclarationSignature;
|
||||
use crate::typed_absy::{
|
||||
DeclarationArrayType, DeclarationFunctionKey, DeclarationType, FieldElementExpression,
|
||||
GType, Identifier, TypedConstant, TypedExpression, TypedFunction, TypedFunctionSymbol,
|
||||
TypedStatement,
|
||||
};
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
#[test]
|
||||
fn inline_const_field() {
|
||||
// const field a = 1
|
||||
//
|
||||
// def main() -> field:
|
||||
// return a
|
||||
|
||||
let const_id = "a";
|
||||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
FieldElementExpression::Identifier(Identifier::from(const_id)).into(),
|
||||
])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
};
|
||||
|
||||
let constants: TypedConstantSymbols<_> = vec![(
|
||||
CanonicalConstantIdentifier::new(
|
||||
const_id,
|
||||
"main".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::FieldElement(
|
||||
FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
))),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let program = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: constants.clone(),
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let program = ConstantInliner::inline(program);
|
||||
|
||||
let expected_main = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(1)).into(),
|
||||
])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
};
|
||||
|
||||
let expected_program: TypedProgram<Bn128Field> = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(expected_main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants,
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
assert_eq!(program, Ok(expected_program))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_const_boolean() {
|
||||
// const bool a = true
|
||||
//
|
||||
// def main() -> bool:
|
||||
// return a
|
||||
|
||||
let const_id = "a";
|
||||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![BooleanExpression::Identifier(
|
||||
Identifier::from(const_id),
|
||||
)
|
||||
.into()])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Boolean]),
|
||||
};
|
||||
|
||||
let constants: TypedConstantSymbols<_> = vec![(
|
||||
CanonicalConstantIdentifier::new(const_id, "main".into(), DeclarationType::Boolean),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::Boolean(
|
||||
BooleanExpression::Value(true),
|
||||
))),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let program = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Boolean]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: constants.clone(),
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let program = ConstantInliner::inline(program);
|
||||
|
||||
let expected_main = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
BooleanExpression::Value(true).into()
|
||||
])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Boolean]),
|
||||
};
|
||||
|
||||
let expected_program: TypedProgram<Bn128Field> = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Boolean]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(expected_main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants,
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
assert_eq!(program, Ok(expected_program))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_const_uint() {
|
||||
// const u32 a = 0x00000001
|
||||
//
|
||||
// def main() -> u32:
|
||||
// return a
|
||||
|
||||
let const_id = "a";
|
||||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![UExpressionInner::Identifier(
|
||||
Identifier::from(const_id),
|
||||
)
|
||||
.annotate(UBitwidth::B32)
|
||||
.into()])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Uint(UBitwidth::B32)]),
|
||||
};
|
||||
|
||||
let constants: TypedConstantSymbols<_> = vec![(
|
||||
CanonicalConstantIdentifier::new(
|
||||
const_id,
|
||||
"main".into(),
|
||||
DeclarationType::Uint(UBitwidth::B32),
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(
|
||||
UExpressionInner::Value(1u128)
|
||||
.annotate(UBitwidth::B32)
|
||||
.into(),
|
||||
)),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let program = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Uint(UBitwidth::B32)]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: constants.clone(),
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let program = ConstantInliner::inline(program);
|
||||
|
||||
let expected_main = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![UExpressionInner::Value(1u128)
|
||||
.annotate(UBitwidth::B32)
|
||||
.into()])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Uint(UBitwidth::B32)]),
|
||||
};
|
||||
|
||||
let expected_program: TypedProgram<Bn128Field> = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::Uint(UBitwidth::B32)]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(expected_main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants,
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
assert_eq!(program, Ok(expected_program))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_const_field_array() {
|
||||
// const field[2] a = [2, 2]
|
||||
//
|
||||
// def main() -> field:
|
||||
// return a[0] + a[1]
|
||||
|
||||
let const_id = "a";
|
||||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![FieldElementExpression::Add(
|
||||
FieldElementExpression::select(
|
||||
ArrayExpressionInner::Identifier(Identifier::from(const_id))
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
UExpressionInner::Value(0u128).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into(),
|
||||
FieldElementExpression::select(
|
||||
ArrayExpressionInner::Identifier(Identifier::from(const_id))
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
UExpressionInner::Value(1u128).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.into()])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
};
|
||||
|
||||
let constants: TypedConstantSymbols<_> = vec![(
|
||||
CanonicalConstantIdentifier::new(
|
||||
const_id,
|
||||
"main".into(),
|
||||
DeclarationType::Array(DeclarationArrayType::new(
|
||||
DeclarationType::FieldElement,
|
||||
2u32,
|
||||
)),
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::Array(
|
||||
ArrayExpressionInner::Value(
|
||||
vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
]
|
||||
.into(),
|
||||
)
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
))),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let program = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: constants.clone(),
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let program = ConstantInliner::inline(program);
|
||||
|
||||
let expected_main = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![FieldElementExpression::Add(
|
||||
FieldElementExpression::select(
|
||||
ArrayExpressionInner::Value(
|
||||
vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
]
|
||||
.into(),
|
||||
)
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
UExpressionInner::Value(0u128).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into(),
|
||||
FieldElementExpression::select(
|
||||
ArrayExpressionInner::Value(
|
||||
vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
]
|
||||
.into(),
|
||||
)
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
UExpressionInner::Value(1u128).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
.into()])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
};
|
||||
|
||||
let expected_program: TypedProgram<Bn128Field> = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(expected_main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants,
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
assert_eq!(program, Ok(expected_program))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_nested_const_field() {
|
||||
// const field a = 1
|
||||
// const field b = a + 1
|
||||
//
|
||||
// def main() -> field:
|
||||
// return b
|
||||
|
||||
let const_a_id = "a";
|
||||
let const_b_id = "b";
|
||||
|
||||
let main: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
FieldElementExpression::Identifier(Identifier::from(const_b_id)).into(),
|
||||
])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
};
|
||||
|
||||
let program = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: vec![
|
||||
(
|
||||
CanonicalConstantIdentifier::new(
|
||||
const_a_id,
|
||||
"main".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(
|
||||
TypedExpression::FieldElement(FieldElementExpression::Number(
|
||||
Bn128Field::from(1),
|
||||
)),
|
||||
)),
|
||||
),
|
||||
(
|
||||
CanonicalConstantIdentifier::new(
|
||||
const_b_id,
|
||||
"main".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(
|
||||
TypedExpression::FieldElement(FieldElementExpression::Add(
|
||||
box FieldElementExpression::Identifier(Identifier::from(
|
||||
const_a_id,
|
||||
)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
)),
|
||||
)),
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let program = ConstantInliner::inline(program);
|
||||
|
||||
let expected_main = TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(2)).into(),
|
||||
])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
};
|
||||
|
||||
let expected_program: TypedProgram<Bn128Field> = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![(
|
||||
"main".into(),
|
||||
TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(expected_main),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: vec![
|
||||
(
|
||||
CanonicalConstantIdentifier::new(
|
||||
const_a_id,
|
||||
"main".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(
|
||||
TypedExpression::FieldElement(FieldElementExpression::Number(
|
||||
Bn128Field::from(1),
|
||||
)),
|
||||
)),
|
||||
),
|
||||
(
|
||||
CanonicalConstantIdentifier::new(
|
||||
const_b_id,
|
||||
"main".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(
|
||||
TypedExpression::FieldElement(FieldElementExpression::Number(
|
||||
Bn128Field::from(2),
|
||||
)),
|
||||
)),
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
},
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
assert_eq!(program, Ok(expected_program))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inline_imported_constant() {
|
||||
// ---------------------
|
||||
// module `foo`
|
||||
// --------------------
|
||||
// const field FOO = 42
|
||||
//
|
||||
// def main():
|
||||
// return
|
||||
//
|
||||
// ---------------------
|
||||
// module `main`
|
||||
// ---------------------
|
||||
// from "foo" import FOO
|
||||
//
|
||||
// def main() -> field:
|
||||
// return FOO
|
||||
|
||||
let foo_const_id = "FOO";
|
||||
let foo_module = TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main")
|
||||
.signature(DeclarationSignature::new().inputs(vec![]).outputs(vec![])),
|
||||
TypedFunctionSymbol::Here(TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![],
|
||||
signature: DeclarationSignature::new().inputs(vec![]).outputs(vec![]),
|
||||
}),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: vec![(
|
||||
CanonicalConstantIdentifier::new(
|
||||
foo_const_id,
|
||||
"foo".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::FieldElement(
|
||||
FieldElementExpression::Number(Bn128Field::from(42)),
|
||||
))),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let main_module = TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
FieldElementExpression::Identifier(Identifier::from(foo_const_id)).into(),
|
||||
])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
}),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: vec![(
|
||||
CanonicalConstantIdentifier::new(
|
||||
foo_const_id,
|
||||
"main".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::There(CanonicalConstantIdentifier::new(
|
||||
foo_const_id,
|
||||
"foo".into(),
|
||||
DeclarationType::FieldElement,
|
||||
)),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let program = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![
|
||||
("main".into(), main_module),
|
||||
("foo".into(), foo_module.clone()),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let program = ConstantInliner::inline(program);
|
||||
let expected_main_module = TypedModule {
|
||||
functions: vec![(
|
||||
DeclarationFunctionKey::with_location("main", "main").signature(
|
||||
DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
),
|
||||
TypedFunctionSymbol::Here(TypedFunction {
|
||||
arguments: vec![],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(42)).into(),
|
||||
])],
|
||||
signature: DeclarationSignature::new()
|
||||
.inputs(vec![])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
}),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
constants: vec![(
|
||||
CanonicalConstantIdentifier::new(
|
||||
foo_const_id,
|
||||
"main".into(),
|
||||
DeclarationType::FieldElement,
|
||||
),
|
||||
TypedConstantSymbol::Here(TypedConstant::new(TypedExpression::FieldElement(
|
||||
FieldElementExpression::Number(Bn128Field::from(42)),
|
||||
))),
|
||||
)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let expected_program: TypedProgram<Bn128Field> = TypedProgram {
|
||||
main: "main".into(),
|
||||
modules: vec![
|
||||
("main".into(), expected_main_module),
|
||||
("foo".into(), foo_module),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
assert_eq!(program, Ok(expected_program))
|
||||
}
|
||||
}
|
|
@ -310,13 +310,13 @@ mod tests {
|
|||
statements: vec![TypedStatement::Return(vec![FieldElementExpression::Add(
|
||||
FieldElementExpression::select(
|
||||
ArrayExpressionInner::Identifier(Identifier::from(const_id.clone()))
|
||||
.annotate(GType::FieldElement, 2usize),
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
UExpressionInner::Value(0u128).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into(),
|
||||
FieldElementExpression::select(
|
||||
ArrayExpressionInner::Identifier(Identifier::from(const_id.clone()))
|
||||
.annotate(GType::FieldElement, 2usize),
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
UExpressionInner::Value(1u128).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into(),
|
||||
|
@ -346,7 +346,7 @@ mod tests {
|
|||
]
|
||||
.into(),
|
||||
)
|
||||
.annotate(GType::FieldElement, 2usize),
|
||||
.annotate(GType::FieldElement, 2u32),
|
||||
),
|
||||
DeclarationType::Array(DeclarationArrayType::new(
|
||||
DeclarationType::FieldElement,
|
||||
|
|
|
@ -340,7 +340,7 @@ impl<'ast, T: Field> Flattener<T> {
|
|||
&mut self,
|
||||
statements_buffer: &mut Vec<zir::ZirStatement<'ast, T>>,
|
||||
ty: &typed_absy::types::ConcreteType,
|
||||
size: usize,
|
||||
size: u32,
|
||||
e: typed_absy::ArrayExpressionInner<'ast, T>,
|
||||
) -> Vec<zir::ZirExpression<'ast, T>> {
|
||||
fold_array_expression_inner(self, statements_buffer, ty, size, e)
|
||||
|
@ -410,7 +410,7 @@ fn fold_array_expression_inner<'ast, T: Field>(
|
|||
f: &mut Flattener<T>,
|
||||
statements_buffer: &mut Vec<zir::ZirStatement<'ast, T>>,
|
||||
ty: &typed_absy::types::ConcreteType,
|
||||
size: usize,
|
||||
size: u32,
|
||||
array: typed_absy::ArrayExpressionInner<'ast, T>,
|
||||
) -> Vec<zir::ZirExpression<'ast, T>> {
|
||||
match array {
|
||||
|
@ -443,7 +443,7 @@ fn fold_array_expression_inner<'ast, T: Field>(
|
|||
.flat_map(|e| f.fold_expression_or_spread(statements_buffer, e))
|
||||
.collect();
|
||||
|
||||
assert_eq!(exprs.len(), size * ty.get_primitive_count());
|
||||
assert_eq!(exprs.len(), size as usize * ty.get_primitive_count());
|
||||
|
||||
exprs
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ fn fold_array_expression_inner<'ast, T: Field>(
|
|||
|
||||
match (from.into_inner(), to.into_inner()) {
|
||||
(zir::UExpressionInner::Value(from), zir::UExpressionInner::Value(to)) => {
|
||||
assert_eq!(size, to.saturating_sub(from) as usize);
|
||||
assert_eq!(size, to.saturating_sub(from) as u32);
|
||||
|
||||
let element_size = ty.get_primitive_count();
|
||||
let start = from as usize * element_size;
|
||||
|
@ -1114,10 +1114,7 @@ fn fold_array_expression<'ast, T: Field>(
|
|||
statements_buffer: &mut Vec<zir::ZirStatement<'ast, T>>,
|
||||
e: typed_absy::ArrayExpression<'ast, T>,
|
||||
) -> Vec<zir::ZirExpression<'ast, T>> {
|
||||
let size = match e.size().into_inner() {
|
||||
typed_absy::UExpressionInner::Value(v) => v,
|
||||
_ => unreachable!(),
|
||||
} as usize;
|
||||
let size: u32 = e.size().try_into().unwrap();
|
||||
f.fold_array_expression_inner(
|
||||
statements_buffer,
|
||||
&typed_absy::types::ConcreteType::try_from(e.inner_type().clone()).unwrap(),
|
||||
|
|
|
@ -12,6 +12,7 @@ mod flatten_complex_types;
|
|||
mod out_of_bounds;
|
||||
mod propagation;
|
||||
mod reducer;
|
||||
mod struct_concretizer;
|
||||
mod uint_optimizer;
|
||||
mod unconstrained_vars;
|
||||
mod variable_write_remover;
|
||||
|
@ -23,6 +24,7 @@ use self::flatten_complex_types::Flattener;
|
|||
use self::out_of_bounds::OutOfBoundsChecker;
|
||||
use self::propagation::Propagator;
|
||||
use self::reducer::reduce_program;
|
||||
use self::struct_concretizer::StructConcretizer;
|
||||
use self::uint_optimizer::UintOptimizer;
|
||||
use self::unconstrained_vars::UnconstrainedVariableDetector;
|
||||
use self::variable_write_remover::VariableWriteRemover;
|
||||
|
@ -124,6 +126,14 @@ impl<'ast, T: Field> TypedProgram<'ast, T> {
|
|||
let r = reduce_program(r).map_err(Error::from)?;
|
||||
log::trace!("\n{}", r);
|
||||
|
||||
log::debug!("Static analyser: Propagate");
|
||||
let r = Propagator::propagate(r)?;
|
||||
log::trace!("\n{}", r);
|
||||
|
||||
log::debug!("Static analyser: Concretize structs");
|
||||
let r = StructConcretizer::concretize(r);
|
||||
log::trace!("\n{}", r);
|
||||
|
||||
// generate abi
|
||||
log::debug!("Static analyser: Generate abi");
|
||||
let abi = r.abi();
|
||||
|
|
|
@ -1078,6 +1078,14 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
})
|
||||
// ignore spreads over empty arrays
|
||||
.filter_map(|e| match e {
|
||||
// clippy makes a wrong suggestion here:
|
||||
// ```
|
||||
// this creates an owned instance just for comparison
|
||||
// UExpression::from(0u32)
|
||||
// help: try: `0u32`
|
||||
// ```
|
||||
// But for `UExpression`, `PartialEq<Self>` is different from `PartialEq<u32>` (the latter is too optimistic in this case)
|
||||
#[allow(clippy::cmp_owned)]
|
||||
TypedExpressionOrSpread::Spread(s)
|
||||
if s.array.size() == UExpression::from(0u32) =>
|
||||
{
|
||||
|
@ -1197,16 +1205,14 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
|
|||
let e1 = self.fold_struct_expression(e1)?;
|
||||
let e2 = self.fold_struct_expression(e2)?;
|
||||
|
||||
if let (Ok(t1), Ok(t2)) = (
|
||||
ConcreteType::try_from(e1.get_type()),
|
||||
ConcreteType::try_from(e2.get_type()),
|
||||
) {
|
||||
if t1 != t2 {
|
||||
return Err(Error::Type(format!(
|
||||
"Cannot compare {} of type {} to {} of type {}",
|
||||
e1, t1, e2, t2
|
||||
)));
|
||||
}
|
||||
let t1 = e1.get_type();
|
||||
let t2 = e2.get_type();
|
||||
|
||||
if t1 != t2 {
|
||||
return Err(Error::Type(format!(
|
||||
"Cannot compare {} of type {} to {} of type {}",
|
||||
e1, t1, e2, t2
|
||||
)));
|
||||
};
|
||||
|
||||
Ok(BooleanExpression::StructEq(box e1, box e2))
|
||||
|
@ -1470,7 +1476,7 @@ mod tests {
|
|||
]
|
||||
.into(),
|
||||
)
|
||||
.annotate(Type::FieldElement, 3usize),
|
||||
.annotate(Type::FieldElement, 3u32),
|
||||
UExpressionInner::Add(box 1u32.into(), box 1u32.into())
|
||||
.annotate(UBitwidth::B32),
|
||||
);
|
||||
|
|
|
@ -84,7 +84,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantsWriter<'ast, T> {
|
|||
&mut self,
|
||||
s: TypedSymbolDeclaration<'ast, T>,
|
||||
) -> Result<TypedSymbolDeclaration<'ast, T>, Self::Error> {
|
||||
// before we treat the symbol, propagate the constants into it, as may be using constants defined earlier in this module.
|
||||
// before we treat the symbol, propagate the constants into it, as it may be using constants defined earlier in this module.
|
||||
let s = self.update_symbol_declaration(s);
|
||||
|
||||
let s = fold_symbol_declaration(self, s)?;
|
||||
|
@ -103,6 +103,12 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantsWriter<'ast, T> {
|
|||
TypedConstantSymbol::Here(c) => {
|
||||
let c = self.fold_constant(c)?;
|
||||
|
||||
// if constants were used in the rhs, they are now defined in the map
|
||||
// replace them in the expression
|
||||
use crate::typed_absy::folder::Folder;
|
||||
|
||||
let c = ConstantsReader::with_constants(&self.constants).fold_constant(c);
|
||||
|
||||
use crate::typed_absy::{DeclarationSignature, TypedFunction, TypedStatement};
|
||||
|
||||
// wrap this expression in a function
|
||||
|
|
|
@ -508,7 +508,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
}
|
||||
|
||||
pub fn reduce_program<T: Field>(p: TypedProgram<T>) -> Result<TypedProgram<T>, Error> {
|
||||
// inline all constants and replace them in the program
|
||||
// inline all constants and replace them in the program
|
||||
|
||||
let mut constants_writer = ConstantsWriter::with_program(p.clone());
|
||||
|
||||
|
@ -856,22 +856,22 @@ mod tests {
|
|||
|
||||
let foo_signature = DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
))])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
))]);
|
||||
|
||||
let foo: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::array(
|
||||
"a",
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("K").index(0),
|
||||
GenericIdentifier::with_name("K").with_index(0),
|
||||
)
|
||||
.into()],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
|
@ -979,7 +979,7 @@ mod tests {
|
|||
DeclarationFunctionKey::with_location("main", "foo")
|
||||
.signature(foo_signature.clone()),
|
||||
GGenericsAssignment(
|
||||
vec![(GenericIdentifier::with_name("K").index(0), 1)]
|
||||
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
|
@ -1072,22 +1072,22 @@ mod tests {
|
|||
|
||||
let foo_signature = DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
))])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
))]);
|
||||
|
||||
let foo: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::array(
|
||||
"a",
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("K").index(0),
|
||||
GenericIdentifier::with_name("K").with_index(0),
|
||||
)
|
||||
.into()],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
|
@ -1204,7 +1204,7 @@ mod tests {
|
|||
DeclarationFunctionKey::with_location("main", "foo")
|
||||
.signature(foo_signature.clone()),
|
||||
GGenericsAssignment(
|
||||
vec![(GenericIdentifier::with_name("K").index(0), 1)]
|
||||
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
|
@ -1300,21 +1300,21 @@ mod tests {
|
|||
let foo_signature = DeclarationSignature::new()
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
))])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
))])
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)]);
|
||||
|
||||
let foo: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::array(
|
||||
"a",
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
)
|
||||
.into()],
|
||||
statements: vec![
|
||||
|
@ -1378,7 +1378,7 @@ mod tests {
|
|||
arguments: vec![DeclarationVariable::array(
|
||||
"a",
|
||||
DeclarationType::FieldElement,
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").index(0)),
|
||||
DeclarationConstant::Generic(GenericIdentifier::with_name("K").with_index(0)),
|
||||
)
|
||||
.into()],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
|
@ -1453,7 +1453,7 @@ mod tests {
|
|||
DeclarationFunctionKey::with_location("main", "foo")
|
||||
.signature(foo_signature.clone()),
|
||||
GGenericsAssignment(
|
||||
vec![(GenericIdentifier::with_name("K").index(0), 1)]
|
||||
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
|
@ -1462,7 +1462,7 @@ mod tests {
|
|||
DeclarationFunctionKey::with_location("main", "bar")
|
||||
.signature(foo_signature.clone()),
|
||||
GGenericsAssignment(
|
||||
vec![(GenericIdentifier::with_name("K").index(0), 2)]
|
||||
vec![(GenericIdentifier::with_name("K").with_index(0), 2)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
|
@ -1507,22 +1507,22 @@ mod tests {
|
|||
|
||||
let foo_signature = DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("K").index(0),
|
||||
GenericIdentifier::with_name("K").with_index(0),
|
||||
))])
|
||||
.outputs(vec![DeclarationType::array((
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("K").index(0),
|
||||
GenericIdentifier::with_name("K").with_index(0),
|
||||
))]);
|
||||
|
||||
let foo: TypedFunction<Bn128Field> = TypedFunction {
|
||||
arguments: vec![DeclarationVariable::array(
|
||||
"a",
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier::with_name("K").index(0),
|
||||
GenericIdentifier::with_name("K").with_index(0),
|
||||
)
|
||||
.into()],
|
||||
statements: vec![TypedStatement::Return(vec![
|
||||
|
|
|
@ -105,7 +105,7 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> {
|
|||
.map(|(g, v)| {
|
||||
TypedStatement::Definition(
|
||||
TypedAssignee::Identifier(Variable::with_id_and_type(
|
||||
g.name,
|
||||
g.name(),
|
||||
Type::Uint(UBitwidth::B32),
|
||||
)),
|
||||
UExpression::from(*v as u32).into(),
|
||||
|
@ -662,7 +662,7 @@ mod tests {
|
|||
],
|
||||
signature: DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::FieldElement])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
|
@ -673,7 +673,7 @@ mod tests {
|
|||
let ssa = ShallowTransformer::transform(
|
||||
f,
|
||||
&GGenericsAssignment(
|
||||
vec![(GenericIdentifier::with_name("K").index(0), 1)]
|
||||
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
|
@ -742,7 +742,7 @@ mod tests {
|
|||
],
|
||||
signature: DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::FieldElement])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
|
@ -851,7 +851,7 @@ mod tests {
|
|||
],
|
||||
signature: DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::FieldElement])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
|
@ -862,7 +862,7 @@ mod tests {
|
|||
let ssa = ShallowTransformer::transform(
|
||||
f,
|
||||
&GGenericsAssignment(
|
||||
vec![(GenericIdentifier::with_name("K").index(0), 1)]
|
||||
vec![(GenericIdentifier::with_name("K").with_index(0), 1)]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
|
@ -934,7 +934,7 @@ mod tests {
|
|||
],
|
||||
signature: DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier::with_name("K").index(0).into(),
|
||||
GenericIdentifier::with_name("K").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::FieldElement])
|
||||
.outputs(vec![DeclarationType::FieldElement]),
|
||||
|
|
90
zokrates_core/src/static_analysis/struct_concretizer.rs
Normal file
90
zokrates_core/src/static_analysis/struct_concretizer.rs
Normal file
|
@ -0,0 +1,90 @@
|
|||
// After all generics are inlined, a program should be completely "concrete", which means that all types must only contain
|
||||
// litterals for array sizes. This is especially important to generate the ABI of the program.
|
||||
// It is direct to ensure that with most types, however the way structs are implemented requires a slightly different process:
|
||||
// Where for an array, `field[N]` ends up being propagated to `field[42]` which is direct to turn into a concrete type,
|
||||
// for structs, `Foo<N> { field[N] a }` is propagated to `Foo<42> { field[N] a }`. The missing step is replacing `N` by `42`
|
||||
// *inside* the canonical type, so that it can be concretized in the same way arrays are.
|
||||
|
||||
use crate::typed_absy::folder::*;
|
||||
use crate::typed_absy::{
|
||||
types::{
|
||||
ConcreteGenericsAssignment, DeclarationArrayType, DeclarationConstant,
|
||||
DeclarationStructMember, GGenericsAssignment,
|
||||
},
|
||||
DeclarationStructType, GenericIdentifier, TypedProgram,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub struct StructConcretizer<'ast, T> {
|
||||
generics: ConcreteGenericsAssignment<'ast>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> StructConcretizer<'ast, T> {
|
||||
pub fn concretize(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> {
|
||||
StructConcretizer::with_generics(ConcreteGenericsAssignment::default()).fold_program(p)
|
||||
}
|
||||
|
||||
pub fn with_generics(generics: ConcreteGenericsAssignment<'ast>) -> Self {
|
||||
Self {
|
||||
generics,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Folder<'ast, T> for StructConcretizer<'ast, T> {
|
||||
fn fold_declaration_struct_type(
|
||||
&mut self,
|
||||
ty: DeclarationStructType<'ast, T>,
|
||||
) -> DeclarationStructType<'ast, T> {
|
||||
let concrete_generics: Vec<u32> = ty
|
||||
.generics
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|g| g.unwrap().map_concrete(&self.generics).unwrap())
|
||||
.collect();
|
||||
|
||||
let concrete_generics_map: ConcreteGenericsAssignment = GGenericsAssignment(
|
||||
concrete_generics
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, g)| (GenericIdentifier::without_name().with_index(index), *g))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let mut internal_concretizer: StructConcretizer<'ast, T> =
|
||||
StructConcretizer::with_generics(concrete_generics_map);
|
||||
|
||||
DeclarationStructType {
|
||||
members: ty
|
||||
.members
|
||||
.into_iter()
|
||||
.map(|member| {
|
||||
DeclarationStructMember::new(
|
||||
member.id,
|
||||
internal_concretizer.fold_declaration_type(*member.ty),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
generics: concrete_generics
|
||||
.into_iter()
|
||||
.map(|g| Some(DeclarationConstant::Concrete(g as u32)))
|
||||
.collect(),
|
||||
..ty
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_declaration_array_type(
|
||||
&mut self,
|
||||
ty: DeclarationArrayType<'ast, T>,
|
||||
) -> DeclarationArrayType<'ast, T> {
|
||||
let size = ty.size.map_concrete(&self.generics).unwrap();
|
||||
|
||||
DeclarationArrayType {
|
||||
size: DeclarationConstant::Concrete(size),
|
||||
ty: box self.fold_declaration_type(*ty.ty),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,10 +37,9 @@ impl<'ast> VariableWriteRemover {
|
|||
let inner_ty = base.inner_type();
|
||||
let size = base.size();
|
||||
|
||||
let size = match size.as_inner() {
|
||||
UExpressionInner::Value(v) => *v as u32,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
|
||||
let size: u32 = size.try_into().unwrap();
|
||||
|
||||
let head = indices.remove(0);
|
||||
let tail = indices;
|
||||
|
|
|
@ -226,12 +226,12 @@ mod tests {
|
|||
ty: ConcreteType::Struct(ConcreteStructType::new(
|
||||
"".into(),
|
||||
"Bar".into(),
|
||||
vec![Some(1usize)],
|
||||
vec![Some(1u32)],
|
||||
vec![ConcreteStructMember::new(
|
||||
String::from("a"),
|
||||
ConcreteType::Array(ConcreteArrayType::new(
|
||||
ConcreteType::FieldElement,
|
||||
1usize,
|
||||
1u32,
|
||||
)),
|
||||
)],
|
||||
)),
|
||||
|
@ -395,7 +395,7 @@ mod tests {
|
|||
ConcreteStructMember::new(String::from("c"), ConcreteType::Boolean),
|
||||
],
|
||||
)),
|
||||
2usize,
|
||||
2u32,
|
||||
)),
|
||||
}],
|
||||
outputs: vec![ConcreteType::Boolean],
|
||||
|
@ -449,8 +449,8 @@ mod tests {
|
|||
name: String::from("a"),
|
||||
public: false,
|
||||
ty: ConcreteType::Array(ConcreteArrayType::new(
|
||||
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2usize)),
|
||||
2usize,
|
||||
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2u32)),
|
||||
2u32,
|
||||
)),
|
||||
}],
|
||||
outputs: vec![ConcreteType::FieldElement],
|
||||
|
|
|
@ -122,7 +122,14 @@ pub trait Folder<'ast, T: Field>: Sized {
|
|||
}
|
||||
|
||||
fn fold_name(&mut self, n: Identifier<'ast>) -> Identifier<'ast> {
|
||||
n
|
||||
let id = match n.id {
|
||||
CoreIdentifier::Constant(c) => {
|
||||
CoreIdentifier::Constant(self.fold_canonical_constant_identifier(c))
|
||||
}
|
||||
id => id,
|
||||
};
|
||||
|
||||
Identifier { id, ..n }
|
||||
}
|
||||
|
||||
fn fold_variable(&mut self, v: Variable<'ast, T>) -> Variable<'ast, T> {
|
||||
|
@ -1027,6 +1034,9 @@ pub fn fold_declaration_constant<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
) -> DeclarationConstant<'ast, T> {
|
||||
match c {
|
||||
DeclarationConstant::Expression(e) => DeclarationConstant::Expression(f.fold_expression(e)),
|
||||
DeclarationConstant::Constant(c) => {
|
||||
DeclarationConstant::Constant(f.fold_canonical_constant_identifier(c))
|
||||
}
|
||||
c => c,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1203,9 +1203,9 @@ impl<'ast, T> IntoIterator for ArrayValue<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Clone + fmt::Debug> ArrayValue<'ast, T> {
|
||||
impl<'ast, T: Clone> ArrayValue<'ast, T> {
|
||||
fn expression_at_aux<
|
||||
U: Select<'ast, T> + Into<TypedExpression<'ast, T>> + From<TypedExpression<'ast, T>>,
|
||||
U: Select<'ast, T> + From<TypedExpression<'ast, T>> + Into<TypedExpression<'ast, T>>,
|
||||
>(
|
||||
v: TypedExpressionOrSpread<'ast, T>,
|
||||
) -> Vec<Option<U>> {
|
||||
|
@ -1236,7 +1236,7 @@ impl<'ast, T: Clone + fmt::Debug> ArrayValue<'ast, T> {
|
|||
}
|
||||
|
||||
pub fn expression_at<
|
||||
U: Select<'ast, T> + Into<TypedExpression<'ast, T>> + From<TypedExpression<'ast, T>>,
|
||||
U: Select<'ast, T> + From<TypedExpression<'ast, T>> + Into<TypedExpression<'ast, T>>,
|
||||
>(
|
||||
&self,
|
||||
index: usize,
|
||||
|
|
|
@ -150,7 +150,14 @@ pub trait ResultFolder<'ast, T: Field>: Sized {
|
|||
}
|
||||
|
||||
fn fold_name(&mut self, n: Identifier<'ast>) -> Result<Identifier<'ast>, Self::Error> {
|
||||
Ok(n)
|
||||
let id = match n.id {
|
||||
CoreIdentifier::Constant(c) => {
|
||||
CoreIdentifier::Constant(self.fold_canonical_constant_identifier(c)?)
|
||||
}
|
||||
id => id,
|
||||
};
|
||||
|
||||
Ok(Identifier { id, ..n })
|
||||
}
|
||||
|
||||
fn fold_variable(&mut self, v: Variable<'ast, T>) -> Result<Variable<'ast, T>, Self::Error> {
|
||||
|
@ -214,8 +221,8 @@ pub trait ResultFolder<'ast, T: Field>: Sized {
|
|||
fn fold_select_expression<
|
||||
E: Expr<'ast, T>
|
||||
+ Select<'ast, T>
|
||||
+ From<TypedExpression<'ast, T>>
|
||||
+ Into<TypedExpression<'ast, T>>,
|
||||
+ Into<TypedExpression<'ast, T>>
|
||||
+ From<TypedExpression<'ast, T>>,
|
||||
>(
|
||||
&mut self,
|
||||
ty: &E::Ty,
|
||||
|
@ -1072,6 +1079,9 @@ pub fn fold_declaration_constant<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
DeclarationConstant::Expression(e) => {
|
||||
Ok(DeclarationConstant::Expression(f.fold_expression(e)?))
|
||||
}
|
||||
DeclarationConstant::Constant(c) => Ok(DeclarationConstant::Constant(
|
||||
f.fold_canonical_constant_identifier(c)?,
|
||||
)),
|
||||
c => Ok(c),
|
||||
}
|
||||
}
|
||||
|
@ -1238,11 +1248,14 @@ pub fn fold_program<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
p: TypedProgram<'ast, T>,
|
||||
) -> Result<TypedProgram<'ast, T>, F::Error> {
|
||||
Ok(TypedProgram {
|
||||
main: f.fold_module_id(p.main)?,
|
||||
modules: p
|
||||
.modules
|
||||
.into_iter()
|
||||
.map(|(module_id, module)| f.fold_module(module).map(|m| (module_id, m)))
|
||||
.map(|(module_id, module)| {
|
||||
let module_id = f.fold_module_id(module_id)?;
|
||||
f.fold_module(module).map(|m| (module_id, m))
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
main: f.fold_module_id(p.main)?,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -59,21 +59,39 @@ impl<'ast, T> Types<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, Ord)]
|
||||
#[derive(Debug, Clone, Eq)]
|
||||
pub struct GenericIdentifier<'ast> {
|
||||
pub name: &'ast str,
|
||||
pub index: usize,
|
||||
name: Option<&'ast str>,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'ast> GenericIdentifier<'ast> {
|
||||
pub fn with_name(name: &'ast str) -> Self {
|
||||
Self { name, index: 0 }
|
||||
pub fn without_name() -> Self {
|
||||
Self {
|
||||
name: None,
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn index(mut self, index: usize) -> Self {
|
||||
pub fn with_name(name: &'ast str) -> Self {
|
||||
Self {
|
||||
name: Some(name),
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_index(mut self, index: usize) -> Self {
|
||||
self.index = index;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &'ast str {
|
||||
self.name.unwrap()
|
||||
}
|
||||
|
||||
pub fn index(&self) -> usize {
|
||||
self.index
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> PartialEq for GenericIdentifier<'ast> {
|
||||
|
@ -88,6 +106,12 @@ impl<'ast> PartialOrd for GenericIdentifier<'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast> Ord for GenericIdentifier<'ast> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.partial_cmp(other).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> Hash for GenericIdentifier<'ast> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.index.hash(state);
|
||||
|
@ -96,7 +120,7 @@ impl<'ast> Hash for GenericIdentifier<'ast> {
|
|||
|
||||
impl<'ast> fmt::Display for GenericIdentifier<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
write!(f, "{}", self.name())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +155,34 @@ pub enum DeclarationConstant<'ast, T> {
|
|||
Expression(TypedExpression<'ast, T>),
|
||||
}
|
||||
|
||||
impl<'ast, T> DeclarationConstant<'ast, T> {
|
||||
pub fn map<S: From<CanonicalConstantIdentifier<'ast>> + From<u32> + Clone>(
|
||||
self,
|
||||
generics: &GGenericsAssignment<'ast, S>,
|
||||
) -> Result<S, GenericIdentifier<'ast>> {
|
||||
match self {
|
||||
DeclarationConstant::Generic(g) => generics.0.get(&g).cloned().ok_or(g),
|
||||
DeclarationConstant::Concrete(v) => Ok(v.into()),
|
||||
DeclarationConstant::Constant(c) => Ok(c.into()),
|
||||
DeclarationConstant::Expression(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_concrete<S: From<u32> + Clone>(
|
||||
self,
|
||||
generics: &GGenericsAssignment<'ast, S>,
|
||||
) -> Result<S, GenericIdentifier<'ast>> {
|
||||
match self {
|
||||
DeclarationConstant::Constant(_) => unreachable!(
|
||||
"called map_concrete on a constant, it should have been resolved before"
|
||||
),
|
||||
DeclarationConstant::Generic(g) => generics.0.get(&g).cloned().ok_or(g),
|
||||
DeclarationConstant::Concrete(v) => Ok(v.into()),
|
||||
DeclarationConstant::Expression(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: PartialEq> PartialEq<UExpression<'ast, T>> for DeclarationConstant<'ast, T> {
|
||||
fn eq(&self, other: &UExpression<'ast, T>) -> bool {
|
||||
match (self, other) {
|
||||
|
@ -184,8 +236,8 @@ impl<'ast, T: fmt::Display> fmt::Display for DeclarationConstant<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> From<usize> for UExpression<'ast, T> {
|
||||
fn from(i: usize) -> Self {
|
||||
impl<'ast, T> From<u32> for UExpression<'ast, T> {
|
||||
fn from(i: u32) -> Self {
|
||||
UExpressionInner::Value(i as u128).annotate(UBitwidth::B32)
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +246,7 @@ impl<'ast, T> From<DeclarationConstant<'ast, T>> for UExpression<'ast, T> {
|
|||
fn from(c: DeclarationConstant<'ast, T>) -> Self {
|
||||
match c {
|
||||
DeclarationConstant::Generic(i) => {
|
||||
UExpressionInner::Identifier(i.name.into()).annotate(UBitwidth::B32)
|
||||
UExpressionInner::Identifier(i.name().into()).annotate(UBitwidth::B32)
|
||||
}
|
||||
DeclarationConstant::Concrete(v) => {
|
||||
UExpressionInner::Value(v as u128).annotate(UBitwidth::B32)
|
||||
|
@ -208,14 +260,14 @@ impl<'ast, T> From<DeclarationConstant<'ast, T>> for UExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> TryInto<usize> for UExpression<'ast, T> {
|
||||
impl<'ast, T> TryInto<u32> for UExpression<'ast, T> {
|
||||
type Error = SpecializationError;
|
||||
|
||||
fn try_into(self) -> Result<usize, Self::Error> {
|
||||
fn try_into(self) -> Result<u32, Self::Error> {
|
||||
assert_eq!(self.bitwidth, UBitwidth::B32);
|
||||
|
||||
match self.into_inner() {
|
||||
UExpressionInner::Value(v) => Ok(v as usize),
|
||||
UExpressionInner::Value(v) => Ok(v as u32),
|
||||
_ => Err(SpecializationError),
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +295,7 @@ pub struct GStructMember<S> {
|
|||
}
|
||||
|
||||
pub type DeclarationStructMember<'ast, T> = GStructMember<DeclarationConstant<'ast, T>>;
|
||||
pub type ConcreteStructMember = GStructMember<usize>;
|
||||
pub type ConcreteStructMember = GStructMember<u32>;
|
||||
pub type StructMember<'ast, T> = GStructMember<UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, S, R: PartialEq<S>> PartialEq<GStructMember<S>> for GStructMember<R> {
|
||||
|
@ -283,7 +335,7 @@ pub struct GArrayType<S> {
|
|||
}
|
||||
|
||||
pub type DeclarationArrayType<'ast, T> = GArrayType<DeclarationConstant<'ast, T>>;
|
||||
pub type ConcreteArrayType = GArrayType<usize>;
|
||||
pub type ConcreteArrayType = GArrayType<u32>;
|
||||
pub type ArrayType<'ast, T> = GArrayType<UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, S, R: PartialEq<S>> PartialEq<GArrayType<S>> for GArrayType<R> {
|
||||
|
@ -365,7 +417,7 @@ pub struct GStructType<S> {
|
|||
}
|
||||
|
||||
pub type DeclarationStructType<'ast, T> = GStructType<DeclarationConstant<'ast, T>>;
|
||||
pub type ConcreteStructType = GStructType<usize>;
|
||||
pub type ConcreteStructType = GStructType<u32>;
|
||||
pub type StructType<'ast, T> = GStructType<UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, S, R: PartialEq<S>> PartialEq<GStructType<S>> for GStructType<R> {
|
||||
|
@ -377,8 +429,7 @@ impl<'ast, S, R: PartialEq<S>> PartialEq<GStructType<S>> for GStructType<R> {
|
|||
.zip(other.generics.iter())
|
||||
.all(|(a, b)| match (a, b) {
|
||||
(Some(a), Some(b)) => a == b,
|
||||
(None, None) => true,
|
||||
_ => false,
|
||||
_ => true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -622,7 +673,7 @@ impl<'de, S: Deserialize<'de>> Deserialize<'de> for GType<S> {
|
|||
}
|
||||
|
||||
pub type DeclarationType<'ast, T> = GType<DeclarationConstant<'ast, T>>;
|
||||
pub type ConcreteType = GType<usize>;
|
||||
pub type ConcreteType = GType<u32>;
|
||||
pub type Type<'ast, T> = GType<UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, S, R: PartialEq<S>> PartialEq<GType<S>> for GType<R> {
|
||||
|
@ -811,7 +862,9 @@ impl ConcreteType {
|
|||
GType::FieldElement => 1,
|
||||
GType::Boolean => 1,
|
||||
GType::Uint(_) => 1,
|
||||
GType::Array(array_type) => array_type.size * array_type.ty.get_primitive_count(),
|
||||
GType::Array(array_type) => {
|
||||
array_type.size as usize * array_type.ty.get_primitive_count()
|
||||
}
|
||||
GType::Int => unreachable!(),
|
||||
GType::Struct(struct_type) => struct_type
|
||||
.iter()
|
||||
|
@ -831,7 +884,7 @@ pub struct GFunctionKey<'ast, S> {
|
|||
}
|
||||
|
||||
pub type DeclarationFunctionKey<'ast, T> = GFunctionKey<'ast, DeclarationConstant<'ast, T>>;
|
||||
pub type ConcreteFunctionKey<'ast> = GFunctionKey<'ast, usize>;
|
||||
pub type ConcreteFunctionKey<'ast> = GFunctionKey<'ast, u32>;
|
||||
pub type FunctionKey<'ast, T> = GFunctionKey<'ast, UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, S: fmt::Display> fmt::Display for GFunctionKey<'ast, S> {
|
||||
|
@ -843,7 +896,7 @@ impl<'ast, S: fmt::Display> fmt::Display for GFunctionKey<'ast, S> {
|
|||
#[derive(Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
|
||||
pub struct GGenericsAssignment<'ast, S>(pub BTreeMap<GenericIdentifier<'ast>, S>);
|
||||
|
||||
pub type ConcreteGenericsAssignment<'ast> = GGenericsAssignment<'ast, usize>;
|
||||
pub type ConcreteGenericsAssignment<'ast> = GGenericsAssignment<'ast, u32>;
|
||||
pub type GenericsAssignment<'ast, T> = GGenericsAssignment<'ast, UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, S> Default for GGenericsAssignment<'ast, S> {
|
||||
|
@ -943,32 +996,50 @@ impl<'ast> ConcreteFunctionKey<'ast> {
|
|||
|
||||
use std::collections::btree_map::Entry;
|
||||
|
||||
pub fn check_type<'ast, T, S: Clone + PartialEq + PartialEq<usize>>(
|
||||
// check an optional generic value against the corresponding declaration constant
|
||||
// if None is provided, return true
|
||||
// if some value is provided, insert it into the map or check that it doesn't conflict if a value is already thereq
|
||||
pub fn check_generic<'ast, T, S: Clone + PartialEq + PartialEq<u32>>(
|
||||
generic: &DeclarationConstant<'ast, T>,
|
||||
value: Option<&S>,
|
||||
constants: &mut GGenericsAssignment<'ast, S>,
|
||||
) -> bool {
|
||||
value
|
||||
.map(|value| match generic {
|
||||
// if the generic is an identifier, we insert into the map, or check if the concrete size
|
||||
// matches if this identifier is already in the map
|
||||
DeclarationConstant::Generic(id) => match constants.0.entry(id.clone()) {
|
||||
Entry::Occupied(e) => *e.get() == *value,
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(value.clone());
|
||||
true
|
||||
}
|
||||
},
|
||||
DeclarationConstant::Concrete(generic) => *value == *generic,
|
||||
// in the case of a constant, we do not know the value yet, so we optimistically assume it's correct
|
||||
// if it does not match, it will be caught during inlining
|
||||
DeclarationConstant::Constant(..) => true,
|
||||
DeclarationConstant::Expression(e) => match e {
|
||||
TypedExpression::Uint(e) => match e.as_inner() {
|
||||
UExpressionInner::Value(v) => *value == *v as u32,
|
||||
_ => true,
|
||||
},
|
||||
_ => unreachable!(),
|
||||
},
|
||||
})
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
pub fn check_type<'ast, T, S: Clone + PartialEq + PartialEq<u32>>(
|
||||
decl_ty: &DeclarationType<'ast, T>,
|
||||
ty: >ype<S>,
|
||||
constants: &mut GGenericsAssignment<'ast, S>,
|
||||
) -> bool {
|
||||
match (decl_ty, ty) {
|
||||
(DeclarationType::Array(t0), GType::Array(t1)) => {
|
||||
let s1 = t1.size.clone();
|
||||
|
||||
// both the inner type and the size must match
|
||||
check_type(&t0.ty, &t1.ty, constants)
|
||||
&& match &t0.size {
|
||||
// if the declared size is an identifier, we insert into the map, or check if the concrete size
|
||||
// matches if this identifier is already in the map
|
||||
DeclarationConstant::Generic(id) => match constants.0.entry(id.clone()) {
|
||||
Entry::Occupied(e) => *e.get() == s1,
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(s1);
|
||||
true
|
||||
}
|
||||
},
|
||||
DeclarationConstant::Concrete(s0) => s1 == *s0 as usize,
|
||||
// in the other cases, we do not know the value yet, so we optimistically assume it's correct
|
||||
// if it does not match, it will be caught during inlining
|
||||
DeclarationConstant::Constant(..) | DeclarationConstant::Expression(..) => true,
|
||||
}
|
||||
&& check_generic(&t0.size, Some(&t1.size), constants)
|
||||
}
|
||||
(DeclarationType::FieldElement, GType::FieldElement)
|
||||
| (DeclarationType::Boolean, GType::Boolean) => true,
|
||||
|
@ -976,10 +1047,10 @@ pub fn check_type<'ast, T, S: Clone + PartialEq + PartialEq<usize>>(
|
|||
(DeclarationType::Struct(s0), GType::Struct(s1)) => {
|
||||
s0.canonical_location == s1.canonical_location
|
||||
&& s0
|
||||
.members
|
||||
.generics
|
||||
.iter()
|
||||
.zip(s1.members.iter())
|
||||
.all(|(m0, m1)| check_type(&*m0.ty, &*m1.ty, constants))
|
||||
.zip(s1.generics.iter())
|
||||
.all(|(g0, g1)| check_generic(g0.as_ref().unwrap(), g1.as_ref(), constants))
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
@ -1000,7 +1071,7 @@ impl<'ast, T> From<CanonicalConstantIdentifier<'ast>> for DeclarationConstant<'a
|
|||
|
||||
pub fn specialize_declaration_type<
|
||||
'ast,
|
||||
T,
|
||||
T: Clone,
|
||||
S: Clone + PartialEq + From<u32> + fmt::Debug + From<CanonicalConstantIdentifier<'ast>>,
|
||||
>(
|
||||
decl_ty: DeclarationType<'ast, T>,
|
||||
|
@ -1010,46 +1081,53 @@ pub fn specialize_declaration_type<
|
|||
DeclarationType::Int => unreachable!(),
|
||||
DeclarationType::Array(t0) => {
|
||||
let ty = box specialize_declaration_type(*t0.ty, generics)?;
|
||||
let size = match t0.size {
|
||||
DeclarationConstant::Generic(s) => generics.0.get(&s).cloned().ok_or(s),
|
||||
DeclarationConstant::Concrete(s) => Ok(s.into()),
|
||||
DeclarationConstant::Constant(c) => Ok(c.into()),
|
||||
DeclarationConstant::Expression(..) => unreachable!("the semantic checker should not yield this DeclarationConstant variant")
|
||||
}?;
|
||||
let size = t0.size.map(generics)?;
|
||||
|
||||
GType::Array(GArrayType { size, ty })
|
||||
}
|
||||
DeclarationType::FieldElement => GType::FieldElement,
|
||||
DeclarationType::Boolean => GType::Boolean,
|
||||
DeclarationType::Uint(b0) => GType::Uint(b0),
|
||||
DeclarationType::Struct(s0) => GType::Struct(GStructType {
|
||||
members: s0
|
||||
.members
|
||||
.into_iter()
|
||||
.map(|m| {
|
||||
let id = m.id;
|
||||
specialize_declaration_type(*m.ty, generics)
|
||||
.map(|ty| GStructMember { ty: box ty, id })
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
generics: s0
|
||||
.generics
|
||||
.into_iter()
|
||||
.map(|g| match g {
|
||||
Some(constant) => match constant {
|
||||
DeclarationConstant::Generic(s) => {
|
||||
generics.0.get(&s).cloned().ok_or(s).map(Some)
|
||||
}
|
||||
DeclarationConstant::Concrete(s) => Ok(Some(s.into())),
|
||||
DeclarationConstant::Constant(c) => Ok(Some(c.into())),
|
||||
DeclarationConstant::Expression(..) => unreachable!("the semantic checker should not yield this DeclarationConstant variant"),
|
||||
},
|
||||
_ => Ok(None),
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
canonical_location: s0.canonical_location,
|
||||
location: s0.location,
|
||||
}),
|
||||
DeclarationType::Struct(s0) => {
|
||||
// here we specialize Foo<Generics> {FooDef<InsideGenerics>} with some values for Generics
|
||||
// we need to remap these values for InsideGenerics to then visit the members
|
||||
|
||||
let inside_generics = GGenericsAssignment(
|
||||
s0.generics
|
||||
.clone()
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, g)| {
|
||||
(
|
||||
GenericIdentifier::without_name().with_index(index),
|
||||
g.map(|g| g.map(generics).unwrap()).unwrap(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
|
||||
GType::Struct(GStructType {
|
||||
members: s0
|
||||
.members
|
||||
.into_iter()
|
||||
.map(|m| {
|
||||
let id = m.id;
|
||||
specialize_declaration_type(*m.ty, &inside_generics)
|
||||
.map(|ty| GStructMember { ty: box ty, id })
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
generics: s0
|
||||
.generics
|
||||
.into_iter()
|
||||
.map(|g| match g {
|
||||
Some(constant) => constant.map(generics).map(Some),
|
||||
_ => Ok(None),
|
||||
})
|
||||
.collect::<Result<_, _>>()?,
|
||||
canonical_location: s0.canonical_location,
|
||||
location: s0.location,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1107,7 +1185,7 @@ pub mod signature {
|
|||
}
|
||||
|
||||
pub type DeclarationSignature<'ast, T> = GSignature<DeclarationConstant<'ast, T>>;
|
||||
pub type ConcreteSignature = GSignature<usize>;
|
||||
pub type ConcreteSignature = GSignature<u32>;
|
||||
pub type Signature<'ast, T> = GSignature<UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, T> PartialEq<DeclarationSignature<'ast, T>> for ConcreteSignature {
|
||||
|
@ -1120,7 +1198,7 @@ pub mod signature {
|
|||
.iter()
|
||||
.chain(other.outputs.iter())
|
||||
.zip(self.inputs.iter().chain(self.outputs.iter()))
|
||||
.all(|(decl_ty, ty)| check_type::<T, usize>(decl_ty, ty, &mut constants))
|
||||
.all(|(decl_ty, ty)| check_type::<T, u32>(decl_ty, ty, &mut constants))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1223,7 @@ pub mod signature {
|
|||
constants.0.extend(
|
||||
decl_generics
|
||||
.zip(values.into_iter())
|
||||
.filter_map(|(g, v)| v.map(|v| (g, v as usize))),
|
||||
.filter_map(|(g, v)| v.map(|v| (g, v))),
|
||||
);
|
||||
|
||||
let condition = self
|
||||
|
@ -1378,33 +1456,19 @@ pub mod signature {
|
|||
|
||||
let generic1 = DeclarationSignature::<Bn128Field>::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier {
|
||||
name: "P",
|
||||
index: 0,
|
||||
}
|
||||
.into(),
|
||||
GenericIdentifier::with_name("P").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::array(DeclarationArrayType::new(
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier {
|
||||
name: "P",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("P").with_index(0),
|
||||
))]);
|
||||
let generic2 = DeclarationSignature::new()
|
||||
.generics(vec![Some(
|
||||
GenericIdentifier {
|
||||
name: "Q",
|
||||
index: 0,
|
||||
}
|
||||
.into(),
|
||||
GenericIdentifier::with_name("Q").with_index(0).into(),
|
||||
)])
|
||||
.inputs(vec![DeclarationType::array(DeclarationArrayType::new(
|
||||
DeclarationType::FieldElement,
|
||||
GenericIdentifier {
|
||||
name: "Q",
|
||||
index: 0,
|
||||
},
|
||||
GenericIdentifier::with_name("Q").with_index(0),
|
||||
))]);
|
||||
|
||||
assert_eq!(generic1, generic2);
|
||||
|
@ -1469,8 +1533,8 @@ pub mod signature {
|
|||
fn array_slug() {
|
||||
let s = ConcreteSignature::new()
|
||||
.inputs(vec![
|
||||
ConcreteType::array((ConcreteType::FieldElement, 42usize)),
|
||||
ConcreteType::array((ConcreteType::FieldElement, 21usize)),
|
||||
ConcreteType::array((ConcreteType::FieldElement, 42u32)),
|
||||
ConcreteType::array((ConcreteType::FieldElement, 21u32)),
|
||||
])
|
||||
.outputs(vec![]);
|
||||
|
||||
|
@ -1485,7 +1549,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn array() {
|
||||
let t = ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 42usize));
|
||||
let t = ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 42u32));
|
||||
assert_eq!(t.get_primitive_count(), 42);
|
||||
}
|
||||
|
||||
|
@ -1493,8 +1557,8 @@ mod tests {
|
|||
fn array_display() {
|
||||
// field[1][2]
|
||||
let t = ConcreteType::Array(ConcreteArrayType::new(
|
||||
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2usize)),
|
||||
1usize,
|
||||
ConcreteType::Array(ConcreteArrayType::new(ConcreteType::FieldElement, 2u32)),
|
||||
1u32,
|
||||
));
|
||||
assert_eq!(format!("{}", t), "field[1][2]");
|
||||
}
|
||||
|
|
|
@ -146,12 +146,6 @@ pub struct UExpression<'ast, T> {
|
|||
pub inner: UExpressionInner<'ast, T>,
|
||||
}
|
||||
|
||||
impl<'ast, T> From<u32> for UExpression<'ast, T> {
|
||||
fn from(u: u32) -> Self {
|
||||
UExpressionInner::Value(u as u128).annotate(UBitwidth::B32)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> From<u16> for UExpression<'ast, T> {
|
||||
fn from(u: u16) -> Self {
|
||||
UExpressionInner::Value(u as u128).annotate(UBitwidth::B16)
|
||||
|
@ -164,8 +158,8 @@ impl<'ast, T> From<u8> for UExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> PartialEq<usize> for UExpression<'ast, T> {
|
||||
fn eq(&self, other: &usize) -> bool {
|
||||
impl<'ast, T> PartialEq<u32> for UExpression<'ast, T> {
|
||||
fn eq(&self, other: &u32) -> bool {
|
||||
match self.as_inner() {
|
||||
UExpressionInner::Value(v) => *v == *other as u128,
|
||||
_ => true,
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct GVariable<'ast, S> {
|
|||
}
|
||||
|
||||
pub type DeclarationVariable<'ast, T> = GVariable<'ast, DeclarationConstant<'ast, T>>;
|
||||
pub type ConcreteVariable<'ast> = GVariable<'ast, usize>;
|
||||
pub type ConcreteVariable<'ast> = GVariable<'ast, u32>;
|
||||
pub type Variable<'ast, T> = GVariable<'ast, UExpression<'ast, T>>;
|
||||
|
||||
impl<'ast, T> TryFrom<Variable<'ast, T>> for ConcreteVariable<'ast> {
|
||||
|
|
|
@ -11,7 +11,7 @@ pub enum Identifier<'ast> {
|
|||
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
||||
pub enum SourceIdentifier<'ast> {
|
||||
Basic(CoreIdentifier<'ast>),
|
||||
Select(Box<SourceIdentifier<'ast>>, usize),
|
||||
Select(Box<SourceIdentifier<'ast>>, u32),
|
||||
Member(Box<SourceIdentifier<'ast>>, MemberId),
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,10 @@ use zokrates_fs_resolver::FileSystemResolver;
|
|||
#[test]
|
||||
fn lt_field() {
|
||||
let source = r#"
|
||||
def main(private field a, private field b) -> field:
|
||||
def main(private field a, private field b):
|
||||
field x = if a < b then 3333 else 4444 fi
|
||||
assert(x == 3333)
|
||||
return 1
|
||||
return
|
||||
"#
|
||||
.to_string();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_core_test"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
authors = ["schaeff <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
16
zokrates_core_test/tests/tests/compare_min_to_max.json
Normal file
16
zokrates_core_test/tests/tests/compare_min_to_max.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/compare_min_to_max.zok",
|
||||
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["0"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["0"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
from "field" import FIELD_MAX
|
||||
|
||||
// as p - 1 is greater than p/2, comparing to it should fail
|
||||
// /!\ should be called with a = 0
|
||||
// as `|a - FIELD_MAX| < 2**(N-2)` the comparison should succeed
|
||||
|
||||
def main(field a) -> bool:
|
||||
field p = FIELD_MAX + a
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/constants/issue_1038/a.zok",
|
||||
"tests": []
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
from "./b" import SIZE_WORDS
|
||||
|
||||
def main(field[SIZE_WORDS] a):
|
||||
assert(a == [0; SIZE_WORDS])
|
||||
return
|
|
@ -0,0 +1,2 @@
|
|||
const u32 SIZE_BYTES = 136
|
||||
const u32 SIZE_WORDS = SIZE_BYTES/8
|
|
@ -0,0 +1,2 @@
|
|||
const u32 SIZE_BYTES = 136
|
||||
const u32 SIZE_WORDS = SIZE_BYTES/8
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/constants/issue_1038/reversed/b.zok",
|
||||
"tests": []
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
from "./a" import SIZE_WORDS
|
||||
|
||||
def main(field[SIZE_WORDS] a):
|
||||
assert(a == [0; SIZE_WORDS])
|
||||
return
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/constants/issue_1047/a.zok",
|
||||
"tests": []
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
from "./b" import B
|
||||
|
||||
def main():
|
||||
return
|
|
@ -0,0 +1,2 @@
|
|||
const field A = 1
|
||||
const field B = A + 1
|
|
@ -0,0 +1,2 @@
|
|||
const field A = 1
|
||||
const field B = A + 1
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/constants/issue_1047/reversed/b.zok",
|
||||
"tests": []
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
from "./a" import B
|
||||
|
||||
def main():
|
||||
return
|
|
@ -41,15 +41,6 @@
|
|||
"values": ["1", "1", "0", "0", "0", "0", "0", "1", "1", "0", "0", "1", "0", "0", "0", "1", "0", "0", "1", "1", "1", "0", "0", "1", "1", "1", "0", "0", "1", "0", "1", "1", "1", "0", "0", "0", "0", "1", "0", "0", "1", "1", "0", "0", "0", "1", "1", "0", "1", "0", "0", "0", "0", "0", "0", "0", "1", "0", "1", "0", "0", "1", "1", "0", "1", "1", "1", "0", "0", "0", "0", "1", "0", "1", "0", "0", "0", "0", "0", "1", "0", "0", "0", "1", "0", "1", "1", "0", "1", "1", "0", "1", "1", "0", "1", "0", "0", "0", "0", "0", "0", "1", "1", "0", "0", "0", "0", "0", "0", "1", "0", "1", "0", "1", "1", "0", "0", "0", "0", "1", "0", "1", "1", "1", "0", "1", "0", "0", "1", "0", "1", "0", "0", "0", "0", "0", "1", "1", "0", "0", "1", "1", "1", "1", "1", "0", "1", "0", "0", "0", "0", "1", "0", "0", "1", "0", "0", "0", "0", "1", "1", "1", "1", "0", "0", "1", "1", "0", "1", "1", "1", "0", "0", "1", "0", "1", "1", "1", "0", "0", "0", "0", "1", "0", "0", "1", "0", "0", "0", "1", "0", "1", "0", "0", "0", "0", "1", "1", "1", "1", "1", "0", "0", "0", "0", "1", "1", "1", "1", "1", "0", "1", "0", "1", "1", "0", "0", "1", "0", "0", "1", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"input": {
|
||||
"values": ["21888242871839275222246405745257275088548364400416034343698204186575808495617"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_embed"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
authors = ["schaeff <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
420
zokrates_js/Cargo.lock
generated
420
zokrates_js/Cargo.lock
generated
|
@ -4,26 +4,26 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.13.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
|
||||
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "0.2.3"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.4"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom 0.2.2",
|
||||
"getrandom 0.2.3",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
@ -90,7 +90,7 @@ dependencies = [
|
|||
"ark-serialize",
|
||||
"ark-std",
|
||||
"derivative",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
|
@ -105,7 +105,7 @@ dependencies = [
|
|||
"ark-serialize",
|
||||
"ark-std",
|
||||
"derivative",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
"rustc_version",
|
||||
"zeroize",
|
||||
]
|
||||
|
@ -116,8 +116,8 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e8cb28c2137af1ef058aa59616db3f7df67dbb70bf2be4ee6920008cc30d98c"
|
||||
dependencies = [
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -127,9 +127,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0b9c256a93a10ed9708c16a517d6dcfaba3d215c0d7fab44d29a9affefb5eeb8"
|
||||
dependencies = [
|
||||
"num-bigint 0.4.2",
|
||||
"num-traits 0.2.12",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"num-traits 0.2.14",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -164,7 +164,7 @@ dependencies = [
|
|||
"derivative",
|
||||
"num-bigint 0.4.2",
|
||||
"num-integer",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -193,7 +193,7 @@ dependencies = [
|
|||
"ark-std",
|
||||
"derivative",
|
||||
"num-bigint 0.4.2",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -224,9 +224,9 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ac3d78c750b01f5df5b2e76d106ed31487a93b3868f14a7f0eb3a74f45e1d8a"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -261,18 +261,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.50"
|
||||
version = "0.3.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293"
|
||||
checksum = "091bcdf2da9950f96aa522681ce805e6857f6ca8df73833d35736ab2dc78e152"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if 0.1.10",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
|
@ -308,9 +309,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.2"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
|
@ -353,7 +354,7 @@ dependencies = [
|
|||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.3",
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -367,9 +368,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.13"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
|
@ -379,9 +380,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.4.0"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
|
@ -391,9 +392,15 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
|||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
|
@ -409,11 +416,11 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "console_error_panic_hook"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
|
||||
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
|
@ -513,9 +520,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.3"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
|
@ -539,9 +546,9 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -550,7 +557,7 @@ version = "0.8.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3",
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -564,9 +571,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "failure"
|
||||
|
@ -584,9 +591,9 @@ version = "0.1.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
@ -627,10 +634,10 @@ checksum = "50c052fa6d4c2f12305ec364bfb8ef884836f3f61ea015b202372ff996d1ac4b"
|
|||
dependencies = [
|
||||
"num-bigint 0.2.6",
|
||||
"num-integer",
|
||||
"num-traits 0.2.12",
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"num-traits 0.2.14",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -651,9 +658,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
|||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
|
||||
checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -666,9 +673,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
|
||||
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -676,15 +683,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
|
||||
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
|
||||
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
|
@ -693,47 +700,45 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
|
||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
|
||||
checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.5"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
|
||||
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
@ -750,20 +755,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
|
@ -774,9 +779,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.22.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
||||
checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
|
@ -789,18 +794,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.15"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
|
@ -813,15 +818,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.6"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.42"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52732a3d3ad72c58ad2dc70624f9c17b46ecd0943b9a4f1ee37c4c18c5d983e2"
|
||||
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -834,17 +839,17 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.72"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
|
||||
checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -861,9 +866,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.3"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
|
@ -876,11 +881,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.0"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
|
||||
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -897,7 +903,7 @@ checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
|
|||
dependencies = [
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -908,7 +914,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
@ -920,7 +926,7 @@ checksum = "74e768dff5fb39a41b3bcd30bb25cf989706c90d028d1ad71971987aa309d535"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -930,18 +936,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.41"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
|
||||
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -950,14 +956,14 @@ version = "0.1.43"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
dependencies = [
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.12"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
@ -974,9 +980,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.20.0"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
|
||||
checksum = "c821014c18301591b89b843809ef953af9e3df0496c232d5c0611b0a52aac363"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
|
@ -1047,9 +1056,9 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
|||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1073,32 +1082,12 @@ dependencies = [
|
|||
"blake2-rfc",
|
||||
"byteorder",
|
||||
"crossbeam",
|
||||
"getrandom 0.2.2",
|
||||
"getrandom 0.2.3",
|
||||
"num_cpus",
|
||||
"pairing_ce",
|
||||
"rand 0.4.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.7"
|
||||
|
@ -1113,9 +1102,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.9"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
|
||||
checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
|
@ -1128,11 +1117,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.1",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1146,11 +1135,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.7"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"proc-macro2 1.0.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1172,7 +1161,7 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.15",
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core 0.5.1",
|
||||
|
@ -1210,7 +1199,7 @@ version = "0.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.15",
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1242,9 +1231,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "reduce"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c8549eb79c1fc8c449cb18a2d9b7873a7cb1bf2fcbfe8a3ad8812320544341"
|
||||
checksum = "16d2dc47b68ac15ea328cd7ebe01d7d512ed29787f7d534ad2a3c341328b35d7"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
|
@ -1261,12 +1250,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
|
@ -1279,9 +1265,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.16"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
|
@ -1341,29 +1327,29 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.114"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
|
||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.114"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.56"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3"
|
||||
checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1405,9 +1391,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.2"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
|
@ -1428,25 +1414,25 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.34"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
|
||||
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"unicode-xid 0.2.1",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.4"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"unicode-xid 0.2.1",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"unicode-xid 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1469,9 +1455,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.28"
|
||||
version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8"
|
||||
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
|
@ -1481,20 +1467,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.16"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98863d0dd09fa59a1b79c6750ad80dbda6b75f4e71c437a6a1a8cb91a8bcbd77"
|
||||
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.20"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46125608c26121c81b0c6d693eab5a420e416da7e43c426d2e8f7df8da8a3acf"
|
||||
checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
|
@ -1504,9 +1490,9 @@ checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
|||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.12.0"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
|
||||
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
|
@ -1528,9 +1514,9 @@ checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
|
@ -1564,11 +1550,11 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.65"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3edbcc9536ab7eababcc6d2374a0b7bfe13a2b6d562c5e07f370456b1a8f33d"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen-macro",
|
||||
|
@ -1576,53 +1562,53 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.65"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ed2fb8c84bfad20ea66b26a3743f3e7ba8735a69fe7d95118c33ec8fc1244d"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.65"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb071268b031a64d92fc6cf691715ca5a40950694d8f683c5bb43db7c730929e"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
dependencies = [
|
||||
"quote 1.0.7",
|
||||
"quote 1.0.10",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.65"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf592c807080719d1ff2f245a687cbadb3ed28b2077ed7084b47aba8b691f2c6"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.65"
|
||||
version = "0.2.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b6c0220ded549d63860c78c38f3bcc558d1ca3f4efa74942c536ddbbb55e87"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.42"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be2398f326b7ba09815d0b403095f34dd708579220d099caae89be0b32137b2"
|
||||
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
@ -1665,9 +1651,9 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.18",
|
||||
"quote 1.0.7",
|
||||
"syn 1.0.34",
|
||||
"proc-macro2 1.0.30",
|
||||
"quote 1.0.10",
|
||||
"syn 1.0.80",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
@ -1688,14 +1674,14 @@ version = "0.1.0"
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_core"
|
||||
version = "0.6.7"
|
||||
version = "0.6.8"
|
||||
dependencies = [
|
||||
"bellman_ce",
|
||||
"bincode",
|
||||
"cfg-if 0.1.10",
|
||||
"csv",
|
||||
"ff_ce 0.9.0",
|
||||
"getrandom 0.2.2",
|
||||
"getrandom 0.2.3",
|
||||
"hex",
|
||||
"lazy_static",
|
||||
"log",
|
||||
|
@ -1718,7 +1704,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_embed"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-bw6-761",
|
||||
|
@ -1743,7 +1729,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"num-bigint 0.2.6",
|
||||
"num-integer",
|
||||
"num-traits 0.2.12",
|
||||
"num-traits 0.2.14",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
|
@ -1752,7 +1738,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_js"
|
||||
version = "1.0.36"
|
||||
version = "1.0.37"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
|
@ -1767,7 +1753,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_parser"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
|
@ -1775,7 +1761,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_pest_ast"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
dependencies = [
|
||||
"from-pest",
|
||||
"lazy_static",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_js"
|
||||
version = "1.0.36"
|
||||
version = "1.0.37"
|
||||
authors = ["Darko Macesic"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
6624
zokrates_js/package-lock.json
generated
6624
zokrates_js/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
|||
"name": "zokrates-js",
|
||||
"main": "index.js",
|
||||
"author": "Darko Macesic <darem966@gmail.com>",
|
||||
"version": "1.0.36",
|
||||
"version": "1.0.37",
|
||||
"keywords": [
|
||||
"zokrates",
|
||||
"wasm-bindgen",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_parser"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
authors = ["JacobEberhardt <jacob.eberhardt@tu-berlin.de>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ ace.define("ace/mode/zokrates_highlight_rules",["require","exports","module","ac
|
|||
var ZoKratesHighlightRules = function () {
|
||||
|
||||
var keywords = (
|
||||
"assert|as|bool|byte|const|def|do|else|endfor|export|false|field|for|if|then|fi|import|from|in|private|public|return|struct|true|u8|u16|u32|u64"
|
||||
"assert|as|bool|byte|const|def|do|else|endfor|export|false|field|for|if|then|fi|import|from|in|private|public|return|struct|true|type|u8|u16|u32|u64"
|
||||
);
|
||||
|
||||
var keywordMapper = this.createKeywordMapper({
|
||||
|
|
|
@ -202,19 +202,23 @@ repository:
|
|||
-
|
||||
comment: 'control flow keywords'
|
||||
name: keyword.control.zokrates
|
||||
match: \b(do|else|for|do|endfor|if|then|fi|return|assert)\b
|
||||
match: \b(for|in|do|endfor|if|then|else|fi|return|assert)\b
|
||||
-
|
||||
comment: 'storage keywords'
|
||||
name: storage.type.zokrates
|
||||
match: \b(struct)\b
|
||||
-
|
||||
comment: const
|
||||
comment: 'const keyword'
|
||||
name: keyword.other.const.zokrates
|
||||
match: \bconst\b
|
||||
match: \b(const)\b
|
||||
-
|
||||
comment: def
|
||||
comment: 'type keyword'
|
||||
name: keyword.other.type.zokrates
|
||||
match: \b(type)\b
|
||||
-
|
||||
comment: 'def keyword'
|
||||
name: keyword.other.def.zokrates
|
||||
match: \bdef\b
|
||||
match: \b(def)\b
|
||||
-
|
||||
comment: 'import keywords'
|
||||
name: keyword.other.import.zokrates
|
||||
|
|
|
@ -6,7 +6,7 @@ curve = @{ (ASCII_ALPHANUMERIC | "_") * }
|
|||
string = @{(!"\"" ~ ANY)*}
|
||||
quoted_string = _{ "\"" ~ string ~ "\"" }
|
||||
|
||||
symbol_declaration = { (import_directive | ty_struct_definition | const_definition | function_definition) ~ NEWLINE* }
|
||||
symbol_declaration = { (import_directive | ty_struct_definition | const_definition | type_definition | function_definition) ~ NEWLINE* }
|
||||
|
||||
import_directive = { main_import_directive | from_import_directive }
|
||||
from_import_directive = { "from" ~ quoted_string ~ "import" ~ import_symbol_list ~ NEWLINE* }
|
||||
|
@ -15,6 +15,7 @@ import_symbol = { identifier ~ ("as" ~ identifier)? }
|
|||
import_symbol_list = _{ import_symbol ~ ("," ~ import_symbol)* }
|
||||
function_definition = {"def" ~ identifier ~ constant_generics_declaration? ~ "(" ~ parameter_list ~ ")" ~ return_types ~ ":" ~ NEWLINE* ~ statement* }
|
||||
const_definition = {"const" ~ ty ~ identifier ~ "=" ~ expression ~ NEWLINE*}
|
||||
type_definition = {"type" ~ identifier ~ constant_generics_declaration? ~ "=" ~ ty ~ NEWLINE*}
|
||||
return_types = _{ ( "->" ~ ( "(" ~ type_list ~ ")" | ty ))? }
|
||||
constant_generics_declaration = _{ "<" ~ constant_generics_list ~ ">" }
|
||||
constant_generics_list = _{ identifier ~ ("," ~ identifier)* }
|
||||
|
@ -166,6 +167,6 @@ COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
|||
|
||||
// the ordering of reserved keywords matters: if "as" is before "assert", then "assert" gets parsed as (as)(sert) and incorrectly
|
||||
// accepted
|
||||
keyword = @{"assert"|"as"|"bool"|"byte"|"const"|"def"|"do"|"else"|"endfor"|"export"|"false"|"field"|"for"|"if"|"then"|"fi"|"import"|"from"|
|
||||
keyword = @{"assert"|"as"|"bool"|"const"|"def"|"do"|"else"|"endfor"|"export"|"false"|"field"|"for"|"if"|"then"|"fi"|"import"|"from"|
|
||||
"in"|"private"|"public"|"return"|"struct"|"true"|"u8"|"u16"|"u32"|"u64"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_pest_ast"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = ["schaeff <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ pub use ast::{
|
|||
InlineStructExpression, InlineStructMember, IterationStatement, LiteralExpression, Parameter,
|
||||
PostfixExpression, Range, RangeOrExpression, ReturnStatement, Span, Spread, SpreadOrExpression,
|
||||
Statement, StructDefinition, StructField, SymbolDeclaration, TernaryExpression, ToExpression,
|
||||
Type, TypedIdentifier, TypedIdentifierOrAssignee, UnaryExpression, UnaryOperator, Underscore,
|
||||
Visibility,
|
||||
Type, TypeDefinition, TypedIdentifier, TypedIdentifierOrAssignee, UnaryExpression,
|
||||
UnaryOperator, Underscore, Visibility,
|
||||
};
|
||||
|
||||
mod ast {
|
||||
|
@ -147,6 +147,7 @@ mod ast {
|
|||
Import(ImportDirective<'ast>),
|
||||
Constant(ConstantDefinition<'ast>),
|
||||
Struct(StructDefinition<'ast>),
|
||||
Type(TypeDefinition<'ast>),
|
||||
Function(FunctionDefinition<'ast>),
|
||||
}
|
||||
|
||||
|
@ -191,6 +192,16 @@ mod ast {
|
|||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::type_definition))]
|
||||
pub struct TypeDefinition<'ast> {
|
||||
pub id: IdentifierExpression<'ast>,
|
||||
pub generics: Vec<IdentifierExpression<'ast>>,
|
||||
pub ty: Type<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
#[derive(Debug, FromPest, PartialEq, Clone)]
|
||||
#[pest_ast(rule(Rule::import_directive))]
|
||||
pub enum ImportDirective<'ast> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_stdlib"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
authors = ["Stefan Deml <stefandeml@gmail.com>", "schaeff <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import "hashes/keccak/keccak" as keccak
|
||||
|
||||
def main<N>(u64[N] input) -> u64[4]:
|
||||
return keccak::<N, 256>(input, 0x0000000000000001)[..4]
|
||||
return keccak::<_, 256>(input, 0x0000000000000001)[..4]
|
|
@ -1,4 +1,4 @@
|
|||
import "hashes/keccak/keccak" as keccak
|
||||
|
||||
def main<N>(u64[N] input) -> u64[6]:
|
||||
return keccak::<N, 384>(input, 0x0000000000000001)[..6]
|
||||
return keccak::<_, 384>(input, 0x0000000000000001)[..6]
|
|
@ -1,4 +1,4 @@
|
|||
import "hashes/keccak/keccak" as keccak
|
||||
|
||||
def main<N>(u64[N] input) -> u64[8]:
|
||||
return keccak::<N, 512>(input, 0x0000000000000001)[..8]
|
||||
return keccak::<_, 512>(input, 0x0000000000000001)[..8]
|
|
@ -1,4 +1,4 @@
|
|||
import "hashes/keccak/keccak" as keccak
|
||||
|
||||
def main<N>(u64[N] input) -> (u64[4]):
|
||||
return keccak::<N, 256>(input, 0x0000000000000006)[..4]
|
||||
return keccak::<_, 256>(input, 0x0000000000000006)[..4]
|
|
@ -1,4 +1,4 @@
|
|||
import "hashes/keccak/keccak" as keccak
|
||||
|
||||
def main<N>(u64[N] input) -> (u64[6]):
|
||||
return keccak::<N, 384>(input, 0x0000000000000006)[..6]
|
||||
return keccak::<_, 384>(input, 0x0000000000000006)[..6]
|
|
@ -1,4 +1,4 @@
|
|||
import "hashes/keccak/keccak" as keccak
|
||||
|
||||
def main<N>(u64[N] input) -> (u64[8]):
|
||||
return keccak::<N, 512>(input, 0x0000000000000006)[..8]
|
||||
return keccak::<_, 512>(input, 0x0000000000000006)[..8]
|
|
@ -7,6 +7,6 @@ import "./unpack_unchecked"
|
|||
// For example, `0` can map to `[0, 0, ..., 0]` or to `bits(p)`
|
||||
def main(field i) -> bool[256]:
|
||||
|
||||
bool[254] b = unpack_unchecked::<254>(i)
|
||||
bool[254] b = unpack_unchecked(i)
|
||||
|
||||
return [false, false, ...b]
|
|
@ -3,5 +3,5 @@ import "./unpack" as unpack
|
|||
// Unpack a field element as 128 big-endian bits
|
||||
// If the input is larger than `2**128 - 1`, the output is truncated.
|
||||
def main(field i) -> bool[128]:
|
||||
bool[128] res = unpack::<128>(i)
|
||||
bool[128] res = unpack(i)
|
||||
return res
|
|
@ -9,7 +9,7 @@ import "hashes/blake2/blake2s"
|
|||
// '879043503b04cab2f3c0d7a4bb01c1db74c238c49887da84e8a619893092b6e2'
|
||||
|
||||
def main():
|
||||
u32[8] h = blake2s::<3>([[0x12345678; 16]; 3]) // 3 * 16 * 32 = 1536 bit input
|
||||
u32[8] h = blake2s([[0x12345678; 16]; 3]) // 3 * 16 * 32 = 1536 bit input
|
||||
assert(h == [
|
||||
0x87904350, 0x3B04CAB2, 0xF3C0D7A4, 0xBB01C1DB,
|
||||
0x74C238C4, 0x9887DA84, 0xE8A61989, 0x3092B6E2
|
||||
|
|
|
@ -9,7 +9,7 @@ import "hashes/blake2/blake2s"
|
|||
// '52af1aec3e6663bcc759d55fc7557fbb2f710219f0de138b1b52c919f5c94415'
|
||||
|
||||
def main():
|
||||
u32[8] h = blake2s::<1>([[0x12345678; 16]; 1]) // 16 * 32 = 512 bit input
|
||||
u32[8] h = blake2s([[0x12345678; 16]; 1]) // 16 * 32 = 512 bit input
|
||||
assert(h == [
|
||||
0x52AF1AEC, 0x3E6663BC, 0xC759D55F, 0xC7557FBB,
|
||||
0x2F710219, 0xF0DE138B, 0x1B52C919, 0xF5C94415
|
||||
|
|
|
@ -9,7 +9,7 @@ import "hashes/blake2/blake2s_p" as blake2s
|
|||
// '780105bc9ca7633b1f289b3d1558dece65e04ac23f88e711dc29600fa3e0258a'
|
||||
|
||||
def main():
|
||||
u32[8] h = blake2s::<1>([[0x12345678; 16]; 1], [0x12345678, 0])
|
||||
u32[8] h = blake2s([[0x12345678; 16]; 1], [0x12345678, 0])
|
||||
assert(h == [
|
||||
0x780105BC, 0x9CA7633B, 0x1F289B3D, 0x1558DECE,
|
||||
0x65E04AC2, 0x3F88E711, 0xDC29600F, 0xA3E0258A
|
||||
|
|
|
@ -9,7 +9,7 @@ import "hashes/keccak/384bit" as keccak384
|
|||
// 'a944b9b859c1e69d66b52d4cf1f678b24ed8a9ccb0a32bbe882af8a3a1acbd3b68eed9c628307e5d3789f1a64a50e8e7'
|
||||
|
||||
def main():
|
||||
u64[6] h = keccak384::<20>([42; 20])
|
||||
u64[6] h = keccak384([42; 20])
|
||||
assert(h == [
|
||||
0xA944B9B859C1E69D, 0x66B52D4CF1F678B2, 0x4ED8A9CCB0A32BBE,
|
||||
0x882AF8A3A1ACBD3B, 0x68EED9C628307E5D, 0x3789F1A64A50E8E7
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import "hashes/mimcSponge/mimcSponge" as mimcSponge
|
||||
|
||||
def main():
|
||||
assert(mimcSponge::<2, 3>([1, 2], 3) == [
|
||||
assert(mimcSponge::<_, 3>([1, 2], 3) == [
|
||||
20225509322021146255705869525264566735642015554514977326536820959638320229084,
|
||||
13871743498877225461925335509899475799121918157213219438898506786048812913771,
|
||||
21633608428713573518356618235457250173701815120501233429160399974209848779097
|
||||
])
|
||||
assert(mimcSponge::<2, 3>([0, 0], 0) == [
|
||||
assert(mimcSponge::<_, 3>([0, 0], 0) == [
|
||||
20636625426020718969131298365984859231982649550971729229988535915544421356929,
|
||||
6046202021237334713296073963481784771443313518730771623154467767602059802325,
|
||||
16227963524034219233279650312501310147918176407385833422019760797222680144279
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["1"]
|
||||
"values": []
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import "hashes/pedersen/512bitBool" as pedersen
|
||||
|
||||
def main() -> (field):
|
||||
def main():
|
||||
bool[512] input = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, true]
|
||||
bool[256] res = [true,false,true,false,true,true,true,false,true,false,false,false,true,true,false,true,false,true,false,false,true,false,false,true,true,false,true,false,true,true,true,false,false,true,true,false,true,true,false,false,false,true,false,false,false,true,false,false,false,true,false,true,false,true,true,false,true,false,false,false,false,false,true,true,false,true,true,true,true,false,true,true,false,true,false,false,true,false,true,false,true,true,true,true,true,true,false,true,false,false,true,true,false,true,true,false,true,false,false,false,true,true,false,true,false,true,false,true,true,false,true,true,true,true,true,false,true,true,true,false,true,false,true,false,false,true,false,true,false,false,false,true,true,true,false,true,true,true,true,true,false,true,false,false,true,false,false,true,true,false,false,true,false,true,false,true,true,false,false,false,false,false,false,false,false,true,true,true,true,true,true,true,false,true,true,false,false,true,false,true,false,true,true,false,true,true,true,false,true,true,true,false,true,true,true,true,false,false,false,true,true,false,true,true,false,false,false,false,true,false,false,false,false,true,true,true,false,true,false,true,false,false,false,false,true,true,false,false,true,false,true,true,false,false,true,false,true,true,false,true,false,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true]
|
||||
assert(pedersen(input) == res)
|
||||
return 1
|
||||
return
|
|
@ -7,7 +7,7 @@
|
|||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["1"]
|
||||
"values": []
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import "hashes/sha256/256bitPadded" as sha256
|
||||
def main() -> (field):
|
||||
def main():
|
||||
u32[8] a = [0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89]
|
||||
u32[8] digest = sha256(a)
|
||||
|
||||
assert(digest == [0x16d947ca, 0x4831aee7, 0x6999aa28, 0x20e5c3b4, 0x8171bf49, 0x27241da9, 0xebe644df, 0x9b690df0])
|
||||
return 1
|
||||
return
|
|
@ -7,7 +7,7 @@
|
|||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"values": ["1"]
|
||||
"values": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import "hashes/sha256/embed/1024bitPadded" as sha256
|
||||
def main() -> (field):
|
||||
def main():
|
||||
|
||||
bool[256] a = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
bool[256] b = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
||||
|
@ -10,4 +10,4 @@ def main() -> (field):
|
|||
|
||||
assert(digest == [true, true, true, false, true, true, true, true, true, false, true, false, false, true, false, false, false, false, false, true, true, true, false, false, true, false, true, false, false, true, false, false, true, false, true, false, false, true, false, true, true, true, false, false, false, true, true, true, false, true, true, false, true, false, true, true, false, true, false, false, true, false, false, true, false, true, false, true, true, true, false, true, false, true, false, true, false, true, false, true, true, true, false, true, true, true, true, true, true, true, false, true, true, false, true, true, true, true, true, true, true, false, false, true, false, false, false, true, false, true, true, true, false, true, false, true, false, false, true, true, false, false, true, false, false, false, false, false, false, true, false, false, false, false, false, false, false, true, false, false, true, false, true, true, false, false, true, true, true, true, false, false, true, false, false, false, false, false, false, false, false, true, false, false, true, false, false, false, true, false, true, true, false, false, true, true, true, false, false, false, true, true, true, false, true, false, true, true, false, false, false, true, true, false, false, false, false, true, true, true, false, false, true, true, true, false, true, false, true, false, true, false, false, true, true, false, false, true, true, false, false, false, true, true, false, false, true, true, true, false, true, false, false, false, true, true, false, true, true, false, false, false, true, true, true, false, false, false, true, false, false, false, false, false, true, true])
|
||||
|
||||
return 1
|
||||
return
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue