Last active
March 25, 2025 05:28
-
-
Save Turupawn/55ad199f273cfd6bc2ff886be84ed6d0 to your computer and use it in GitHub Desktop.
ezkl locally
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Verifica si el notebook está en Colab | |
try: | |
# Instala ezkl y onnx si estás en Colab | |
import google.colab | |
import subprocess | |
import sys | |
subprocess.check_call([sys.executable, "-m", "pip", "install", "ezkl"]) | |
subprocess.check_call([sys.executable, "-m", "pip", "install", "onnx"]) | |
except: | |
pass # Si no, usa tu setup de ezkl local | |
# Importa las librería necesarias | |
from torch import nn | |
import torch | |
import ezkl | |
import os | |
# Define el address que recibirá el tip | |
tip_recipient_address = 0x707e55a12557E89915D121932F83dEeEf09E5d70 | |
# Convierte la dirección al formato que EZKL espera | |
def address_to_byte_tensor(address): | |
address_hex = f"{address:040x}" | |
return torch.tensor([int(address_hex[i:i+2], 16) for i in range(0, len(address_hex), 2)], dtype=torch.uint8) | |
tip_recipient_tensor = address_to_byte_tensor(tip_recipient_address) | |
print(f"Tip Recipient Tensor: {tip_recipient_tensor}") | |
# Define un modelo que genera como salida el address que recibirá el tip | |
class FixedHexAddressModel(nn.Module): | |
def __init__(self, address_tensor): | |
super(FixedHexAddressModel, self).__init__() | |
self.output_value = address_tensor | |
def forward(self, x): | |
# Ignora los inputs y siempre devuelve una dirección fija | |
batch_size = x.size(0) | |
return self.output_value.repeat(batch_size, 1) # Repeat for batch size | |
# Instancia el modelo | |
circuit = FixedHexAddressModel(tip_recipient_tensor) | |
# Input ejemplo | |
dummy_input = torch.ones(1, 1) # Dummy input (not used by the model) | |
# Genera el output | |
output = circuit(dummy_input) | |
print(f"Output (Hex Address): {output}") | |
# Exporta el model en el formato de Onnx | |
torch.onnx.export( | |
circuit, | |
dummy_input, | |
"fixed_hex_address_model.onnx", | |
input_names=["input"], | |
output_names=["output"], | |
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}} | |
) | |
print("Model saved as 'fixed_hex_address_model.onnx'!") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import asyncio | |
from torch import nn | |
import ezkl | |
import os | |
import json | |
import torch | |
class MyModel(nn.Module): | |
def __init__(self): | |
super(MyModel, self).__init__() | |
self.conv1 = nn.Conv2d(in_channels=1, out_channels=2, kernel_size=5, stride=2) | |
self.conv2 = nn.Conv2d(in_channels=2, out_channels=3, kernel_size=5, stride=2) | |
self.relu = nn.ReLU() | |
self.d1 = nn.Linear(48, 48) | |
self.d2 = nn.Linear(48, 10) | |
def forward(self, x): | |
# 32x1x28x28 => 32x32x26x26 | |
x = self.conv1(x) | |
x = self.relu(x) | |
x = self.conv2(x) | |
x = self.relu(x) | |
# flatten => 32 x (32*26*26) | |
x = x.flatten(start_dim = 1) | |
# 32 x (32*26*26) => 32x128 | |
x = self.d1(x) | |
x = self.relu(x) | |
# logits => 32x10 | |
logits = self.d2(x) | |
return logits | |
async def my_async_function(): | |
circuit = MyModel() | |
model_path = os.path.join('network.onnx') | |
compiled_model_path = os.path.join('network.compiled') | |
pk_path = os.path.join('test.pk') | |
vk_path = os.path.join('test.vk') | |
settings_path = os.path.join('settings.json') | |
witness_path = os.path.join('witness.json') | |
data_path = os.path.join('input.json') | |
shape = [1, 28, 28] | |
# After training, export to onnx (network.onnx) and create a data file (input.json) | |
x = 0.1*torch.rand(1,*shape, requires_grad=True) | |
# Flips the neural net into inference mode | |
circuit.eval() | |
# Export the model | |
torch.onnx.export(circuit, # model being run | |
x, # model input (or a tuple for multiple inputs) | |
model_path, # where to save the model (can be a file or file-like object) | |
export_params=True, # store the trained parameter weights inside the model file | |
opset_version=10, # the ONNX version to export the model to | |
do_constant_folding=True, # whether to execute constant folding for optimization | |
input_names = ['input'], # the model's input names | |
output_names = ['output'], # the model's output names | |
dynamic_axes={'input' : {0 : 'batch_size'}, # variable length axes | |
'output' : {0 : 'batch_size'}}) | |
data_array = ((x).detach().numpy()).reshape([-1]).tolist() | |
data = dict(input_data = [data_array]) | |
# Serialize data into file: | |
json.dump( data, open(data_path, 'w' )) | |
py_run_args = ezkl.PyRunArgs() | |
py_run_args.input_visibility = "public" | |
py_run_args.output_visibility = "public" | |
py_run_args.param_visibility = "fixed" # "fixed" for params means that the committed to params are used for all proofs | |
res = ezkl.gen_settings(model_path, settings_path, py_run_args=py_run_args) | |
assert res == True | |
cal_path = os.path.join("calibration.json") | |
data_array = (torch.rand(20, *shape, requires_grad=True).detach().numpy()).reshape([-1]).tolist() | |
data = dict(input_data = [data_array]) | |
# Serialize data into file: | |
json.dump(data, open(cal_path, 'w')) | |
await ezkl.calibrate_settings(cal_path, model_path, settings_path, "resources") | |
res = ezkl.compile_circuit(model_path, compiled_model_path, settings_path) | |
assert res == True | |
# srs path | |
res = await ezkl.get_srs( settings_path) | |
res = await ezkl.gen_witness(data_path, compiled_model_path, witness_path) | |
assert os.path.isfile(witness_path) | |
# HERE WE SETUP THE CIRCUIT PARAMS | |
# WE GOT KEYS | |
# WE GOT CIRCUIT PARAMETERS | |
# EVERYTHING ANYONE HAS EVER NEEDED FOR ZK | |
res = ezkl.setup( | |
compiled_model_path, | |
vk_path, | |
pk_path, | |
) | |
assert res == True | |
assert os.path.isfile(vk_path) | |
assert os.path.isfile(pk_path) | |
assert os.path.isfile(settings_path) | |
# GENERATE A PROOF | |
proof_path = os.path.join('test.pf') | |
res = ezkl.prove( | |
witness_path, | |
compiled_model_path, | |
pk_path, | |
proof_path, | |
"single", | |
) | |
print(res) | |
assert os.path.isfile(proof_path) | |
# VERIFY IT | |
res = ezkl.verify( | |
proof_path, | |
settings_path, | |
vk_path, | |
) | |
assert res == True | |
print("verified") | |
# Define el archivo donde se generará el ABI y el código Solidity | |
abi_path = 'test.abi' | |
sol_code_path = 'test.sol' | |
# Crea el código Solidity del verificador basado en el circuito previamente generado | |
res = await ezkl.create_evm_verifier( | |
vk_path, | |
settings_path, | |
sol_code_path, | |
abi_path, | |
) | |
assert res == True | |
# Imprime el código Solidity en la consola | |
with open(sol_code_path, 'r') as sol_file: | |
sol_content = sol_file.read() | |
print(sol_content) | |
return 17 | |
async def main(): | |
result = await my_async_function() | |
print(result) | |
# Run the main coroutine | |
asyncio.run(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment