1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! This library is intended to generate proofs with the [plonky2 zkEVM](https://github.com/0xPolygonZero/plonky2/evm), given
//! transactions provided in Intermediate Representation (IR) format.
//!
//! The exact format of this IR is defined by the [GenerationInputs](https://github.com/0xPolygonZero/plonky2/evm/src/generation/mod.rs)
//! used by the zkEVM prover, containing an RLP-encoded transaction along with
//! state metadata prior and post execution of this transaction.
//!
//! # Usage
//!
//! First, a prover needs to initialize its `ProverState`. For this, one can
//! use the `ProverStateBuilder`, which contains the ranges to be used by all
//! internal STARK tables of the zkEVM.
//!
//! The default method contains an initial set of ranges for each table, that
//! can be overridden at will by calling
//! `ProverStateBuilder::set_foo_circuit_size` where `foo` is the name of the
//! targeted table. At the moment, plonky2 zkEVM contains seven tables:
//! `arithmetic`, `byte_packing`, `cpu`, `keccak`, `keccak_sponge`, `logic` and
//! `memory`.
//!
//! ```no_run
//! # use proof_gen::prover_state::ProverStateBuilder;
//! let mut builder = ProverStateBuilder::default();
//!
//! // Change Cpu and Memory tables supported ranges.
//! let builder = builder
//! .set_cpu_circuit_size(12..25)
//! .set_memory_circuit_size(18..28);
//!
//! // Generate a `ProverState` from the builder.
//! let prover_state = builder.build();
//! ```
//!
//! ***NOTE***: All the circuits to generate the different kind of proofs, from
//! transaction proofs to block proofs, are specific to the initial set of
//! ranges selected for each table. Changing one of them will require building a
//! new `ProverState`, and will make all previously generated proofs
//! incompatible with the new state. Make sure you select sufficiently large
//! ranges for your application!
//!
//! Once all circuits have been pre-processed, a prover can now generate proofs
//! from inputs passed as Intermediary Representation.
//!
//! This library handles the 3 kinds of proof generations necessary for the
//! zkEVM:
//!
//! ### Transaction proofs
//!
//! From a `ProverState` and a transaction processed with some metadata in
//! Intermediate Representation, one can obtain a transaction proof by calling
//! the method below:
//!
//! ```compile_fail
//! pub fn generate_txn_proof(
//! p_state: &ProverState,
//! gen_inputs: GenerationInputs,
//! abort_signal: Option<Arc<AtomicBool>>,
//! ) -> ProofGenResult<GeneratedTxnProof> { ... }
//! ```
//!
//! The obtained `GeneratedTxnProof` contains the actual proof and some
//! additional data to be used when aggregating this transaction with others.
//!
//! ### Aggregation proofs
//!
//! Two proofs can be aggregated together with a `ProverState`. These `child`
//! proofs can either be transaction proofs, or aggregated proofs themselves.
//! This library abstracts their type behind an `AggregatableProof` enum.
//!
//! ```compile_fail
//! pub fn generate_agg_proof(
//! p_state: &ProverState,
//! lhs_child: &AggregatableProof,
//! rhs_child: &AggregatableProof,
//! ) -> ProofGenResult<GeneratedAggProof> { ... }
//! ```
//!
//! ### Block proofs
//!
//! Once the prover has obtained a `GeneratedAggProof` corresponding to the
//! entire set of transactions within a block, they can then wrap it into a
//! final `GeneratedBlockProof`. The prover can pass an optional previous
//! block proof as argument to the `generate_block_proof` method, to combine
//! both statement into one, effectively proving an entire chain from genesis
//! through a single final proof.
//!
//! ```compile_fail
//! pub fn generate_block_proof(
//! p_state: &ProverState,
//! prev_opt_parent_b_proof: Option<&GeneratedBlockProof>,
//! curr_block_agg_proof: &GeneratedAggProof,
//! ) -> ProofGenResult<GeneratedBlockProof> { ... }
//! ```
//!
//! ## Verifying block proofs
//!
//! The `ProverState` can be used to verify any block proofs emitted with the
//! same set of circuits.
//! However, because the prover state can be quite heavy, the necessary verifier
//! data to verify block proofs can be saved independently into a
//! `VerifierState`, to allow anyone to easily verify block proofs.
//!
//! ```compile_fail
//! # use proof_gen::prover_state::ProverStateBuilder;
//! # use proof_gen::verifier_state::VerifierState;
//! let mut builder = ProverStateBuilder::default();
//!
//! // Generate a `ProverState` from the builder.
//! let prover_state = builder.build();
//!
//! // Derive a `VerifierState` from the `ProverState`.
//! let verifier_state: VerifierState = prover_state.into();
//!
//! // The prover generates some block proof.
//! let block_proof = prover_state.generate_block_proof(...);
//!
//! // Have the verifier attest validity of the proof.
//! assert!(verifier_state.verify(block_proof.intern).is_ok());
//! ```
pub
// Re-exports
pub use ProverState;
pub use VerifierState;