From ba727c68c2d5972d1562f30ebade120d4622a71f Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Thu, 5 Oct 2023 12:31:19 +0200 Subject: [PATCH] adjust reamde --- README.md | 35 +++++++++++++++++------------------ book/src/powdr_wires.png | Bin 0 -> 20312 bytes 2 files changed, 17 insertions(+), 18 deletions(-) create mode 100644 book/src/powdr_wires.png diff --git a/README.md b/README.md index 430b0032a..a64694c60 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,33 @@ +

+ +

+ # powdr [![Matrix Chat](https://img.shields.io/badge/Matrix%20-chat-brightgreen?style=plastic&logo=matrix)](https://matrix.to/#/#powdr:matrix.org) [![Twitter Follow](https://img.shields.io/twitter/follow/powdr_labs?style=plastic&logo=twitter)](https://twitter.com/powdr_labs) -*powdr* is an extended polynomial identity (PIL) and zk-focused assembly (zkASM) -language written in Rust, focused on modularity and excellent developer experience. +> WARNING: This codebase is experimental and has not been audited. DO NOT USE FOR PRODUCTION! -WARNING: This is a proof-of-concept implementation. It is missing many internal checks. DO NOT USE FOR PRODUCTION! - -## Basic Concept +For detailed documentation please visit [the powdr book](https://docs.powdr.org/). *powdr* is a toolkit that helps build zkVMs and similar proof frameworks. It has two main components: -- A polynomial identity language that allows you to define polynomial constraints, lookups, etc. -- An extensible assembly language to perform dynamic executions. +- powdr-asm: an extensible assembly IR language to perform dynamic executions. +- powdr-PIL: a low level constraint language that allows you to define arithmetic constraints, lookups, etc. Both frontend and backend are highly flexible. As an example, *powdr* contains a frontend that enables you to write code in (no-std) Rust, -which is compiled to RISCV, then to powdr-asm and finally to PIL. +which is compiled to RISCV, then to powdr-asm and finally to powdr-PIL. *powdr*-pil can be used to generate proofs using multiple backends, such as: -- Halo2 -- eSTARKs: *powdr*-pil is fully compatible with the eSTARKS backend from Polygon Hermez, - although not yet fully integrated in an automatic way. -- Nova: ongoing work. -- other STARKs: maybe? +- Halo2: via [polyexen](https://github.com/Dhole/polyexen) and [snark-verifer](https://github.com/privacy-scaling-explorations/snark-verifier/) +- eSTARK: via [Eigen's starky](https://github.com/0xEigenLabs/eigen-zkvm/) +- SuperNova: ongoing work (https://github.com/powdr-labs/powdr/pull/453) All stages are fully automatic, which means you do not need to write any additional code for witness generation besides your Rust code. All witnesses @@ -37,7 +36,7 @@ inferred, *powdr* can ensure that the system is not underconstrained, i.e. there are no additional unwanted witnesses. All artifacts from the compilation pipeline are human-readable. This means you -can inspect the RISCV assembly files, the powdr-asm, and the PIL file. +can inspect the RISCV assembly files, the powdr-asm IR, and the compiled PIL file. The assembly language is designed to be extensible. This means that it does not have a single native instruction. Instead, all instructions are user-defined and because of that, @@ -45,10 +44,10 @@ it is easy to adapt *powdr* assembly to any VM. ### Notes on Efficiency -Currently, the code is quite wasteful. It generates many unnecessary columns. -The idea is to first see if automatic witness generation is possible in general. -If this is confirmed, various optimizer stages will be built to reduce the -column (and row) count automatically. +The current focus of the project is VM support and developer experience. The +compiler generates many unnecessary columns. We will soon start writing +optimizer steps that should bring performance closer to existing production +systems. ### Project structure diff --git a/book/src/powdr_wires.png b/book/src/powdr_wires.png new file mode 100644 index 0000000000000000000000000000000000000000..2772f906e31420cdfd55cc4d03c4ac033ce4303a GIT binary patch literal 20312 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 literal 0 HcmV?d00001