{ "cells": [ { "cell_type": "markdown", "id": "cf69bb3f-94e6-4dba-92cd-ce08df117d67", "metadata": { "id": "cf69bb3f-94e6-4dba-92cd-ce08df117d67" }, "source": [ "## EZKL Jupyter Notebook Demo LOCAL\n", "\n", "Here we demonstrate how to use the EZKL package to run a publicly known / committed to network on some private data, producing a public output.\n" ] }, { "cell_type": "code", "execution_count": 8, "id": "95613ee9", "metadata": { "id": "95613ee9" }, "outputs": [ { "ename": "ImportError", "evalue": "attempted relative import beyond top-level package", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mImportError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 18\u001b[39m\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m extra_path \u001b[38;5;129;01min\u001b[39;00m sys.path:\n\u001b[32m 16\u001b[39m sys.path.append(extra_path)\n\u001b[32m---> \u001b[39m\u001b[32m18\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mmodel\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m fashion\n", "\u001b[36mFile \u001b[39m\u001b[32m~/src/zkml-bootcamp2025Q1-g6/app/model/fashion.py:15\u001b[39m\n\u001b[32m 13\u001b[39m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mPIL\u001b[39;00m\n\u001b[32m 14\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mPIL\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m Image\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01m.\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m tools\n\u001b[32m 17\u001b[39m classes = [\n\u001b[32m 18\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mT-shirt/top\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 19\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mTrouser\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 27\u001b[39m \u001b[33m\"\u001b[39m\u001b[33mAnkle boot\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 28\u001b[39m ]\n\u001b[32m 30\u001b[39m \u001b[38;5;66;03m# Download test data from open datasets.\u001b[39;00m\n", "\u001b[31mImportError\u001b[39m: attempted relative import beyond top-level package" ] } ], "source": [ "# make sure you have the dependencies required here already installed\n", "import subprocess\n", "import sys\n", "from torch import nn\n", "import ezkl\n", "import os\n", "import json\n", "import torch\n", "from torch.utils.data import DataLoader\n", "from torchvision import datasets\n", "from torchvision.transforms import ToTensor\n", "\n", "# hack PYTHON_PATH\n", "extra_path = \"/home/philippe/src/zkml-bootcamp2025Q1-g6/app\"\n", "if not extra_path in sys.path:\n", " sys.path.append(extra_path)\n", " \n", "from model import fashion" ] }, { "cell_type": "code", "execution_count": 5, "id": "2c90da79-a173-4a3d-ad82-7505fb718c88", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 10, "id": "945dc7a9-f969-45b6-8202-eea00bc77e6e", "metadata": {}, "outputs": [ { "ename": "AttributeError", "evalue": "module 'model' has no attribute 'fashion'", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mAttributeError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[10]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mmodel\u001b[49m\u001b[43m.\u001b[49m\u001b[43mfashion\u001b[49m\n", "\u001b[31mAttributeError\u001b[39m: module 'model' has no attribute 'fashion'" ] } ], "source": [] }, { "cell_type": "code", "execution_count": 2, "id": "cde92973-2ff1-405b-9ca4-fa3f68f3d954", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100.0%\n", "100.0%\n", "100.0%\n", "100.0%\n" ] } ], "source": [ "\n", "# Download training data from open datasets.\n", "training_data = datasets.FashionMNIST(\n", " root=\"data\",\n", " train=True,\n", " download=True,\n", " transform=ToTensor(),\n", ")\n", "\n", "# Download test data from open datasets.\n", "test_data = datasets.FashionMNIST(\n", " root=\"data\",\n", " train=False,\n", " download=True,\n", " transform=ToTensor(),\n", ")\n", "\n", "batch_size = 64\n", "\n", "# Create data loaders.\n", "train_dataloader = DataLoader(training_data, batch_size=batch_size)\n", "test_dataloader = DataLoader(test_data, batch_size=batch_size)\n", "\n", "def train(dataloader, model, loss_fn, optimizer):\n", " size = len(dataloader.dataset)\n", " model.train()\n", " for batch, (X, y) in enumerate(dataloader):\n", " X, y = X, y\n", "\n", " # Compute prediction error\n", " pred = model(X)\n", " loss = loss_fn(pred, y)\n", "\n", " # Backpropagation\n", " loss.backward()\n", " optimizer.step()\n", " optimizer.zero_grad()\n", "\n", " if batch % 100 == 0:\n", " loss, current = loss.item(), (batch + 1) * len(X)\n", " print(f\"loss: {loss:>7f} [{current:>5d}/{size:>5d}]\")\n", "\n", "def test(dataloader, model, loss_fn):\n", " size = len(dataloader.dataset)\n", " num_batches = len(dataloader)\n", " model.eval()\n", " test_loss, correct = 0, 0\n", " with torch.no_grad():\n", " for X, y in dataloader:\n", " X, y = X, y\n", " pred = model(X)\n", " test_loss += loss_fn(pred, y).item()\n", " correct += (pred.argmax(1) == y).type(torch.float).sum().item()\n", " test_loss /= num_batches\n", " correct /= size\n", " print(f\"Test Error: \\n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \\n\")\n", "\n", "# Defines the model\n", "class NeuralNetwork(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", " self.flatten = nn.Flatten()\n", " self.linear_relu_stack = nn.Sequential(\n", " nn.Linear(28*28, 512),\n", " nn.ReLU(),\n", " nn.Linear(512, 512),\n", " nn.ReLU(),\n", " nn.Linear(512, 10)\n", " )\n", "\n", " def forward(self, x):\n", " x = self.flatten(x)\n", " logits = self.linear_relu_stack(x)\n", " return logits\n", "\n" ] }, { "cell_type": "code", "execution_count": 5, "id": "b37637c4", "metadata": { "id": "b37637c4" }, "outputs": [], "source": [ "model_path = os.path.join('network.onnx')\n", "compiled_model_path = os.path.join('network.compiled')\n", "pk_path = os.path.join('test.pk')\n", "vk_path = os.path.join('test.vk')\n", "settings_path = os.path.join('settings.json')\n", "\n", "witness_path = os.path.join('witness.json')\n", "data_path = os.path.join('input.json')" ] }, { "cell_type": "code", "execution_count": 6, "id": "mbTNTVVVUWHf", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "mbTNTVVVUWHf", "outputId": "298c39ef-d47d-45e1-b398-69b8752f9843" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "NeuralNetwork(\n", " (flatten): Flatten(start_dim=1, end_dim=-1)\n", " (linear_relu_stack): Sequential(\n", " (0): Linear(in_features=784, out_features=512, bias=True)\n", " (1): ReLU()\n", " (2): Linear(in_features=512, out_features=512, bias=True)\n", " (3): ReLU()\n", " (4): Linear(in_features=512, out_features=10, bias=True)\n", " )\n", ")\n", "Epoch 1\n", "-------------------------------\n", "loss: 2.312977 [ 64/60000]\n", "loss: 2.296970 [ 6464/60000]\n", "loss: 2.274892 [12864/60000]\n", "loss: 2.276994 [19264/60000]\n", "loss: 2.254272 [25664/60000]\n", "loss: 2.238387 [32064/60000]\n", "loss: 2.232406 [38464/60000]\n", "loss: 2.202704 [44864/60000]\n", "loss: 2.202426 [51264/60000]\n", "loss: 2.174140 [57664/60000]\n", "Test Error: \n", " Accuracy: 56.1%, Avg loss: 2.163561 \n", "\n", "Epoch 2\n", "-------------------------------\n", "loss: 2.175747 [ 64/60000]\n", "loss: 2.158823 [ 6464/60000]\n", "loss: 2.105635 [12864/60000]\n", "loss: 2.131705 [19264/60000]\n", "loss: 2.067987 [25664/60000]\n", "loss: 2.017259 [32064/60000]\n", "loss: 2.039357 [38464/60000]\n", "loss: 1.960464 [44864/60000]\n", "loss: 1.975269 [51264/60000]\n", "loss: 1.903171 [57664/60000]\n", "Test Error: \n", " Accuracy: 58.7%, Avg loss: 1.897245 \n", "\n", "Epoch 3\n", "-------------------------------\n", "loss: 1.933288 [ 64/60000]\n", "loss: 1.893456 [ 6464/60000]\n", "loss: 1.784591 [12864/60000]\n", "loss: 1.838915 [19264/60000]\n", "loss: 1.714538 [25664/60000]\n", "loss: 1.665039 [32064/60000]\n", "loss: 1.689406 [38464/60000]\n", "loss: 1.585296 [44864/60000]\n", "loss: 1.619385 [51264/60000]\n", "loss: 1.516735 [57664/60000]\n", "Test Error: \n", " Accuracy: 61.9%, Avg loss: 1.527831 \n", "\n", "Epoch 4\n", "-------------------------------\n", "loss: 1.597046 [ 64/60000]\n", "loss: 1.551634 [ 6464/60000]\n", "loss: 1.408163 [12864/60000]\n", "loss: 1.488660 [19264/60000]\n", "loss: 1.363807 [25664/60000]\n", "loss: 1.358963 [32064/60000]\n", "loss: 1.368338 [38464/60000]\n", "loss: 1.288468 [44864/60000]\n", "loss: 1.324361 [51264/60000]\n", "loss: 1.233305 [57664/60000]\n", "Test Error: \n", " Accuracy: 63.3%, Avg loss: 1.251777 \n", "\n", "Epoch 5\n", "-------------------------------\n", "loss: 1.330162 [ 64/60000]\n", "loss: 1.306223 [ 6464/60000]\n", "loss: 1.143752 [12864/60000]\n", "loss: 1.257733 [19264/60000]\n", "loss: 1.132717 [25664/60000]\n", "loss: 1.157656 [32064/60000]\n", "loss: 1.170492 [38464/60000]\n", "loss: 1.103810 [44864/60000]\n", "loss: 1.139225 [51264/60000]\n", "loss: 1.067870 [57664/60000]\n", "Test Error: \n", " Accuracy: 64.5%, Avg loss: 1.082341 \n", "\n", "Epoch 6\n", "-------------------------------\n", "loss: 1.152435 [ 64/60000]\n", "loss: 1.153687 [ 6464/60000]\n", "loss: 0.973343 [12864/60000]\n", "loss: 1.116238 [19264/60000]\n", "loss: 0.991616 [25664/60000]\n", "loss: 1.024298 [32064/60000]\n", "loss: 1.049273 [38464/60000]\n", "loss: 0.989383 [44864/60000]\n", "loss: 1.020612 [51264/60000]\n", "loss: 0.966005 [57664/60000]\n", "Test Error: \n", " Accuracy: 65.8%, Avg loss: 0.974972 \n", "\n", "Epoch 7\n", "-------------------------------\n", "loss: 1.031440 [ 64/60000]\n", "loss: 1.057128 [ 6464/60000]\n", "loss: 0.859297 [12864/60000]\n", "loss: 1.023219 [19264/60000]\n", "loss: 0.902562 [25664/60000]\n", "loss: 0.932362 [32064/60000]\n", "loss: 0.970724 [38464/60000]\n", "loss: 0.916998 [44864/60000]\n", "loss: 0.939589 [51264/60000]\n", "loss: 0.898259 [57664/60000]\n", "Test Error: \n", " Accuracy: 67.1%, Avg loss: 0.902818 \n", "\n", "Epoch 8\n", "-------------------------------\n", "loss: 0.944603 [ 64/60000]\n", "loss: 0.991639 [ 6464/60000]\n", "loss: 0.779391 [12864/60000]\n", "loss: 0.957908 [19264/60000]\n", "loss: 0.842370 [25664/60000]\n", "loss: 0.866209 [32064/60000]\n", "loss: 0.916129 [38464/60000]\n", "loss: 0.870094 [44864/60000]\n", "loss: 0.881627 [51264/60000]\n", "loss: 0.849794 [57664/60000]\n", "Test Error: \n", " Accuracy: 68.4%, Avg loss: 0.851363 \n", "\n", "Epoch 9\n", "-------------------------------\n", "loss: 0.878879 [ 64/60000]\n", "loss: 0.943430 [ 6464/60000]\n", "loss: 0.720472 [12864/60000]\n", "loss: 0.909670 [19264/60000]\n", "loss: 0.798988 [25664/60000]\n", "loss: 0.817197 [32064/60000]\n", "loss: 0.875414 [38464/60000]\n", "loss: 0.837863 [44864/60000]\n", "loss: 0.838859 [51264/60000]\n", "loss: 0.812779 [57664/60000]\n", "Test Error: \n", " Accuracy: 69.7%, Avg loss: 0.812555 \n", "\n", "Epoch 10\n", "-------------------------------\n", "loss: 0.826808 [ 64/60000]\n", "loss: 0.905002 [ 6464/60000]\n", "loss: 0.674947 [12864/60000]\n", "loss: 0.872401 [19264/60000]\n", "loss: 0.765720 [25664/60000]\n", "loss: 0.779864 [32064/60000]\n", "loss: 0.842847 [38464/60000]\n", "loss: 0.814456 [44864/60000]\n", "loss: 0.805864 [51264/60000]\n", "loss: 0.782933 [57664/60000]\n", "Test Error: \n", " Accuracy: 71.1%, Avg loss: 0.781673 \n", "\n", "Done!\n", "\n", "Saved PyTorch Model State to model.pth\n" ] } ], "source": [ "# Train the model as you like here (skipped for brevity)\n", "model = NeuralNetwork()\n", "print(model)\n", "\n", "loss_fn = nn.CrossEntropyLoss()\n", "optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)\n", "\n", "epochs = 10\n", "for t in range(epochs):\n", " print(f\"Epoch {t+1}\\n-------------------------------\")\n", " train(train_dataloader, model, loss_fn, optimizer)\n", " test(test_dataloader, model, loss_fn)\n", "print(\"Done!\")\n", "\n", "torch.save(model.state_dict(), \"model.pth\")\n", "print(\"\\nSaved PyTorch Model State to model.pth\")" ] }, { "cell_type": "code", "execution_count": 7, "id": "82db373a", "metadata": { "id": "82db373a" }, "outputs": [], "source": [ "\n", "model.eval()\n", "model.load_state_dict(torch.load(\"model.pth\", weights_only=True))\n", "dummy_input = test_data[0][0]\n", "\n", " # Export the model\n", "torch.onnx.export(model, # model being run\n", " dummy_input, # model input (or a tuple for multiple inputs)\n", " model_path, # where to save the model (can be a file or file-like object)\n", " export_params=True, # store the trained parameter weights inside the model file\n", " opset_version=10, # the ONNX version to export the model to\n", " do_constant_folding=True, # whether to execute constant folding for optimization\n", " input_names = ['input'], # the model's input names\n", " output_names = ['output'], # the model's output names\n", " dynamic_axes={'input' : {0 : 'batch_size'}, # variable length axes\n", " 'output' : {0 : 'batch_size'}})\n", "\n", "data_array = ((dummy_input).detach().numpy()).reshape([-1]).tolist()\n", "\n", "data = dict(input_data = [data_array])\n", "\n", " # Serialize data into file:\n", "json.dump( data, open(data_path, 'w' ))\n" ] }, { "cell_type": "code", "execution_count": 24, "id": "d5e374a2", "metadata": { "id": "d5e374a2" }, "outputs": [], "source": [ "py_run_args = ezkl.PyRunArgs()\n", "py_run_args.input_visibility = \"private\"\n", "py_run_args.output_visibility = \"public\"\n", "py_run_args.param_visibility = \"fixed\" # private by default\n", "\n", "res = ezkl.gen_settings(model_path, settings_path, py_run_args=py_run_args)\n", "\n", "assert res == True\n" ] }, { "cell_type": "code", "execution_count": null, "id": "c6iTDB6f2JOK", "metadata": { "id": "c6iTDB6f2JOK" }, "outputs": [], "source": [ "cal_path = os.path.join(\"calibration.json\")\n", "\n", "data_array = (torch.rand(20, *shape, requires_grad=True).detach().numpy()).reshape([-1]).tolist()\n", "\n", "data = dict(input_data = [data_array])\n", "\n", "# Serialize data into file:\n", "json.dump(data, open(cal_path, 'w'))\n", "\n", "\n", "await ezkl.calibrate_settings(cal_path, model_path, settings_path, \"resources\")" ] }, { "cell_type": "code", "execution_count": 25, "id": "3aa4f090", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "3aa4f090", "outputId": "c370bb1a-35ea-4044-84df-21110a79b7b0" }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:ezkl:low scale values (<8) may impact precision\n" ] } ], "source": [ "res = ezkl.compile_circuit(model_path, compiled_model_path, settings_path)\n", "assert res == True" ] }, { "cell_type": "code", "execution_count": 27, "id": "8b74dcee", "metadata": { "id": "8b74dcee" }, "outputs": [], "source": [ "# srs path\n", "res = await ezkl.get_srs( settings_path, srs_path=\"kzg.srs\")" ] }, { "cell_type": "code", "execution_count": 28, "id": "18c8b7c7", "metadata": { "id": "18c8b7c7" }, "outputs": [], "source": [ "# now generate the witness file\n", "\n", "res = await ezkl.gen_witness(data_path, compiled_model_path, witness_path)\n", "assert os.path.isfile(witness_path)" ] }, { "cell_type": "code", "execution_count": 29, "id": "b1c561a8", "metadata": { "id": "b1c561a8" }, "outputs": [], "source": [ "\n", "# HERE WE SETUP THE CIRCUIT PARAMS\n", "# WE GOT KEYS\n", "# WE GOT CIRCUIT PARAMETERS\n", "# EVERYTHING ANYONE HAS EVER NEEDED FOR ZK\n", "\n", "\n", "\n", "res = ezkl.setup(\n", " compiled_model_path,\n", " vk_path,\n", " pk_path,\n", " srs_path=\"kzg.srs\"\n", " )\n", "\n", "assert res == True\n", "assert os.path.isfile(vk_path)\n", "assert os.path.isfile(pk_path)\n", "assert os.path.isfile(settings_path)" ] }, { "cell_type": "code", "execution_count": 31, "id": "c384cbc8", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "c384cbc8", "outputId": "bdb4cd87-820c-460d-e9f9-962b3fa35235" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'instances': [['ebfdffef93f5e1439170b97948e833285d588181b64550b829a031e1724e6430', 'e4fdffef93f5e1439170b97948e833285d588181b64550b829a031e1724e6430', 'e4feffef93f5e1439170b97948e833285d588181b64550b829a031e1724e6430', 'c4feffef93f5e1439170b97948e833285d588181b64550b829a031e1724e6430', '46ffffef93f5e1439170b97948e833285d588181b64550b829a031e1724e6430', '8302000000000000000000000000000000000000000000000000000000000000', 'e7feffef93f5e1439170b97948e833285d588181b64550b829a031e1724e6430', '5102000000000000000000000000000000000000000000000000000000000000', '3d01000000000000000000000000000000000000000000000000000000000000', 'b302000000000000000000000000000000000000000000000000000000000000']], 'proof': '0x0e57589f9b085afe90eb99197cc7d9d6e59cadfef3cadfd2ec893bcc29c72c092c4e45dab8c578ff07f7ac9afcce47835141a98b4844eb59b509d5600cc92d222f259e536c37a7b07e1a6a3a4e24830108501363c571dec7155e230da4b981422e39e09486081143d1970b3f87d0a1f3f71cb9667688ea95eeb9676c964f712e1fc5eabd3dabeae259cb0285f0163ca83dc8a16ea6c897fda96792933f15d2ac1f34f00e457273ccb60a567ecaf8ea930daaec708fe4b28c23f3355ac79b395c1e2ea127e3cbef36b3b3c6b0e2b218311e5229de72a65c064fba68f6135a1c3a0bf38764f6407b2fb4ceb45cfbf74d2175e0218a2c95487e9b8311a49c38ff55009a353520ae7786cbf6c2073a62d2b9a5168ec80ad1cbd5ca02271840d8672c28e774690d70044269ffd2d57ecd05ffdc0c29ec24357354d7bdf0dc76c0cc171a780ef24fbd87392e05ff953ce3b2bb0da28abe21c4fc2dde383d8741f0456c12ac07fe0f6f59420d246f900fb8470ef0cdd41c5f8834dc847af828c72e7bde0ac59b0e3f1eebf386c79da2feebdbf775cd8c1da6c3ba009e47150d8790967b1f4e057787b913930f4bf66df7c7dadb6107763634727aecb008789349d40f6e2502e327547ba4e22547a2d59537338d4dfa937b04e9d56a2278ed6cb0b46e782e98a7989646e71724412875aae113a4cc6e73b1be0ba089d07d8465c64500462e2d1841316c2b0fd7b301b9ca9acc19420351fed86b8d921cdd5252dcd7fb9128b17307e1140025ffb5fa080501e1061af5c28043dde5a00795ddc37eeffd060a8bb71581188fe0755a76279fc707ab896cb7d66529bca9c0447503c2fb40ff24a5728d4a8148a8899c291a1a602fc0511c64dbefe6f3b50f9c3e6b5a4194771e40d002228d9de7e9b888dd235a5cf9dc55e6dc03a4b8be4972223e47304bae2356d495f26b97f4f268134424693331cdb03260e7670f4889beb1058c2d305814e3d33bb7bf5a396f4ebcc13195234063501222dca2784038eba0c244827bae1678f87baf4a24a927acdf5392fde09a94362b882a2f41b4b092e3ce6331fc632ee89b544861e6abe3f0dac116c73f14c3e67b0ed61a65205d7c3d2f38b15b920cf2f798691ba5b923212ff951bda57fba6bea97425bc90e4fc41ea7db7f17e52fcf836a4765548ee0654a27ff6babcbb4c771ff5dc7c9f72ca402642c8ca5200a94ff079460a32b2e66f4627ebc1486efc6a8a33581f22425a89828cf4d6faf1a8048171ff3795c1d7e8e801fa63aa8a0386e1494e2b68df223852b9d4e0b3322e19a617a180d1f5929d6d902fb84f558442c55fc7f950e9a87fc3fa28ee4fc235072aff5f1b114b97b6b533e38b8b84c3a0216defe11a749faef2cac13997b2d0eb4fb51221b1934c5d79777e4d0554a27aa62f9c6843727bab2972fee45030dcce99dbe8ba74259803e3d780ba2eb50d83dc7e0ffbd5fd92bcdb437e5f8762b1c986b256dc74fd14ffad1c451a1c9d9f47d9a62a123324e7645447d5c086219268b5149ce4b2fa10628727035465de547d2d6ea6dc5d98f3a83d3563144700dad8246e4557b93bb6e92fb0bdfde8d14fabede526777852535bf8972eb4f1327a245c5dc9ab5c49cd6851a93a3923c19c07df1aafc28d8e7705dd6f849a39f232a9e1a60ce95f0d7855ce397997b811e8cd70439025cb54090500b87e9b925119d16620f203c3d2ff3053d049112de0a8379002af727498d4494aa106133d90eadf994d2ef6a5cbcbfcb180afb5fb63bcd4c7ffac77dfeb03a505c3a9cb9c508c1d3ea1925f2c19ede519d69f2c8e86e305ed1bad74d4a58ee800865ac3b6016712a0a9f42e485292d30c9740708af7fbf46f6617bfd39d0a08215b44a0b540023bf5610bc0ee0adf1902eda56e5059b297ae95eff21b3ba71ba3d8e16220d26cd3f82f2a0d12d81d2b7ae3a8ab9fde5bca97128a42ee23d33e8159da8cfb9118b21564fcb5d288b03c2fcb8770293deb1b75985fbfe6652f8fd3a0642691120c3948dc3c1ce4533a78fd5e30be9e039d0ebfe630dadeb460098338d8f9f0905d7dd7c9cf79ce9e8dd026ccf2023137580ae49c7eb05da09566f0250707aa70b3cd068dc36775127d0607b5adb0ce4828c8132c7ac594c4b6bae9bfeeb9c941efe61e76ba18f81867e524093084dce151b53f82c4f931753d3978cbdaa35191f31d46738d333142c225f5325273b6a22ead726b44ee175b2b0ddd45072efc408dd4b138db5e5de392a58932d26a9282fdb776e84e4abaa9c415143aeb9121d03e9794c1f276b20d24c839cb8e06db6decd548d6252d83dc92c5949e9bcb45b1efe61e76ba18f81867e524093084dce151b53f82c4f931753d3978cbdaa35191f31d46738d333142c225f5325273b6a22ead726b44ee175b2b0ddd45072efc411f955bd701f08f4e0fbe2be6f567a12d7243b9e1476e092af503cbaf690d1361d36f19915680d9c69def90dad4363b15868b0c841b3b3e5bcd5504a9a935e471efe61e76ba18f81867e524093084dce151b53f82c4f931753d3978cbdaa35191f31d46738d333142c225f5325273b6a22ead726b44ee175b2b0ddd45072efc410732d3244ecf5493b1a159e7d60597cbf2c478adce62cfc9f3989d65a9bfe20231806ec8f4340be833064c65b0816fe7cf89cb5d9c475cc59557d25af67ead10769335db2055c4ab02f8e2b3678bae9fb10fa4aa4d4df40c60686ffda9c5803190be4a8a705dcdecb84e161fa6b5105b3e84da1fb8023e5cb1d7fcb3c1b54b61f85fd964c0ef983a34d6c12aaaac500347a94c789cb5ab59c5bb99bf7518ec70e869de7561bf99edad62581ed3800d53986d9a358493321fc160c4fb10566e1093e9314f097a487b8ab764bd97673a1fd241aedcedd2b86417e6d813e6ae3561d51760d756e9b6942b78b689bb74dc6b099a1ba4a08fbb879dba822f67a995f112dd7fb8d7ff6bab34b23695df06840dfd3709d60ed2ab70a7ef6ff96f9b5cc1031171a6e450555e43430417a40c92a7bd0557103c9b06ed17f7de076aa4b891925a3d3b5a5b98c88e69f5af6984a2f76a3d4a7f273d0a7dfbeffb96378136a04900e365618b2e734b4be70cc3a5e3b1e52d6ba66d3b799376c41ef242ea73b24a4a53eb2e77d489264415d131ad99bfc5f244bd4bb8fde92282b0703d65abd1b58b1e02513232d18c0bf156bf8116a2ecbd40dc6afd0b5840fc20aeb918ffc06a4d9082b8a2478d87c4af3b0ae276c1157e609a1e1f971f39d4db92911607b2897f56ad0e8319fe58e4ff5e496734b43e57902ca0e36b97f361a29b8d5262a1283a638e7fc558ece34da94a80deba9f7ba0f20bfcabca5f6b393628f6b49d612174064f8ce42f6233c6c34e602ffe83ff3b481c9af19f83b0af8d906ff4dc71527b2e28978b7048bf922d667af5644b019f430bcb5c4ac034a6c0cd238bfce25e9243eba787cd86bc4a738e827b40beb49fbc18bfe3a7cb1586e4de4a2c03d17a5b62db864c1b9cb77c9e7f2726e1396cb271f4760ec172aaa1fec5e9b4f770d3131d52557a4d980d94c365326e11c6620be780cd43c957770650221a5218822b13fd6fbc1e4a2eacd3c7b28daeb8c7a412a30b3ac4f49dfcafe5582cc0b8f1c1f123b4f7e14a60ea7655328e4db1995fdd76a027c8c53088ae7fc12e73cb31f91bd170ba504a810695b98b84c006d353899710136cdc6b5ef76cd927eb1d2175c644a98de92652da922cefd142dc73304eebed855fc7e5327bbd02fbeb71f1bfb5d28dffb144c2e22720cd03157e9fbb3b8e9d9c6d1e5a53ede773c087dec237ac6b2713bb82b1a20b4859c5880d19407cc693c6a5ac405d4053fb0cddc48075dc3c91dcd72aa71c56c30b74e93058d9a4b17f00dd19e3f5f806f8ce536b01d86666eaafdaf1bd6c819e3395808a0c26e612f27fecf9cfde9e00df310aec300c4493ea742bc727b85a6229e646d6919b608ec69535efe9bfab9aada913cac1c986200cf0c339e15c95af65b1ec4e896986d4bfa297badae127be8d3a73b72075dc3c91dcd72aa71c56c30b74e93058d9a4b17f00dd19e3f5f806f8ce536b01d86666eaafdaf1bd6c819e3395808a0c26e612f27fecf9cfde9e00df310aec30c0ff204c900d6df4725e7a8ed1ea87d1704079d033c1f158cb2c54189e6fc112d0855b4dbf45affbe9a55fc29666d6219366ea8fa3568ccd8b18d4f51bb7511075dc3c91dcd72aa71c56c30b74e93058d9a4b17f00dd19e3f5f806f8ce536b01d86666eaafdaf1bd6c819e3395808a0c26e612f27fecf9cfde9e00df310aec3204301a1ef3d96a1429e18b690789e90e3d381f6e851102f71685a2c976cee611053311d55ce72ad5e7a69d53e1ae96683060b73ac1a144fcb0c703832b89eb72ffa2b3d91908b319571b0868d558244abea2e66076fde99fb38c03142d3acd12e8ac4fca2425ec01887a95447ae3ff4be6114fddabc9602c9a3ca6860f7277202c7bbfe6e5323f371660be808f98901d75b8b95e8d3ad088c39f159c374096f1a2be87dd4089e10c33179a0243515918538bdc9dfd5a4c9d8b9b4358c6558c90a428b02ec4b0f4ec693bb59b9dac1117557341831f16e1177dfe1afa40455251225fc41dee58da23e51ea37e2fd4af044ec27203e972d9efaf98b998bf608661a8d83fa5e6ccf441444a86f0d0ba8959976262c820239a230dbe7056341f28426e9108c74ddc53ccb6ff571b3fcd4b3049d23bf5264703b366271a81a8693ad2c30f74860e04d07825127a212758c5eca04974ed50c1eca97d8db428c9f0b2f1ddfbf520e55ef0ac2d42df4227d61b884d1c7d6b7c5c048d227703b57224f0d1d06ea4f244bc9ffe0f4b20951e8691308acf76b18390687f8d13ad4da8c12222eefeef0d17f389487d4405abd2b474c0d49b6580ee69fe0784ecf4ecce88bb32b10d9f4bd26c79263255d7046493e219ba95752771c5ad596445b8f682b6df9168b7ae150c8999029b14dd5136877a17f5e249452fbddffd4cd7fe334a81d37072823847f3ce5ece6f7ae2280252fc0a4bcbca0d4100a9f14f504ff6d9054af069111d6d49e24f9bae671fe82166bfcacba2178b4b1d4be1dd134e77157162b0b6b1160a72c34b7e46f94deb074c42b123b131ebb72a027739095e1aa466966229d6121c3cdd323eebbd715235d22f9f13120da30886d6ce4708de4de0a3d820ebdc36a0f3ab67531301659731e90d5163cab62435779a0da067aaad5bc356a1cf0e0506c2a049a60616ee8e5aae79af9c8017f548f5f856c28969812aceecd0479f283df56a3dbe66db3b2f2e5e838b29b205aa1156556269317dde3771c0d156946882e664a96d765673fc14396614df626337b899aeb3329d513796de94623df2a43eaab12a7c6cfbcca06604cc6e1b9fa3a5ef620e1261329463e005d4e20b9f72f54da39ff245c2ae8604b541ee4f9cf740b8940f514bb0a53122bab401447c461d2b8ccfdd8ef9e265d4cddc2d1814391bac1119eaacd49d1bcf1fdfc0ef4d2735f0398e89b7aefa0485c478526fb4cfe4a16fc4a2ef9746104ffcc750863952387448213cb7d718dd31524e174b4914d0c745d5f46c51cb1d566d472049aeb56c8c55413493ee047b954d25e11a11b25cef6a7d05911cebe69c3e4421cfd872057600e11e44707ba144a859dea59e63f98ac226e9109453cbf2559fc0814a8baf9a27c39471648351a4ff4ebe6e228a8c53c9a47d1bf49e1c8deec3307b4babb9e1ff27b5a6dd8c345d3d8c9f4ee5073f88f0f500df808d994ed00d126569604f09fb51ede21de6b3c08b3d20da346c7d96dfebd3921b669974b79a41d346efcf2153a9a7e56e73c4a3ab8c379ea2c38c63c30d4af2dc268d9ef27720f1ca2feb4cbaafcd419ceefa37823cc3a02e60ab2799d8417fa72979cee76462ed7386539af567bec2aa8fb435c8ef8ff847690de21c75c67ea3f559fd6814e2ed7386539af567bec2aa8fb435c8ef8ff847690de21c75c67ea3f559fd6814e29b4b1f5622fb1eb71ecf693c27a68255e73dba75b8813fb9faff747744fa16129b4b1f5622fb1eb71ecf693c27a68255e73dba75b8813fb9faff747744fa16110ccaa6b8ae8b5ba43f034f242e50650b8761d6fb75b769cd5efa86840d638ae10ccaa6b8ae8b5ba43f034f242e50650b8761d6fb75b769cd5efa86840d638ae24b29c12d63d4da8d82a063c8e3eb8b212a1bab62024573d099b5c1e60c628e224b29c12d63d4da8d82a063c8e3eb8b212a1bab62024573d099b5c1e60c628e22a4201574b68aa277ead391aa4a4a0b73b944b0bc160560651ef9ec77274b1d32a4201574b68aa277ead391aa4a4a0b73b944b0bc160560651ef9ec77274b1d31727680ca89d1096e6b235afe84e3caa826e871f4b653920b8bf7756ad3235ed1727680ca89d1096e6b235afe84e3caa826e871f4b653920b8bf7756ad3235ed1a4b2e3c126c74a4f4ba1d7fd13565eaac9995c44d90ba8ca7bfb641f88a83421a4b2e3c126c74a4f4ba1d7fd13565eaac9995c44d90ba8ca7bfb641f88a8342285ff8e79b8f317ebe507f5534e808bd701bbafc7fa84aac2ace4b7c3e787046285ff8e79b8f317ebe507f5534e808bd701bbafc7fa84aac2ace4b7c3e7870462aaec9c6fde6bfb2d644428b58157a21315aa21bc1fb682f4fdca15890b0ead12aaec9c6fde6bfb2d644428b58157a21315aa21bc1fb682f4fdca15890b0ead10c9b2aa2a2229904d4e23506a6760e17591fb8646ddac96e741b29ff6dc8586e000000000000000000000000000000000000000000000000000000000000000018f05134bc7840d256bc24de9d25311578cccbfb81faae44ba157ba23c62175200000000000000000000000000000000000000000000000000000000000000001482346c116a5b77a85e47180b4651cbad780cd4661514dd706dc0df4fc2628b19dcdd7b909fabf77b76074e93590a80d80d721e8154e6eea3072552116098fe000000000000000000000000000000000000000000000000000000000000000009fd8a5e2c2dce20c7e2b2234443e3e05eb586109bd829166443a740416c0529243307788c19b9119db327a5575d841ea2fdb0640d7eca369fd502bcb6a500770102864046ebc4a90e416a889867aa1b23e1637ccccf052a28ca5df53655e8f308046467bb2709298b55166baab99c618358dc6c2c0b41fabd3641df20f874cf1450d27687cc76bf4ef7ddbf12f83df59c2e2972a28e650e56b89b7507058ab306fcba82e8389935f02add7c1aae6ac952276f1828612d7ef006f913739e10ce09d1f5c48f4cb77c479542dc847afb4f8157607f3c0d0d18da9c002ca84e9564156337065740a5f3f63849a9e003a8bd922c8467a7d3b462453a03693c957d132d754feb9e5507dd676410b2d647e0f605d9b36620e048d4603d0043062ed95706f3077415db70fbcf08fc79f047874bd7e16782267e198b023ec66162aaeddc1fab5d79e8aa20a11adbf2a2f78cbdc4d3ed5578c6b487b6cc14f45311a98510047902244d3f868dd034ebbc85568327cbc4674a6a25b009fce8ef761340e6061d893f78362de18661d5d5bd0bfabb80f0bb032c42b6cdfb15bcf42f088330e1060d5566c5fe6dce2e05df69a4ad434eb28fb8faa4a25dc5c3e00a80d44fa4fc0935a4cba70f163e1f93453f33bda8569de4ce519b22bc9c71b168bd268c6bca14f0421e2a5a49b3eb1f5a8610a8d1ddd105187591f8758b0c4d21faee9a984e2d8fe7e3b339f7405076a88862f19107e399b2d94721dd283b630240616647b529e8a1125c0777e25be1f92a021c0d2b719dff3cf7fd3cdc86c773b92d7090810568a91a6339feb9c6209856786c10d9096074502833f5b555145f5ac44f6d342afb58e46cfb7a083ac98e22be588f67eec40fdbc6c001a0d6f73feabcc750b515ec4fda5d2f1aa5341e8dccfe0d2cde11191c5b2144814e9bc94501fe362deb0aa5a642f78360041978f1cbf37aab523e94d9180e70781b5d38cde2abc4c8831031f94854246d8d1a369f83902a80c5b6cb1ff84330776ccddb50a10f7ee1201c333a6af14acf8228e729a2e14bce95ee295b984fadade893f7fa013bb7220220d6546de4553736c7bca81215b03eb59dcff79f444d0f219b3a2df00892bc392f460ab356bbf19fa8b2bd87be43af5c6e3f1ec2003fab174922974631a211db0dd015f44033eec2420245f7b06fd06bd1943388bb9751c0ca3f8ec773da84d22b73c0e0ba5d8762ec548008c5b83724743a88bcb68cf6f4c1c0f67aaeeb0b0323b319f760d4c6dc47c22e7f9553b56a1a519cd134926611270d1f1c24f63aa208f410432e3c57a656fd52176673e322cc70f373ca3cc3361988bf361e62a7a4023424da463bddebabfa5e76dc8b4c24546f6120fdb7d24a4a2e19f757e34ae005d3437df0cbff1269921a65b7bae5a9ac8f0cbc420bfb528fca66630b7332a80db7c9717fb4d413457e144de60b1872c1671a013bffe5c28f9500cc3f2fc34c11d2629e0127ce9a3cbb5c8b4463afe84967ec8aec41b2bcf4e8a229e90d79d9138d9cc478807f369548a02993d633179cded8bdf45426a71c7dec056a961f2d1744aca8c581208e26045bb8024e4b6c33aa0be8cd91860f5da1e5229267b1df2f0b0d9f26f2245de9f64aeb396635ae329e1011986ee1789354af02ff2d015b2e574568feca6f8f326c112af8444beb0117d2ed5f6407b561e9987a262421770de8aefda7faadd1c3e9951c155d655a35009e402d5070ac85a50455f5f017b111b3835d337032ee5f8754f6d479b57717347ff75b8db604b7680d580c3ab211276d81888cd76b74b3e2231ace7eac999c8ff957f698d389d171def09a0602462b959cf5bf95ab0e1a6c04b34fe8acaed541b9e77c989a6f3788112be55fe2e22067b18bc926e9898bb44c0e381140587bd231463a8759ea958d6d950f0f30610dad66d039fbaa134298f758e081abc32c2d77a15407206d37a6571860e97cdc10282a46487d305fd736bb4270104f1761c93ba9c1462d9d6bf1d2a70a06273825d7dbfc9c07ef8e4c3ad1531bfda399489c259255323e7fd31310ae456ffe162f0a3729bd24795c004840ae476afd7fb707d940d582700aa81ac450c685bbfd0d9ac5c1f359fababb9e70157acf849f90ff1957360b2baa6c16af355f54e82916c297d332690976408f634ad5daa29690f417dc440bf2784e21fec8209c8f72191a34aa5aebf254c77005f9bebd3519cf267f0bc702f30ab6e55bbd295190f4238d9ca6c867f6ed598ac762e9b299a9f8ead170476209c699251bfd1b32343f05f185a7c52ed746a22ca54802526fdd2156c3a559ec6f417c9df59ca8de4a6d03c476f5902f5b2f4c5859a99a9ca15f19b8fdd929b12db1ea9bdeaf53b996f62b18caf3e7c2550daee340ed738a5425bad05e64e3e509cfc494f2089818456f118875eff5082654569cc87eeabd54909e034c251cb25bdc6a41c94bb9c288e612d7f4c47232bbbd7db307c6ff32d78186040f608ab70a5b96d033cd73d6377a2a2ed8a5df6d9df8cd8b0c86640bd26f65256fd45f33dd1a99605a2d78ba3003212e77182170e77b066bab23d41b2926837f468218883c4d64403a9e20ae9ebe0aff560a001d90f5bef806f062b718f2885a230e5758498ac9667bc73291616f132b963a94f9fe6f52590c2a90e2a9b1a8690d36e9bce3bb22119e6bdaebc4a01a6eda5aa071a0a7936ca5feabdf03562d408cd05f9e9f2bd71aec95fae5a21316ad3bb7cb05437878ae9fca548e1777e9905ec4a642bea6ae598db63ae2e88c0c43871be9af721396ebadd0e7d5a770b6dfd5b99d732696bd66a7ec1d021c62068bb3e2b0bfa560c0209980812e28b2c22e282dd8e8253987e2a642febf1a2705e61d6262298d9b3296ca217ace2ad64b8db7b36fa6663b42f695f699c5095f132b963a94f9fe6f52590c2a90e2a9b1a8690d36e9bce3bb22119e6bdaebc4a01a6eda5aa071a0a7936ca5feabdf03562d408cd05f9e9f2bd71aec95fae5a21316ad3bb7cb05437878ae9fca548e1777e9905ec4a642bea6ae598db63ae2e88c1f6924875982299dc1e7af4650e1bec94047a417531c5f20cca51c6e7f95f0e0282164cc2d161d397369cf168680b01f7caad0f96dd0aff8a46bae58cb9dcd47174f597b1d78cfbec74ad8b09971877a61ba3d098d9e55e046ad732acfc0b0e5132b963a94f9fe6f52590c2a90e2a9b1a8690d36e9bce3bb22119e6bdaebc4a01a6eda5aa071a0a7936ca5feabdf03562d408cd05f9e9f2bd71aec95fae5a21316ad3bb7cb05437878ae9fca548e1777e9905ec4a642bea6ae598db63ae2e88c2ed4cdaf33097635208d6a76015bf912806798cc40d18284fbb792dec089c5522db9d3848c11a63e36129c750cc6793c8fa6d7665da0130f5cf66f0676e42202123bd61bf6f7834c74285c634115fb9a1fb28c21c431e7aa7488570fe80228b52aad89aafc95c819e61055e411f47f182f56c0e16d190f40d0344c06fd99a6ae2f7daf1de718d45c2c444aa0dcf1c9455d2b799581e5ca84030abd46029eadd7150e93b61fc21fd6085f4c6d3f3497476e01f9a0998cb310646841e0b2b0568b1b39292ca3309d87ed4fd7252725e33f8465bd089dd0c87eb82d368358a37929', 'transcript_type': 'EVM'}\n" ] } ], "source": [ "# GENERATE A PROOF\n", "\n", "\n", "proof_path = os.path.join('test.pf')\n", "\n", "res = ezkl.prove(\n", " witness_path,\n", " compiled_model_path,\n", " pk_path,\n", " proof_path,\n", " \"single\",\n", " srs_path=\"kzg.srs\",\n", " )\n", "\n", "print(res)\n", "assert os.path.isfile(proof_path)" ] }, { "cell_type": "code", "execution_count": 32, "id": "76f00d41", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "76f00d41", "outputId": "c4a7b153-dd32-42ed-9b31-1cb4616ebff4" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "verified\n" ] } ], "source": [ "# VERIFY IT\n", "\n", "res = ezkl.verify(\n", " proof_path,\n", " settings_path,\n", " vk_path,\n", " srs_path=\"kzg.srs\"\n", " )\n", "\n", "assert res == True\n", "print(\"verified\")" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.7" } }, "nbformat": 4, "nbformat_minor": 5 }