Plonk.Main_protocol
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.
include module type of struct include Main_protocol_intf end
module SMap = Plonk.Main_protocol_intf.SMap
module type S = Main_protocol_intf.S
module Make_impl (PP : Polynomial_protocol.S) : sig ... end
module Make
(PP : Polynomial_protocol.S) :
S with type public_inputs = Kzg.Bls.Scalar.t array list
include sig ... end
module Input_commitment : sig ... end
type scalar = Kzg.Bls.Scalar.t
val scalar_t : scalar Repr.t
val scalar_encoding : scalar Data_encoding.t
type circuit_map = (Circuit.t * int) Kzg.SMap.t
type prover_public_parameters =
Make(Polynomial_protocol).prover_public_parameters
val prover_public_parameters_t : prover_public_parameters Repr.t
type verifier_public_parameters =
Make(Polynomial_protocol).verifier_public_parameters
val verifier_public_parameters_t : verifier_public_parameters Repr.t
val verifier_public_parameters_encoding :
verifier_public_parameters Data_encoding.t
type proof = Make(Polynomial_protocol).proof
val proof_t : proof Repr.t
val proof_encoding : proof Data_encoding.t
type circuit_prover_input = Make(Polynomial_protocol).circuit_prover_input = {
witness : scalar array;
input_commitments : Input_commitment.t list;
}
val circuit_prover_input_t : circuit_prover_input Repr.t
type prover_inputs = circuit_prover_input list Kzg.SMap.t
val prover_inputs_t : prover_inputs Repr.t
type public_inputs = Kzg.Bls.Scalar.t array list
val public_inputs_t : public_inputs Repr.t
type circuit_verifier_input = Make(Polynomial_protocol).circuit_verifier_input =
{
nb_proofs : int;
public : public_inputs;
commitments : Input_commitment.public list list;
}
val circuit_verifier_input_t : circuit_verifier_input Repr.t
type verifier_inputs = circuit_verifier_input Kzg.SMap.t
val verifier_inputs_t : verifier_inputs Repr.t
val to_verifier_inputs :
prover_public_parameters ->
prover_inputs ->
verifier_inputs
val input_commit :
?size:int ->
?shift:int ->
prover_public_parameters ->
scalar array ->
Input_commitment.t
val setup :
zero_knowledge:bool ->
circuit_map ->
srs:(Kzg.Bls.Srs.t * Kzg.Bls.Srs.t) ->
prover_public_parameters * verifier_public_parameters
val update_prover_public_parameters :
'a Repr.ty ->
'a ->
prover_public_parameters ->
prover_public_parameters
val update_verifier_public_parameters :
'a Repr.ty ->
'a ->
verifier_public_parameters ->
verifier_public_parameters
val prove : prover_public_parameters -> inputs:prover_inputs -> proof
val verify :
verifier_public_parameters ->
inputs:verifier_inputs ->
proof ->
bool
module Internal_for_tests : sig ... end