diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 188df6c..dd5c46e 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -9,6 +9,7 @@ * [Basic CLI Example](examples/basic.md) * [Full Transpilation](examples/full_transpilation.md) +* [Create a Proof](examples/create_proof.md) * [Reset Your Password](examples/reset_password.md) ## 📦 Resources diff --git a/docs/examples/create_proof.md b/docs/examples/create_proof.md new file mode 100644 index 0000000..37b3836 --- /dev/null +++ b/docs/examples/create_proof.md @@ -0,0 +1,109 @@ +# How To Create a Proof Using Giza CLI + +After transpiling the model to Cairo using Giza CLI, the next step is to create a proof. This proof is a cryptographic evidence that the computation (inference) was done correctly without revealing any information about the data or the computation itself. + +## Prerequisites + +We need to install the following tools: + +* [Giza CLI](cli.gizatech.xyz) +* [Rust](https://www.rust-lang.org/tools/install) +* [Scarb](https://docs.swmansion.com/scarb/) +* [`starknet-sierra-compile`](https://github.com/starkware-libs/cairo/tree/main/crates/bin/starknet-sierra-compile) + +## Embed the model into a Starknet Contract + +First, we need to compile the Cairo contract to a Starknet Contract, more information about starknet contracts [here](https://book.cairo-lang.org/ch99-00-starknet-smart-contracts.html). For now we don't need to dive deep into how these contracts works, as currently we need to make it a contract due a temporary limitation in the prover, once this is solved we should be able to generate the proof without the need of a contract. + +Add the `starknet` as a dependency in the `Scarb.toml` file: + +```toml +[dependencies] +starknet = "2.0.2" +orion = { git = "https://github.com/gizatechxyz/orion.git" } + +# ... + +[[target.starknet-contract]] +``` + +Then declare our program as a contract: + +```rust +// inference.cairo +// Create a module and declare it as a contract +#[starknet::contract] +mod OrionRunner { + + // Kepp your imports as declared previously + // use ... + + // Declare the contract storage, in this case is a dummy storage as we wo't use it + #[storage] + struct Storage { + id: u8, + } + + // Declare the main function as an external function and add `self: @ContractState` as the first argument + #[external(v0)] + fn main(self: @ContractState){ + // The models code goes here + } +// Remember to close the module bracket! +} +``` + +## Compile the contract + +This is done using the `scarb build` command with the main objective of creating the `sierra.json` file that will be used to generate the proof. These files will be generated in the `target/dev` folder. + +```console +❯ scarb build + Updating git repository https://github.com/gizatechxyz/orion + Updating git repository https://github.com/keep-starknet-strange/alexandria + Updating git repository https://github.com/influenceth/cubit + Compiling mnist_pytorch v0.1.0 (/Users/gizabrain/src/giza/giza-cli/examples/mnist/mnist_cairo/Scarb.toml) + Finished release target(s) in 7 seconds +``` + +Now this will create two files, but we are only interested in one of them, the `{{project name}}_OrionRunner.sierra.json` file. + +## Convert the `sierra.json` file to `casm.json` + +For this step we need the `starknet-sierra-compile` tool, this tool will convert the `sierra.json` file to a `casm.json`. If you don't already have it, to get it you need to get it from the Cairo repository and build it: + +```bash +git clone git@github.com:starkware-libs/cairo.git +cd cairo +cargo build +``` + +Then the binary will be placed at `target/debug/starknet-sierra-compile`. Now we can use it to convert the file: + +```bash +starknet-sierra-compile -- target/dev/{{project_name}}_OrionRunner.sierra.json output.casm.json +``` + +## Generate the proof + +Finally, we can generate the proof using the `giza prove` command: + +```console +❯ giza prove --size M output.casm.json +[giza][2023-10-26 13:29:22.337] Proving job created with name 'proof-job-20231026-73fb1007' and id -> 1 ✅ +# This log live updates with the job elapsed time +[giza][2023-10-26 13:32:44.431] Job status is 'PROCESSING', elapsed 103.0s +# Once finished it will update to indicate that the job finished +[giza][2023-10-26 13:37:06.634] Proving job is successful ✅ +[giza][2023-10-26 13:37:06.748] Proof metrics: +{ + "cairovm_execution_time": 4.973674, + "proving_time": 316.3519 +} +[giza][2023-10-26 13:37:07.471] Proof saved at: zk.proof +``` + +And now we have our proof! + +Note: The `verify` command is coming soon! + diff --git a/examples/mnist/mnist_pytorch.ipynb b/examples/mnist/mnist_pytorch.ipynb index d311e34..3a14c27 100644 --- a/examples/mnist/mnist_pytorch.ipynb +++ b/examples/mnist/mnist_pytorch.ipynb @@ -19,7 +19,8 @@ "* How to train the model\n", "* How to export this model to ONNX\n", "* How to transpile the model to Cairo using Giza CLI!\n", - "* How to run inference on the transpiled model" + "* How to run inference on the transpiled model\n", + "* How to create a **Proof** from the model!" ] }, { @@ -40,7 +41,7 @@ "Or:\n", "\n", "```bash\n", - "pip install giza-cli==0.3.0 onnx==1.14.1 torch==2.1.0 torchvision==0.16.0\n", + "pip install giza-cli==0.4.0 onnx==1.14.1 torch==2.1.0 torchvision==0.16.0\n", "```\n", "\n", "We will use the libraries for the following purposes:\n", @@ -55,16 +56,16 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 73, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } @@ -103,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -134,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -167,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -193,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -212,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -246,7 +247,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -331,7 +332,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -376,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -569,7 +570,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -610,8 +611,128 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Now we have the base to start working in our model!\n", + "## How to create a Proof\n", "\n", + "In order to create a proff of the Cairo program we need to perform some changes. Currently, there is a limitation on the prover, this prover needs the cairo programm to be embeded into a Starknet Contract so we can generate the proof. This is a temporary limitation and we are working on a solution to this.\n", + "\n", + "For now we need to do a couple of changes.\n", + "\n", + "Starting with `Scarb.toml` we need to add `starknet` as a dependency:\n", + "\n", + "```diff\n", + "[package]\n", + "name = \"mnist_pytorch\"\n", + "version = \"0.1.0\"\n", + "\n", + "[dependencies]\n", + "+starknet = \"2.0.2\"\n", + "orion = { git = \"https://github.com/gizatechxyz/orion.git\" }\n", + "layer1 = {path = \"crates/layer1\"}\n", + "layer3 = {path = \"crates/layer3\"}\n", + "\n", + "[workspace]\n", + "members = [\n", + " \"crates/layer1\",\n", + " \"crates/layer3\",\n", + "]\n", + "\n", + "+[[target.starknet-contract]]\n", + "```\n", + "\n", + "Once this is done we also need to change our code a bit, so our programm it's turned into a Starknet Contract:\n", + "\n", + "```diff\n", + "#inference.cairo\n", + "+#[starknet::contract]\n", + "+mod OrionRunner {\n", + "\tuse orion::operators::tensor::{TensorTrait, FP16x16Tensor, Tensor};\n", + "\tuse orion::operators::nn::{NNTrait, FP16x16NN};\n", + "\tuse orion::numbers::FP16x16;\n", + "\tuse layer1::weights::tensor1 as w1;\n", + "\tuse layer1::bias::tensor1 as b1;\n", + "\tuse layer3::weights::tensor3 as w3;\n", + "\tuse layer3::bias::tensor3 as b3;\n", + "\tuse mnist_pytorch::functions as f;\n", + " use mnist_pytorch::input::input;\n", + "\n", + "\n", + "+\t#[storage]\n", + "+\tstruct Storage { \n", + "+\t\tid: u8,\n", + "+\t}\n", + "+\n", + "+\t#[external(v0)]\n", + "+\tfn main(self: @ContractState){\n", + "\t\tlet _0 = input();\n", + "\t\tlet _1 = f::lin2(_0, w1(), b1());\n", + "\t\tlet _2 = f::relu3(_1);\n", + "\t\tlet _3 = f::lin4(_2, w3(), b3());\n", + "\t\tlet _4 = f::logsoftmax5(_3);\n", + "\t}\n", + "+}\n", + "```\n", + "\n", + "We have our Starknet Contract! Let's build it:\n", + "\n", + "```console\n", + "❯ scarb build\n", + " Updating git repository https://github.com/gizatechxyz/orion\n", + " Updating git repository https://github.com/keep-starknet-strange/alexandria\n", + " Updating git repository https://github.com/influenceth/cubit\n", + " Compiling mnist_pytorch v0.1.0 (/Users/gizabrain/src/giza/giza-cli/examples/mnist/mnist_cairo/Scarb.toml)\n", + " Finished release target(s) in 7 seconds\n", + "```\n", + "\n", + "If we check the `target` directory we can see that two files have been generated, `mnist_pytorch.starknet_artifacts.json` and `mnist_pytorch_OrionRunner.sierra.json`. The later is the one that we need to use to generate the proof. But first we need to transform it into `casm.json`, for this we will need to use `starknet-sierra-compile`. If you don't have you can get it from the [Cairo repository](https://github.com/starkware-libs/cairo/) and follow the instructions to install it.\n", + "\n", + "```console\n", + "❯ git clone git@github.com:starkware-libs/cairo.git\n", + "Cloning into 'cairo'...\n", + "remote: Enumerating objects: 64708, done.\n", + "remote: Counting objects: 100% (1769/1769), done.\n", + "remote: Compressing objects: 100% (952/952), done.\n", + "remote: Total 64708 (delta 1024), reused 1436 (delta 811), pack-reused 62939\n", + "Receiving objects: 100% (64708/64708), 44.07 MiB | 12.77 MiB/s, done.\n", + "Resolving deltas: 100% (44757/44757), done.\n", + "❯ cd cairo\n", + "❯ cargo build\n", + "# This could take a bit\n", + "...\n", + "```\n", + "\n", + "Now in the resulting `target/debug` directory we can find the `starknet-sierra-compile` binary (you can add it to your PATH for ease of use). We can use it to transform our `sierra.json` file into `casm.json`:\n", + "\n", + "```console\n", + "❯ starknet-sierra-compile -- target/dev/mnist_pytorch_OrionRunner.sierra.json mnist_pytorch.casm.json\n", + "```\n", + "\n", + "This will produce the `mnist_pytorch.casm.json` file that we need to use to generate the proof. Now we are ready to generate the proof using the CLI!\n", + "\n", + "```console\n", + "❯ giza prove --size M mnist_pytorch.casm.json\n", + "[giza][2023-10-26 13:29:22.337] Proving job created with name 'proof-job-20231026-73fb1007' and id -> 1 ✅\n", + "# This log live updates with the job elapsed time\n", + "[giza][2023-10-26 13:32:44.431] Job status is 'PROCESSING', elapsed 103.0s\n", + "# Once finished it will update to indicate that the job finished\n", + "[giza][2023-10-26 13:37:06.634] Proving job is successful ✅\n", + "[giza][2023-10-26 13:37:06.748] Proof metrics:\n", + "{\n", + " \"cairovm_execution_time\": 4.973674,\n", + " \"proving_time\": 316.3519\n", + "}\n", + "[giza][2023-10-26 13:37:07.471] Proof saved at: zk.proof\n", + "```\n", + "\n", + "Now we have our proof four our model! We can use it to verify that the model is correct and that the output that we get is the expected one.\n", + "\n", + "`verify` command coming soon!" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ "Happy coding!" ] }