Просмотр исходного кода

add book page on writing ZK proofs with zkas, includes info on debugging

zero 2 лет назад
Родитель
Сommit
547ffe2144
2 измененных файлов с 78 добавлено и 0 удалено
  1. 1 0
      doc/src/SUMMARY.md
  2. 77 0
      doc/src/zkas/writing-zk-proofs.md

+ 1 - 0
doc/src/SUMMARY.md

@@ -43,6 +43,7 @@
   - [DAO](arch/dao.md)
   - [Wallet](arch/wallet.md)
 - [zkas](zkas/index.md)
+  - [Writing ZK Proofs](zkas/writing-zk-proofs.md)
   - [Bincode](zkas/bincode.md)
   - [zkVM](zkas/zkvm.md)
   - [Examples](zkas/examples.md)

+ 77 - 0
doc/src/zkas/writing-zk-proofs.md

@@ -0,0 +1,77 @@
+# Writing ZK Proofs
+
+ZK proofs in DarkFi are written in a simple low level
+[DSL](https://en.wikipedia.org/w/index.php?title=Domain-specific_language).
+The zkas compiler then converts this human readable code into bytecode
+that is run on the DarkFi ZKVM.
+
+## Zkas Usage
+
+To build zkas, run:
+```
+make zkas
+```
+We can then see the help output with `zkas -h`.
+
+To compile a `.zk` file, simply run:
+```
+$ zkas proof/opcodes.zk
+Wrote output to proof/opcodes.zk.bin
+```
+It's worth running `zkas -i proof/opcodes.zk` to get a sense of what
+instructions the bytecode will send to the VM. We can also see the data
+structure with `-e` as well.
+
+## Structure of a ZK File
+
+Take a look at existing ZK files in `proof/` directory for examples.
+
+`k = ...` indicates the number of rows which is $2ᵏ$. Bigger values make
+your proof slower, whereas if `k` is too low then the proof generation will
+fail. Pick a value that works and find the minimum allowed. Usually 11 to 13
+works.
+
+`field = "pallas"` indicates the base field.
+
+The `constant` section specifies any constants we use.
+
+`witness` section contains the witnesses provided when generating the proof.
+
+`circuit` specifies the actual instructions for the proof.
+
+## Generating a ZK Proof in Rust
+
+When compiling you will need to use the `zk` feature in cargo.
+Check `tests/zkvm_opcodes.rs` for an example to follow along with.
+
+The broad steps are:
+
+1. Create your witness values, and put them in an array. The order must match
+   what is set in the `.zk` file.
+2. Calculate the public values from the private witnesses. This must be
+   an array of the same type (usually `pallas::Base`).
+3. Load the bytecode and generate the ZK proof.
+4. Optionally you can verify it.
+
+## Debugging ZK Files
+
+The first thing you should do is export a JSON file to run with the debugger.
+You can do this by adding this line into Rust.
+```rust
+zk::export_witness_json("witness.json", &prover_witnesses, &public_inputs);
+```
+Then after running the code, you should now have a file called `witness.json`.
+
+Then run the ZK debugger.
+```
+./bin/zkrunner/zkrunner.py -w witness.json --prove --trace foo.zk
+```
+where `foo.zk` is our `.zk` file we're debugging.
+
+Often this works, but the ZK proof is failing when used with a WASM contract.
+In that case the culprit is that the WASM code is exporting the wrong
+public values. Use the `msg!()` macro to print them to the program's output
+log, and compare it with the public values you see in the `witness.json`
+from when the proof was created. This will allow you to pinpoint exactly
+where the error occurs.
+