commit
542c4c1412
245 changed files with 261 additions and 284 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,8 +4,7 @@
|
|||
|
||||
# ZoKrates default files
|
||||
out
|
||||
out.code
|
||||
out.wit
|
||||
out.ztf
|
||||
proof.json
|
||||
proving.key
|
||||
verification.key
|
||||
|
|
|
@ -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}}
|
||||
```
|
|
@ -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.
|
||||
|
|
|
@ -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}}
|
||||
```
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -13,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`
|
||||
|
@ -34,7 +34,7 @@ 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
|
||||
|
@ -64,7 +64,7 @@ In summary, this leads to the following scheme for array declarations:
|
|||
Consider the following example:
|
||||
|
||||
```zokrates
|
||||
{{#include ../../../zokrates_cli/examples/book/multidim_array.code}}
|
||||
{{#include ../../../zokrates_cli/examples/book/multidim_array.zok}}
|
||||
```
|
||||
|
||||
##### Spreads and Slices
|
||||
|
|
|
@ -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}}
|
||||
```
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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])
|
|
@ -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])
|
|
@ -1,4 +1,4 @@
|
|||
import "./popLeastSignificantBit.code"
|
||||
import "./popLeastSignificantBit"
|
||||
|
||||
def main(field order) -> (field, field, field, field):
|
||||
// MSB
|
|
@ -1,5 +1,5 @@
|
|||
import "./decodeOrder.code"
|
||||
import "./limitLessThanPrice.code"
|
||||
import "./decodeOrder"
|
||||
import "./limitLessThanPrice"
|
||||
|
||||
def tupleForTokensWithValue(field value) -> (field[3]):
|
||||
return [value, value, value]
|
|
@ -1,4 +1,4 @@
|
|||
import "./baz.code"
|
||||
import "./baz"
|
||||
|
||||
def main() -> (field):
|
||||
return baz()
|
|
@ -1,5 +1,5 @@
|
|||
import "./foo.code"
|
||||
import "./bar.code"
|
||||
import "./foo"
|
||||
import "./bar"
|
||||
|
||||
def main() -> (field):
|
||||
return foo() + bar()
|
|
@ -1,6 +0,0 @@
|
|||
// See also mock URLs in zokrates_github_resolver
|
||||
import "github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/foo.code"
|
||||
import "github.com/Zokrates/ZoKrates/master/zokrates_cli/examples/imports/bar.code"
|
||||
|
||||
def main() -> (field):
|
||||
return foo() + bar()
|
|
@ -1,4 +1,4 @@
|
|||
import "./foo.code" as d
|
||||
import "./foo" as d
|
||||
|
||||
def main() -> (field):
|
||||
return d()
|
|
@ -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):
|
|
@ -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
|
||||
|
|
@ -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):
|
|
@ -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
Loading…
Reference in a new issue