package tezos-plonk

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

aPlonK is a PlonK-based proving system. As such, it provides a way to create succinct cryptographic proofs about a given predicate, which can be then verified with a low computational cost.

In this system, a predicate is represented by an arithmetic circuit, i.e. a collection of arithmetic gates operating over a prime field, connected through wires holding scalars from this field. For example, the following diagram illustrates a simple circuit checking that the addition of two scalars (w1 and w2) is equal to w0. Here, the add gate can be seen as taking two inputs and producing an output, while the eq gate just takes two inputs and asserts they're equal.

(w0)│ w1│ w2│ │ └───┐ ┌───┘ │ ┌─┴───┴─┐ │ │ add │ │ └───┬───┘ └──────┐ ┌───┘w3 ┌─┴───┴─┐ │ eq │ └───────┘

The wires of a circuit are called prover inputs, since the prover needs an assignment of all wires to produce a proof. The predicate also declares a subset of the wires called verifier inputs. In our example, wire w0 is the only verifier input, which is indicated by the parenthesis. A proof for a given w0 would prove the following statement: ∃ w1, w2, w3: w3 = w1 + w2 ∧ w0 = w3 This means that the verifier only needs a (typically small) subset of the inputs alongside the (succinct) proof to check the validity of the statement.

A more interesting example would be to replace the add gate by a more complicated hash circuit. This would prove the knowledge of the pre-image of a hash.

A simplified view of aPlonk's API consists of the following three functions: val setup : circuit -> srs -> (prover_public_parameters, verifier_public_parameters) val prove : prover_public_parameters -> prover_inputs -> private_inputs -> proof val verify : verifier_public_parameters -> verifier_inputs -> proof -> bool

In addition to the prove and verify, the interface provides a function to setup the system. The setup function requires a Structured Reference String. Two large SRSs were generated by the ZCash and Filecoin projects and are both used in aPlonK. Notice also that the circuit is used during setup only and, independently from its size, the resulting verifier_public_parameters will be a succinct piece of data that will be posted on-chain to allow verification and they are bound to the specific circuit that generated them. The prover_public_parameters's size is linear in the size of the circuit.

module Make_impl (PP : Polynomial_protocol.S with type PC.Scalar.t = Plompiler.S.t) : sig ... end
module type S = sig ... end
include sig ... end
exception Rest_not_null of string

Raised by the prover when the provided inputs are not a satisfying assignment of the circuit.

exception Entry_not_in_table of string

Raised by the prover when the provided inputs are not a satisfying assignment of the circuit when using Plookup.

module Scalar : sig ... end

Prime field used by aPlonk

type scalar = Scalar.t
val scalar_t : scalar Repr.t
val scalar_encoding : scalar Data_encoding.t
type circuit_map = (Circuit.t * int) SMap.t

Before proving and verifying, circuits go through a pre-processing step called setup. The setup takes as input a circuit_map, which associates an identifier to a circuit and the number of statements that can be proved with that circuit. This produces a set of public_parameters which are bound to the circuits and can be reused.

Set of public_parameters needed by the prover. It's size is linear in the size of the circuits.

val prover_public_parameters_t : prover_public_parameters Repr.t

Set of public_parameters needed by the verifier. It's size is constant w.r.t. the size of the circuits.

val verifier_public_parameters_t : verifier_public_parameters Repr.t
val verifier_public_parameters_encoding : verifier_public_parameters Data_encoding.t

Succinct proof for a collection of statements.

val proof_t : proof Repr.t
val proof_encoding : proof Data_encoding.t
type circuit_prover_input = Make(Polynomial_protocol).circuit_prover_input = {
  1. public : scalar array;
  2. witness : scalar array;
}

Prover inputs for one statement. Witness is the assignment of all wires of the circuit.

type prover_inputs = circuit_prover_input list SMap.t

Map where each circuit identifier is bound to a list of circuit_prover_input for a list of statements.

type circuit_verifier_input = Polynomial_protocol.PC.Scalar.t array list
type verifier_inputs = circuit_verifier_input SMap.t

Map where each circuit identifier is bound to the verifier inputs for this circuit.

val to_verifier_inputs : prover_inputs -> verifier_inputs

Conversion from prover_inputs to verifier_inputs.

setup ~zero_knowledge circuit_map ~srs pre-processes the circuit_map producing the public parameters. The SRSs of ZCash and Filecoin can be loaded from file using the Bls12_381_polynomial library. Activating zero_knowledge adds an overhead in proving time.

val update_prover_public_parameters : Stdlib.Bytes.t -> prover_public_parameters -> prover_public_parameters

Enrich the prover_public_parameters with extra application data to prevent replay attacks. The same data must be used for updating the prover and verifier public parameters.

val update_verifier_public_parameters : Stdlib.Bytes.t -> verifier_public_parameters -> verifier_public_parameters

Enrich the verifier_public_parameters with extra application data to prevent replay attacks. The same data must be used for updating the prover and verifier public parameters.

prove public_parameters ~inputs produces a proof for the collection of statements implied by inputs and the circuits used for generating public_parameters.

val verify : verifier_public_parameters -> inputs:verifier_inputs -> proof -> bool

verify public_parameters ~inputs proof checks the validity of the proof with regards to public_parameters and inputs.

module Internal_for_tests : sig ... end