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

merge structs

This commit is contained in:
Thibaut 2019-09-30 14:23:33 +02:00
commit be14810af9
294 changed files with 1166 additions and 927 deletions

3
.gitignore vendored
View file

@ -4,8 +4,7 @@
# ZoKrates default files
out
out.code
out.wit
out.ztf
proof.json
proving.key
verification.key

16
Cargo.lock generated
View file

@ -2329,6 +2329,14 @@ dependencies = [
"zokrates_pest_ast 0.1.2",
]
[[package]]
name = "zokrates_core_test"
version = "0.1.0"
dependencies = [
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zokrates_test 0.1.0",
]
[[package]]
name = "zokrates_embed"
version = "0.1.0"
@ -2395,6 +2403,14 @@ dependencies = [
[[package]]
name = "zokrates_stdlib"
version = "0.1.3"
dependencies = [
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zokrates_test 0.1.0",
]
[[package]]
name = "zokrates_test"
version = "0.1.0"
dependencies = [
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -8,4 +8,6 @@ members = [
"zokrates_stdlib",
"zokrates_embed",
"zokrates_abi",
"zokrates_test",
"zokrates_core_test",
]

6
out.code Normal file
View file

@ -0,0 +1,6 @@
def main() -> (4):
(1 * ~one) * (42 * ~one) == 1 * ~out_0
(1 * ~one) * (43 * ~one) == 1 * ~out_1
(1 * ~one) * (0) == 1 * ~out_2
(1 * ~one) * (1 * ~one) == 1 * ~out_3
return ~out_0, ~out_1, ~out_2, ~out_3

View file

@ -18,5 +18,6 @@
- [Proving schemes](reference/proving_schemes.md)
- [Verification](reference/verification.md)
- [ZIR](reference/ir.md)
- [Testing](reference/testing.md)
- [Tutorial: Proof of preimage](./sha256example.md)

View file

@ -3,5 +3,5 @@
Comments can be added with double-slashes.
```zokrates
{{#include ../../../zokrates_cli/examples/book/comments.code}}
{{#include ../../../zokrates_cli/examples/book/comments.zok}}
```

View file

@ -9,7 +9,7 @@ Function calls can help make programs clearer and more modular. However, using f
Arguments are passed by value.
```zokrates
{{#include ../../../zokrates_cli/examples/book/side_effects.code}}
{{#include ../../../zokrates_cli/examples/book/side_effects.zok}}
```
### If expressions
@ -17,7 +17,7 @@ Arguments are passed by value.
An if expression allows you to branch your code depending on a condition.
```zokrates
{{#include ../../../zokrates_cli/examples/book/if_else.code}}
{{#include ../../../zokrates_cli/examples/book/if_else.zok}}
```
The condition supports `<`, `<=`, `>`, `>=`, `==`, which can be combined with the boolean operators `&&`, `||` and `!`.
@ -29,7 +29,7 @@ The condition supports `<`, `<=`, `>`, `>=`, `==`, which can be combined with th
For loops are available with the following syntax:
```zokrates
{{#include ../../../zokrates_cli/examples/book/for.code}}
{{#include ../../../zokrates_cli/examples/book/for.zok}}
```
The bounds have to be known at compile time, so only constants are allowed.

View file

@ -3,14 +3,14 @@
A function has to be declared at the top level before it is called.
```zokrates
{{#include ../../../zokrates_cli/examples/book/function_declaration.code}}
{{#include ../../../zokrates_cli/examples/book/function_declaration.zok}}
```
A function's signature has to be explicitly provided.
Functions can return many values by providing them as a comma-separated list.
```zokrates
{{#include ../../../zokrates_cli/examples/book/multi_return.code}}
{{#include ../../../zokrates_cli/examples/book/multi_return.zok}}
```
### Inference
@ -18,11 +18,11 @@ Functions can return many values by providing them as a comma-separated list.
When defining a variable as the return value of a function, types are optional:
```zokrates
{{#include ../../../zokrates_cli/examples/book/multi_def.code}}
{{#include ../../../zokrates_cli/examples/book/multi_def.zok}}
```
If there is an ambiguity, providing the types of some of the assigned variables is necessary.
```zokrates
{{#include ../../../zokrates_cli/examples/book/type_annotations.code}}
{{#include ../../../zokrates_cli/examples/book/type_annotations.zok}}
```

View file

@ -1,27 +1,27 @@
## Imports
You can separate your code into multiple ZoKrates files using `import` statements:
You can separate your code into multiple ZoKrates files using `import` statements, ignoring the `.zok` extension of the imported file:
### Relative Imports
You can import a resource in the same folder directly, like this:
```zokrates
import "./mycode.code"
import "./mycode"
```
There also is a handy syntax to import from the parent directory:
```zokrates
import "../mycode.code"
import "../mycode"
```
Also imports further up the file-system are supported:
```zokrates
import "../../../mycode.code"
import "../../../mycode"
```
You can also choose to rename the imported resource, like so:
```zokrates
import "./mycode.code" as abc
import "./mycode" as abc
```
### Absolute Imports

View file

@ -9,7 +9,7 @@ The following section highlights a subset of available imports:
#### sha256
```zokrates
import "hashes/sha256/512Padded.code"
import "hashes/sha256/512Padded.zok"
```
A function that takes 2 `field[256]` arrays as inputs and returns their sha256 compression function as an array of 256 field elements.
@ -17,18 +17,18 @@ A function that takes 2 `field[256]` arrays as inputs and returns their sha256 c
#### sha256compression
```zokrates
import "hashes/sha256/512bit.code"
import "hashes/sha256/512bit.zok"
```
A function that takes 2 `field[256]` arrays as inputs and returns their sha256 compression function as an array of 256 field elements.
The difference with `sha256` is that no padding is added at the end of the message, which makes it more efficient but also less compatible with Solidity.
There also is support for 2-round (1024-bit input) and and 3-round (1536-bit input) variants, using `hashes/1024bit.code` or `hashes/1536bit.code` respectively.
There also is support for 2-round (1024-bit input) and and 3-round (1536-bit input) variants, using `hashes/1024bit.zok` or `hashes/1536bit.zok` respectively.
#### sha256packed
```zokrates
import "hashes/sha256/512bitPacked.code"
import "hashes/sha256/512bitPacked.zok"
```
A function that takes an array of 4 field elements as inputs, unpacks each of them to 128 bits (big endian), concatenates them and applies sha256. It then returns an array of 2 field elements, each representing 128 bits of the result.
@ -38,7 +38,7 @@ A function that takes an array of 4 field elements as inputs, unpacks each of th
#### Proof of private-key ownership
```zokrates
import "ecc/proofOfOwnership.code"
import "ecc/proofOfOwnership.zok"
```
Verifies match of a given public/private keypair. Checks if the following equation holds for the provided keypair:
@ -48,7 +48,7 @@ where `G` is the chosen base point of the subgroup and `*` denotes scalar multip
#### Signature verification
```zokrates
import "signatures/verifyEddsa.code"
import "signatures/verifyEddsa.zok"
```
Verifies an EdDSA Signature. Checks the correctness of a given EdDSA Signature `(R,S)` for the provided public key `A` and message `(M0, M1)`. Check out this [python repository](https://github.com/Zokrates/pycrypto) for tooling to create valid signatures.

View file

@ -1,6 +1,8 @@
## Types
# Types
ZoKrates currently exposes three types:
ZoKrates currently exposes two primitive types and two complex types:
## Primitive Types
### `field`
@ -11,7 +13,7 @@ The prime `p` is set to `2188824287183927522224640574525727508854836440041603434
While `field` values mostly behave like unsigned integers, one should keep in mind that they overflow at `p` and not some power of 2, so that we have:
```zokrates
{{#include ../../../zokrates_cli/examples/book/field_overflow.code}}
{{#include ../../../zokrates_cli/examples/book/field_overflow.zok}}
```
### `bool`
@ -22,10 +24,104 @@ You can use them for equality checks, inequality checks and inequality checks be
Note that while equality checks are cheap, inequality checks should be use wisely as they are orders of magnitude more expensive.
### `field[n]`
## Complex Types
Static arrays of `field` can be instantiated with a constant size, and their elements can be accessed and updated:
ZoKrates provides two complex types, Arrays and Structs.
### Arrays
ZoKrates supports static arrays, i.e., their length needs to be known at compile time.
Arrays can contain elements of any type and have arbitrary dimensions.
The following examples code shows examples of how to use arrays:
```zokrates
{{#include ../../../zokrates_cli/examples/book/array.code}}
{{#include ../../../zokrates_cli/examples/book/array.zok}}
```
#### Declaration and Initialization
An array is defined by appending `[]` to a type literal representing the type of the array's elements.
Initialization always needs to happen in the same statement as declaration, unless the array is declared within a function's signature.
For initialization, a list of comma-separated values is provided within brackets `[]`.
ZoKrates offers a special shorthand syntax to initialize an array with a constant value:
`[value;repetitions]`
The following code provides examples for declaration and initialization:
```zokrates
field[3] a = [1, 2, 3] // initialize a field array with field values
bool[13] b = [false; 13] // initialize a bool array with value false
```
#### Multidimensional Arrays
As an array can contain any type of elements, it can contain arrays again.
There is a special syntax to declare such multi-dimensional arrays, i.e., arrays of arrays.
To declare an array of an inner array, i.e., and array of elements of a type, prepend brackets `[size]` to the declaration of the inner array.
In summary, this leads to the following scheme for array declarations:
`data_type[size of 1st dimension][size of 2nd dimension]`.
Consider the following example:
```zokrates
{{#include ../../../zokrates_cli/examples/book/multidim_array.zok}}
```
#### Spreads and Slices
ZoKrates provides some syntactic sugar to retrieve subsets of arrays.
##### Spreads
The spread operator `...` applied to an copies the elements of an existing array.
This can be used to conveniently compose new arrays, as shown in the following example:
```
field[3] = [1, 2, 3]
field[4] c = [...a, 4] // initialize an array copying values from `a`, followed by 4
```
##### Slices
An array can also be assigned to by creating a copy of a subset of an existing array.
This operation is called slicing, and the following example shows how to slice in ZoKrates:
```
field[3] a = [1, 2, 3]
field[2] b = a[1..3] // initialize an array copying a slice from `a`
```
### Structs
A struct is a composite datatype representing a named collection of variables.
The contained variables can be of any type.
The following code shows an example of how to use structs.
```zokrates
{{#include ../../../zokrates_cli/examples/book/structs.code}}
```
#### Definition
Before a struct data type can be used, it needs to be defined.
A struct definition starts with the `struct` keyword followed by a name. Afterwards, a new-line separated list of variables is declared in curly braces `{}`. For example:
```zokrates
struct Point {
field x
field y
}
```
#### Declaration and Initialization
Initialization of a variable of a struct type always needs to happen in the same statement as declaration, unless the struct-typed variable is declared within a function's signature.
The following example shows declaration and initialization of a variable of the `Point` struct type:
```zokrates
{{#include ../../../zokrates_cli/examples/book/struct_init.code}}
```
#### Assignment
The variables within a struct instance, the so called members, can be accessed through the `.` operator as shown in the following extended example:
```zokrates
{{#include ../../../zokrates_cli/examples/book/struct_assign.code}}
```

View file

@ -7,7 +7,7 @@ Variables are mutable, and always passed by value to functions.
Shadowing is not allowed.
```zokrates
{{#include ../../../zokrates_cli/examples/book/no_shadowing.code}}
{{#include ../../../zokrates_cli/examples/book/no_shadowing.zok}}
```
### Scope
@ -16,11 +16,11 @@ Shadowing is not allowed.
Functions have their own scope
```zokrates
{{#include ../../../zokrates_cli/examples/book/function_scope.code}}
{{#include ../../../zokrates_cli/examples/book/function_scope.zok}}
```
#### For-loop
For-loops have their own scope
```zokrates
{{#include ../../../zokrates_cli/examples/book/for_scope.code}}
{{#include ../../../zokrates_cli/examples/book/for_scope.zok}}
```

View file

@ -33,10 +33,10 @@ cd target/release
## Hello ZoKrates!
First, create the text-file `root.code` and implement your program. In this example, we will prove knowledge of the square root `a` of a number `b`:
First, create the text-file `root.zok` and implement your program. In this example, we will prove knowledge of the square root `a` of a number `b`:
```zokrates
{{#include ../../zokrates_cli/examples/book/factorize.code}}
{{#include ../../zokrates_cli/examples/book/factorize.zok}}
```
Some observations:
@ -47,7 +47,7 @@ Then run the different phases of the protocol:
```bash
# compile
./zokrates compile -i root.code
./zokrates compile -i root.zok
# perform the setup phase
./zokrates setup
# execute the program

View file

@ -1,31 +0,0 @@
# Testing
## Unit tests
Unit tests can be executed with the following command:
```
cargo test --release
```
## Integration tests
Integration tests are excluded from `cargo test` by default.
Before running integration tests:
1. Make sure your `$ZOKRATES_HOME` is set correctly
2. You have [solc](https://github.com/ethereum/solc-js) installed and in your `$PATH`.
Solc can conveniently be installed through `npm` by running
```
npm install -g solc
```
Integration tests can then be run with the following command:
```
cargo test --release -- --ignored
```
If you want to run unit and integrations tests together, run the following command:
```
cargo test --release & cargo test --release -- --ignored
```

View file

@ -10,12 +10,13 @@ You can see an overview of the available subcommands by running
## `compile`
```sh
./zokrates compile -i /path/to/add.code
./zokrates compile -i /path/to/add.zok
```
Compiles a `.code` file into ZoKrates internal representation of arithmetic circuits.
Compiles a `.zok` source code file into ZoKrates internal representation of arithmetic circuits.
Creates a compiled `.code` file at `./out.code`.
Creates a compiled binary file at `./out`.
Unless the `--light` flag is set, a human readable `.ztf` file is generated, which displays the compilation output in ZoKrates Text Format.
## `compute-witness`
@ -23,7 +24,7 @@ Creates a compiled `.code` file at `./out.code`.
./zokrates compute-witness -a 1 2 3
```
Computes a witness for the compiled program found at `./out.code` and arguments to the program.
Computes a witness for the compiled program found at `./out` and arguments to the program.
A witness is a valid assignment of the variables, which include the results of the computation.
Arguments to the program are passed as a space-separated list with the `-a` flag, or over `stdin`.
@ -35,7 +36,7 @@ Creates a witness file at `./witness`
./zokrates setup
```
Generates a trusted setup for the compiled program found at `./out.code`.
Generates a trusted setup for the compiled program found at `./out`.
Creates a proving key and a verifying key at `./proving.key` and `./verifying.key`.
These keys are derived from a source of randomness, commonly referred to as “toxic waste”. Anyone having access to the source of randomness can produce fake proofs that will be accepted by a verifier following the protocol.
@ -46,7 +47,7 @@ These keys are derived from a source of randomness, commonly referred to as “t
./zokrates export-verifier
```
Using the verifying key at `./verifying.key`, generates a Solidity contract which contains the generated verification key and a public function to verify a solution to the compiled program at `./out.code`.
Using the verifying key at `./verifying.key`, generates a Solidity contract which contains the generated verification key and a public function to verify a solution to the compiled program at `./out`.
Creates a verifier contract at `./verifier.sol`.
@ -56,7 +57,7 @@ Creates a verifier contract at `./verifier.sol`.
./zokrates generate-proof
```
Using the proving key at `./proving.key`, generates a proof for a computation of the compiled program `./out.code` resulting in `./witness`.
Using the proving key at `./proving.key`, generates a proof for a computation of the compiled program `./out` resulting in `./witness`.
Returns the proof, for example:

View file

@ -7,3 +7,4 @@ The reference covers the details of various areas of ZoKrates.
- [Proving schemes](proving_schemes.md)
- [Verification](verification.md)
- [ZIR](ir.md)
- [Testing](testing.md)

View file

@ -0,0 +1,44 @@
# Testing
Before running any tests, make sure make sure your `ZOKRATES_HOME` environment variable is set correctly.
It has to point to `zokrates_stdlib/stdlib/`
## Unit tests
In ZoKrates, unit tests comprise
- internal tests for all zokrates crates
- compilation tests for all examples in `zokrates_cli/examples`. These tests only ensure that the examples compile.
- compilation + witness-computation tests. These tests compile the test cases, compute a witness and compare the result with a pre-defined expected result.
Such test cases exist for
- The zokrates_core crate in `zokrates_core_test/tests`
- The zokrates_stdlib crate in `zokrates_stdlib/tests`
Unit tests can be executed with the following command:
```
cargo test --release
```
## Integration tests
Integration tests are excluded from `cargo test` by default.
They are defined in the `zokrates_cli` crate in `integration.rs` and use the test cases specified in `zokrates_cli/tests/code`.
Before running integration tests:
1. Make sure your `$ZOKRATES_HOME` is set correctly
2. You have [solc](https://github.com/ethereum/solc-js) installed and in your `$PATH`.
Solc can conveniently be installed through `npm` by running
```
npm install -g solc
```
3. You have an Ethereum node running on localhost with a JSON-RPC interface on the default port 8545 (`http://localhost:8545`).
Integration tests can then be run with the following command:
```
cargo test --release -- --ignored
```
If you want to run unit and integrations tests together, run the following command:
```
cargo test --release & cargo test --release -- --ignored
```

View file

@ -13,10 +13,10 @@ Make sure you have followed the instructions in the [Getting Started](gettingsta
We will start this tutorial by using ZoKrates to compute the hash for an arbitrarily chosen preimage, being the number `5` in this example.
First, we create a new file named `hashexample.code` with the following content:
First, we create a new file named `hashexample.zok` with the following content:
```zokrates
{{#include ../../zokrates_cli/examples/book/hashexample.code}}
{{#include ../../zokrates_cli/examples/book/hashexample.zok}}
```
The first line imports the `sha256packed` function from the ZoKrates standard library.
@ -32,7 +32,7 @@ Having our problem described in ZoKrates' DSL, we can now continue using ZoKrate
First, we compile the program into an arithmetic circuit using the `compile` command.
```sh
./zokrates compile -i hashexample.code
./zokrates compile -i hashexample.zok
```
As a next step we can create a witness file using the following command:
@ -67,10 +67,10 @@ Let's recall our goal: Peggy wants to prove that she knows a preimage for a dige
To make it work, the two parties have to follow their roles in the protocol:
First, Victor has to specify what hash he is interested in. Therefore, we have to adjust the zkSNARK circuit, compiled by ZoKrates, such that in addition to computing the digest, it also validates it against the digest of interest, provided by Victor. This leads to the following update for `hashexample.code`:
First, Victor has to specify what hash he is interested in. Therefore, we have to adjust the zkSNARK circuit, compiled by ZoKrates, such that in addition to computing the digest, it also validates it against the digest of interest, provided by Victor. This leads to the following update for `hashexample.zok`:
```zokrates
{{#include ../../zokrates_cli/examples/book/hashexample_updated.code}}
{{#include ../../zokrates_cli/examples/book/hashexample_updated.zok}}
```
Note that we now compare the result of `sha256packed` with the hard-coded correct solution defined by Victor. The lines which we added are treated as assertions: the verifier will not accept a proof where these constraints were not satisfied. Clearly, this program only returns 1 if all of the computed bits are equal.
@ -78,7 +78,7 @@ Note that we now compare the result of `sha256packed` with the hard-coded correc
So, having defined the program, Victor is now ready to compile the code:
```sh
./zokrates compile -i hashexample.code
./zokrates compile -i hashexample.zok
```
Based on that Victor can run the setup phase and export verifier smart contract as a Solidity file:

View file

@ -1,10 +1,10 @@
def main() -> ():
field[3] a = [1, 2, 3]
bool[3] b = [true, true, false]
field[2][3] c = [[1, 2], [3, 4], [5, 6]]
field[3][2] c = [[1, 2], [3, 4], [5, 6]]
field[3] aa = [...a]
bool[3] bb = [...b]
field[2][3] cc = [...c]
field[3][2] cc = [...c]
return

View file

@ -1,7 +1,8 @@
def main() -> (field):
field[3] a = [1, 2, 3] // initialize an array with values
field[3] a = [1, 2, 3] // initialize a field array with field values
a[2] = 4 // set a member to a value
field[4] b = [42; 4] // initialize an array of 4 values all equal to 42
field[4] c = [...a, 4] // initialize an array copying values from `a`, followed by 4
field[2] d = a[1..3] // initialize an array copying a slice from `a`
bool[3] e = [true, true || false, true] // initialize a boolean array
return a[0] + b[1] + c[2]

View file

@ -1,4 +1,4 @@
import "hashes/sha256/512bitPacked.code" as sha256packed
import "hashes/sha256/512bitPacked" as sha256packed
def main(private field a, private field b, private field c, private field d) -> (field[2]):
h = sha256packed([a, b, c, d])

View file

@ -1,4 +1,4 @@
import "hashes/sha256/512bitPacked.code" as sha256packed
import "hashes/sha256/512bitPacked" as sha256packed
def main(private field a, private field b, private field c, private field d) -> (field):
h = sha256packed([a, b, c, d])

View file

@ -0,0 +1,9 @@
def main() -> (field):
// Array of two elements of array of 3 elements
field[2][3] a = [[1, 2, 3],[4, 5, 6]]
field[3] b = a[0] // should be [1, 2, 3]
// allowed access [0..2][0..3]
return a[1][2]

View file

@ -0,0 +1,10 @@
struct Point {
field x
field y
}
def main(field a) -> (Point):
Point p = Point {x: 1, y: 0}
p.x = a
p.y = p.x
return p

View file

@ -0,0 +1,8 @@
struct Point {
field x
field y
}
def main() -> (Point):
Point p = Point {x: 1, y: 0}
return p

View file

@ -0,0 +1,14 @@
struct Bar {
field[2] c
bool d
}
struct Foo {
Bar a
bool b
}
def main() -> (Foo):
Foo[2] f = [Foo { a: Bar { c: [0, 0], d: false }, b: true}, Foo { a: Bar {c: [0, 0], d: false}, b: true}]
f[0].a.c = [42, 43]
return f[0]

View file

@ -1,4 +1,4 @@
import "./popLeastSignificantBit.code"
import "./popLeastSignificantBit"
def main(field order) -> (field, field, field, field):
// MSB

View file

@ -1,5 +1,5 @@
import "./decodeOrder.code"
import "./limitLessThanPrice.code"
import "./decodeOrder"
import "./limitLessThanPrice"
def tupleForTokensWithValue(field value) -> (field[3]):
return [value, value, value]

View file

@ -1,4 +1,4 @@
from "./baz.code" import main as baz
import "./baz"
def main() -> (field):
return baz()

View file

@ -1,5 +1,5 @@
import "./foo.code"
import "./bar.code"
import "./foo"
import "./bar"
def main() -> (field):
return foo() + bar()

View file

@ -1,4 +1,4 @@
import "./foo.code" as d
import "./foo" as d
def main() -> (field):
return d()

View file

@ -1,8 +1,8 @@
import "hashes/pedersen/512bit.code" as hash
import "ecc/edwardsCompress.code" as edwardsCompress
import "ecc/babyjubjubParams.code" as context
import "hashes/utils/256bitsDirectionHelper.code" as multiplex
import "utils/binary/not.code" as NOT
import "hashes/pedersen/512bit" as hash
import "ecc/edwardsCompress" as edwardsCompress
import "ecc/babyjubjubParams" as context
import "hashes/utils/256bitsDirectionHelper" as multiplex
import "utils/binary/not" as NOT
// Merke-Tree inclusion proof for tree depth 3 using SNARK efficient pedersen hashes
// directionSelector=> 1/true if current digest is on the rhs of the hash
def main(field[256] rootDigest, private field[256] leafDigest, private field[3] directionSelector, field[256] PathDigest0, private field[256] PathDigest1, private field[256] PathDigest2) -> (field):

View file

@ -1,6 +1,6 @@
import "hashes/sha256/512bit.code" as sha256
import "utils/multiplexer/256bit.code" as multiplex
import "utils/binary/not.code" as NOT
import "hashes/sha256/512bit" as sha256
import "utils/multiplexer/256bit" as multiplex
import "utils/binary/not" as NOT
// Merke-Tree inclusion proof for tree depth 3

View file

@ -1,4 +1,4 @@
import "./pedersenPathProof3.code"
import "./pedersenPathProof3"
// Merke-Tree inclusion proof for tree depth 3
// def main(field treeDepth, field[256] rootDigest, private field[256] leafDigest, private field[2] directionSelector, field[256] PathDigest0, private field[256] PathDigest1) -> (field):
def main() -> (field):

View file

@ -1,4 +1,4 @@
import "./sha256PathProof3.code" as merkleTreeProof
import "./sha256PathProof3" as merkleTreeProof
def main() -> (field):
field treeDepth = 3

Some files were not shown because too many files have changed in this diff Show more