Skip to content

Instantly share code, notes, and snippets.

@Turupawn
Last active March 25, 2025 05:28
Show Gist options
  • Save Turupawn/55ad199f273cfd6bc2ff886be84ed6d0 to your computer and use it in GitHub Desktop.
Save Turupawn/55ad199f273cfd6bc2ff886be84ed6d0 to your computer and use it in GitHub Desktop.
ezkl locally
# 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'!")
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