Getting Started

The life cycle of a proof

There are three steps in the life of an EZKL proof: Setup, Prove, and Verify. Each step is generally performed by a different party.

Setup

Setup is invoked with EZKL setup at the cli or ezkl.setup() in Python. It defines what constitutes a proof and how that proof will be verified, setting the rules of the game. Setup is performed by the application developer, who then deploys the resulting artifacts to production.

The inputs to setup are:

  • the model (as an onnx file)

  • the structured reference string which is a common, public piece of cryptographic data shared among proof setups of the same size

  • various flags, settings, and options for tuning and added functionality

The outputs of setup are:

  • the proving key

  • the verification key, and

  • the circuit settings: serialized flags, settings, and options, and a few numbers that describe the shape of the resulting circuit.

Before setup can run, the settings need to be generated with gen-settings and optionally calibrate-settings, and the model must be compiled.

ezkl.gen_settings(onnx_filename, settings_filename)
ezkl.calibrate_settings(
    input_filename, onnx_filename, settings_filename, "resources")
res = ezkl.compile_model(model_path, compiled_model_path, settings_path)
res = ezkl.setup(
        compiled_model_path,
        vk_path,
        pk_path,
        srs_path,
        settings_path,
    )

Prove

Prove, invoked with EZKL prove at the cli or ezkl.prove() in Python, is called by the prover, often on the client. The prover is making a claim that it knows some inputs (which might include model parameters), such that when the model (chosen during setup) is run on them, produces certain outputs. The prove command computes a cryptographic proof of that claim, which can then be believed by any verifier.

The inputs to prove are:

  • the witness data for the claim: an (input, output) pair (x,y) such that model(input) = output (this pair can be produced from x using the gen-witness command)

  • the model (as a compiled model file, made from an onnx file)

  • the proving key

  • the structured reference string, and

  • the circuit settings.

The outputs of prove are:

  • the proof file.

res = ezkl.gen_witness(data_path, compiled_model_path, witness_path, settings_path = settings_path)
res = ezkl.prove(
        witness_path,
        compiled_model_path,
        pk_path,
        proof_path,
        srs_path,
        "evm",
        "single",
        settings_path,
    )

Verify

EZKL can produce an EVM verifier contract which takes only the proof as input, and this is the normal use case.

res = ezkl.create_evm_verifier(
        vk_path,
        params_path,
        settings_filename,
        sol_code_path,
        abi_path,
    )

# assuming anvil is running
res = ezkl.deploy_evm(
    address_path,
    sol_code_path,
    'http://127.0.0.1:3030'
)
res = ezkl.verify_evm(
    proof_path,
    addr,
    "http://127.0.0.1:3030"
)

Verification can also be invoked with EZKL verify at the cli, ezkl.verify() in Python, or with WASM. It checks the correctness of the cryptographic proof produced by the prover.

The inputs to (non-EVM) verify are:

  • the proof file

  • the verification key

  • the circuit settings, and

  • the structured reference string

Last updated