|
| 1 | +# Architecture |
| 2 | + |
| 3 | +This document explains the architecture of the current implementation. |
| 4 | + |
| 5 | +The main logic of the POD2 implementation is divided into three modules: |
| 6 | +- frontend |
| 7 | + - compiles user-friendly pod declarations into intermediate representations to be consumed by the backend |
| 8 | + - internally connects to the backend to get pods built (signed / proved). |
| 9 | + - presents pods to the user |
| 10 | +- middleware |
| 11 | + - defines the intermediate representation of Statements, Operations and interfaces of PODs |
| 12 | + - Statements and Operations are strongly typed here |
| 13 | + - Both frontend and backend use types defined in the middleware |
| 14 | + - Does not import types from frontend nor backend |
| 15 | +- backend |
| 16 | + - takes a middleware POD request representation, signs/proves it and returns a generic POD object |
| 17 | + |
| 18 | +If this was the Rust language compiler: |
| 19 | +- frontend: takes a Rust code and compiles it to LLVM-IR |
| 20 | +- middleware: defines LLVM-IR instructions and blocks |
| 21 | +- backend: Takes LLVM-IR instructions and emits assembly code for a particular CPU |
| 22 | + |
| 23 | +The following diagram shows visually how the components interact with each other: |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +In this organization, the middleware could be defined at arbitrary points: |
| 28 | +- closer to the user would be more high level |
| 29 | +- closer to the target would be more low level |
| 30 | + |
| 31 | +All these positions are OK. We just need to choose one, and we can try to choose a point that simplifies the implementation. |
| 32 | + |
| 33 | +For example in the middleware we could define `Value = 4 x Goldilock` (making it slightly low level); or `Value = BigUint` and letting the backend choose the maximum representable value, the field encoding, etc. (making it slightly higher level). |
| 34 | + |
| 35 | +In the current iteration we choose `Value = 4 x Goldilock`, but we can revisit it in a future iteration (eg. if we want to support plonky3) by either moving the middleware to a higher level, or by keeping it the same and replacing the `Value` definition. |
| 36 | + |
| 37 | +The diagram above includes an arrow that would show the typical flow followed by a user making a POD. This is a simplified description of the process. |
| 38 | +1. The user interacts with the frontend API and passes a list of Operations. The frontend takes those operations and generates the corresponding Statements. The list of Operations and Statements are transformed into middleware types. This process can be seen as a compilation step. The frontend sends this middleware data as a request to the Backend. |
| 39 | +2. The backend receives a request to build a POD from a list of Statements and Operations. It takes that bundle of data and lays it out in the appropriate format to be proved by a circuit, padding unused slots, etc. Then it calls a proof system API to generate a proof. |
| 40 | +3. The target (proof system) generates a proof from some circuit description and witness data and gives it back to the backend. |
| 41 | +4. The backend receives the proof and encapsulates it in an object that adheres to the Pod trait and passes it to the frontend |
| 42 | +5. The frontend receives a "blackbox" Pod object and wraps it in a presentation layer in order to show it to the user. |
0 commit comments