• This repository has been archived on 15/Aug/2024
  • Stars
    star
    302
  • Rank 138,030 (Top 3 %)
  • Language
    Rust
  • License
    Other
  • Created over 1 year ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Boojum, the scariest SNARK implementation.

Boojum

Logo

zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers write smart contracts in C++, Rust and other popular languages.

About

The purpose of this library is to work with a very specific arithmetization with additional assumptions about the field size. Roughly, we expect to have a field F with |F| ~ 64 bits (the size of a machine word) (the assumption about field size is not important for the strategy of arithmetization and gate placement, but it is asserted in gadget implementations for particular functions which rely on a specific field size).

The system has a hierarchy of logical function (gadgets) - gates (entities that can inscribe itself into trace) - and evaluators (relations between polynomials). Evaluators are written in the form of a trait that allows us to later on automatically compose functions to check satisfiability and compute proofs, as well as synthesize plain and recursive verifiers. Gates have additional tooling attached to them that allows the gates themselves to track the logic of where they should be placed in the trace. Note that we rely on Plonk's copy constraints and work on the copiable logical entities of "variables" to compose a final provable statement. The system is not intended for AIR arithmetization and doesn't allow to express constraints that span multiple rows of the trace.

In general, the trace contrains few varieties of columns. The main separation is between:

  • General purpose columns - where one can allow some columns of variables (copiable), witnesses (non-copiable, also sometimes called "advice" columns) and constants to be used by DIFFERENT TYPES of gates, leading to the necessity to place selectors in front of the corresponding terms in the quotient polynomial. For these general purpose columns, the placement logic is simple: we try to put in as many repetitions of the same relation as the gate/evaluator allows, based on the designated number of columns of the corresponding type in the system. Later on, when selectors are materialized, a few extra constant columns can be added. In general, the default behavoir of the gates is to try to "amortize" constants, in a sense that over the same row, we try to place gates that use same constants. This is a reasonable approach because most of the circuits are "cycles" in practice, so we can "fill" the row.
  • "Specialized" columns - where one can designate a separate set of columns to the particular gate/evaluator, so the relation enforced by evaluator must hold on every row in these columns. This may be beneficial in some circuits where a particular gate is used very often. One can specify few different modes of utilization of these columns in the case of multiple sets being spent for the same relations, namely to share constants or not between sets.

In addition, the trace allows you to add a lookup argument, which can also either use specialized columns to house the entries of the lookup tables, or just use general purpose columns. Tables are encoded as only one set of polynomials for now, so the total length of the trace must be larger than the total number of entries in the tables.

Note that every "gate" (as a Rust type) is unique, and so a gate can only be placed into either specialized or general purpose columns, but not into both. If one needs such functionality then it's possible to make a newtype wrapper.

Higher level logical functions (like boolean decompositions, range checks, zero checks, etc) are used to make a circuit internally inscribe themselves in different manners depending if some gates are allowed or not allowed in the particular instance of the CS. Instances of the CS with different sets of gates are considered a different type from the Rust perspective, and we rely on some inlining/constant prop/compiler work to reduce branching into static jumps.

Notes on subparts of construction

  • Only the 2^64 - 2^32 + 1 field is implemented. The non-vectorized math implementation is based on the implementation developed for Plonky2, but is reformulated for const traits
  • Auto-vectorization is performed mainly for additions, where benefits are clear
  • Poseidon MDS and round constants are equal to Plonky2 to have some compatibility for users
  • Poseidon2 round constants reuses the Poseidon constants
  • Arithmetization constraints only affect one row. The placement strategy is to amortize constants as much as possible by tiling row-wise or column-wise
  • Copy-permutation argument is taken from Plonk (the grand product based one). May be changed to log-derivative (the additive one) later on
  • Lookup argument is log-derivative (the additive one)
  • Lookup tables in a circuit must all be the same width for now
  • No columns can be separated from the oracles and fed into another proof yet
  • At the moment, the movement to the extension field is only done on FRI aggregation (so during previous stages challenges are of |F| and so we have to repeat arguments), but this will be changed so that we move to the extension field as fast as possible after committing to the witness to avoid a quite "large" chance of getting zeroes in denominator. The effect on computational expense in proving is quite negligible
  • Zero-knowledge is not yet implemented, but planned (gates will itself determine how to put a satisfying, but random witness in their yet unused rows)
  • FFT is not optimized
  • Hashes are somewhat optimized
  • Implemented gates are opinionated, as well as arithmetizations

Note on lookup argument

We use a lookup argument enforced via the relations \sum_i selector(x_i) / (witness(x_i) + beta) == \sum_i multiplicity(x_i) / (table(x_i) + beta) where a lookup over specialized columns selector(x_i) is just an identity. We also do not encode the tables as the polynomial of smaller degree to eliminate extra degree bound checks, and instead pad them with zeroes. Note that table entries never contain an element of (0,0,...,0) as we use separate ID columns for table types in case of multiple tables (even in the case of only one table being used), and an ID like this starts with 1.

One nice feature of a lookup argument like this is that, due to its additive nature, if we do lookups over multiple witness polynomials into the same table, instead of repeating the argument for every (tuple of) polynomial(s) (which would require a separate multiplicity column, as well as few a intermediate polynomials later on), we can "add up" multiplicities and transform the argument into something like \sum_i selector_0(x_i) / (witness_0(x_i) + beta) + \sum_i selector_1(x_i) / (witness_1(x_i) + beta) == \sum_i total_multiplicity(x_i) / (table(x_i) + beta), so that the total cost of a lookup is just 1 multiplicities column, and 2 (witness-related) + 1 (table-related) intermediate polynomials to encode the lhs and rhs relations on the roots of unity.

The correctness of this argument is clear. For soundness, we use the original argument as in the "Cached quotients for fast lookups" paper, Lemma 2.4. We need to show that it suffices to commit to the total_multiplicity rather than to the multiplicities of witness_0 and witness_1 separately.

Suppose the equation \sum_i selector_0(x_i) / (witness_0(x_i) + X) + \sum_i selector_1(x_i) / (witness_1(x_i) + X) == \sum_i total_multiplicity(x_i) / (table(x_i) + X) holds. We need to show that witness_0 and witness_1 are contained in the table t. Let f = (witness_0 | witness_1), a concatenation of the values. The equation above implies \sum_i selector_i / (f_i + X) == \sum_i total_multiplicity_i / (t_i + X) (note that the interval length of i on the LHS is double than the above). By Lemma 2.4 we get f \subset t: "subset" in the sense that every coordinate of the vector f is a coordinate of t. In particular, witness_0, witness_1 \subset f \subset t.

Note that the argument holds for several witness_i as well. The rest of the soundness argument, for a chosen \beta, follows directly as in the work above.

Planned extensions

  • Allow lookup tables of different "width" (Unlikely now, we need to update type system a little)
  • Split the CS into a "configurable" part (where one can allow gates and static tools), and an "inscribable" part (where one can put variables, gates, etc). So one first configures, then "freezes" and then inscribes, and can not make a mistake along the way
  • Allow an alternative selector mode (individual insteal of tree) for rare circuits that need it. Because we have a huge number of setup polynomials from copy-permutation anyways, flat selectors are not that expensive if they allow to avoid pushing quotient degree 2x
  • Make u16/u32 use "static" caches for decompositions instead of "dynamic" ones
  • Make "dyn" verifier, so all it's descendants are "Self". Note: most likely unnecessary
  • Move to the field extension "earlier", because it only affects the copy-permutation product and lookup argument parts, and this tradeoff is acceptable in comparison to the 2^-40 chance to get 0 in denominators
  • Switch to generic logging
  • Switch to Poseidon2 by default
    • Note on Monolith: even though it's blazing fast, it has a drawback where it's very hard to just unroll it into single "row" as it mixes lookups and algebraic relations. It may not be the best suited for circuit instances of large width
  • Actually optimize FFT
  • Check what's the most optimal strategy to evaluate gates over general purpose columns
  • Merge new DAG resolver (10-100x faster)
  • Tune consistency check for auxilary lookup polynomials to utilize higher-degree constraint if it's "free" (if we would already do higher degree extension anyway for copy-permutation, or gates)

For curions in benchmarks only

There are benchmarks for 8kB of SHA256 using what we think is somewhat optimal configuration of gates + tables for SHA256 circuit. Note that even though the prover is kind-of fast, we didn't properly optimize the FFT and still use Poseidon (not Poseidon2) for configurations where we expect the proof to be used for recursion. Two scripts sha256_bench_recursive.sh and sha256_bench_non_recursive.sh allow you to run the corresponding tests (whether proof is expected to be used in recursion or not), and you should look for a line Proving is done, taken ... to see the proving time, because the verifier that runs after it is quite verbose. These benchmarks use an LDE factor of 8, even though all our constraints are of degree 4 or less - however, it's a parameter that is used in some other public benchmarks. We also do not use PoW in those proofs because PoW for 20 bits is negligible (30ms), and we do not support PoW over algebraic hashes yet (however those are only ~2x slower, so also negligible). Security level is roughly 100 bits, but the FRI soundness can be boosted by increaseing the number of queries, and an increase in number of queries doesn't increase prover time (not to be confused with changing the FRI rate). Trace length is 2^16 and it uses 60 general purpose columns and 8 lookup arguments of width 4.

Note: benchmarks just try to compile to native arch and only AArch64 (read Apple M1) arch is normally tested end-to-end for now. x86-64 arithmetic implementations were tested for validity, but not end-to-end in full proofs. Note that max performance x86-64 requires extra compiler feature flags in addition to cpu = native (AVX512 set is not used by Rust compiler even on native CPUs)

License

The Boojum prover is distributed under the terms of either

at your option.

Official Links

Disclaimer

zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! It is important to state that forking it now can potentially lead to missing important security updates, critical features, and performance improvements.

Third party notices

This software includes components from third parties. For a full list of these components and their licenses, see the THIRD PARTY NOTICES file.

More Repositories

1

awesome-zero-knowledge-proofs

A curated list of awesome things related to learning Zero-Knowledge Proofs (ZKP).
5,253
star
2

zksync

zkSync: trustless scaling and privacy engine for Ethereum
Rust
4,883
star
3

zksync-era

zkSync era
Rust
3,084
star
4

zksync-web-era-docs

zkSync Era Documentation
JavaScript
982
star
5

zksync-lite-docs

zkSync Lite documentation
Shell
773
star
6

zksync-wallet-vue

zkSync Lite web wallet
Vue
517
star
7

era-contracts

Smart Contract Submodule For zkSync Era
Solidity
481
star
8

l2-intro-pre-ethdenver

Introduction to layer two and zkSync
TypeScript
355
star
9

era-test-node

In-memory node that can be used for integration testing and debugging.
Rust
308
star
10

zinc

The Zinc language public repository
Rust
308
star
11

foundry-zksync

Fork of Foundry tailored for zkSync environment
Rust
295
star
12

hardhat-zksync

TypeScript
281
star
13

era-sync_vm

Circuit Implementation of zkVM for zkSync Era
Rust
278
star
14

era-system-contracts

Implementation of the system contracts
Solidity
201
star
15

zksync-cli

CLI tool that simplifies ZKsync development
TypeScript
163
star
16

era-tutorial-examples

[DEPRECATED ]Full examples for tutorials in the zkSync Era documentation. Visit: https://github.com/matter-labs/tutorials
TypeScript
129
star
17

zksync-dapp-checkout

zkCheckout — trustable permissionless DeFi payment gateway. Fast & cheap transfers / simple & quick withdrawal
Vue
124
star
18

block-explorer

zkSync Era Block Explorer
TypeScript
123
star
19

franklin-crypto

Rust
115
star
20

paymaster-examples

Ready to use paymaster contracts for zkSync Era
TypeScript
110
star
21

era-zk_evm

Out-of-circuit zkEVM implementation
Rust
81
star
22

hodor

Open source implementation of zkSTARKs in pure Rust
Rust
79
star
23

era-bellman-cuda

A library implementing GPU-accelerated cryptographic functionality for the zkSync prover
Cuda
71
star
24

eip1962

EIP1962 implementation effort
Rust
65
star
25

local-setup

zkSync 2.0 setup for local development
Shell
64
star
26

v2-testnet-contracts

Solidity
63
star
27

era-compiler-solidity

Solidity compiler for ZKsync
Rust
62
star
28

zksync-hardhat-template

[DEPRECATED] Template project for zksync-hardhat
TypeScript
62
star
29

era-consensus

Consensus layer implementation for zkSync Era
Rust
62
star
30

era-zkevm_circuits

Rust
59
star
31

era-zkevm_test_harness

Compare in-circuit and out-of-circuit VMs
Rust
59
star
32

zksolc-bin

Releases of the Solidity compiler for ZKsync
55
star
33

zksync-withdrawal-finalizer

zkSync 2.0 Withdrawal Finalizer
Rust
54
star
34

zk_os

OS for next iteration of the world computer
Rust
45
star
35

tutorials

TypeScript
43
star
36

rescue-poseidon

Rescue and Poseidon hash function implementations
Rust
42
star
37

zksync-link

PayNow - Create payment links, get paid in tokens
Svelte
41
star
38

curve-zinc

The Curve Stableswap smart contract implementation in Zinc v0.2.2.
Rust
40
star
39

solidity_plonk_verifier

Solidity verifier for Plonk
Solidity
38
star
40

era-zkevm_opcode_defs

Definitions of zkEVM opcodes (primary dependency for all other repos)
Rust
38
star
41

recursive_aggregation_circuit

Kate commitment based PLONK recursive aggregation circuit
Solidity
38
star
42

era-compiler-vyper

Vyper compiler for ZKsync
Rust
37
star
43

zksync-contract-templates

Contract Templates for zkSync: solidity, hardhat, vyper
TypeScript
32
star
44

era-compiler-llvm

ZKsync fork of the LLVM framework.
C++
31
star
45

schnorr-musig

Simple Schnorr Multi-Signatures
Rust
28
star
46

custom-aa-tutorial

A full example for the tutorial on custom AA
Solidity
28
star
47

zkSync-account-abstraction-template

28
star
48

era-shivini

A library implementing GPU-accelerated zkSync prover.
Rust
27
star
49

zkvyper-bin

Releases of the Vyper compiler for ZKsync
27
star
50

cross-chain-tutorial

TypeScript
27
star
51

hackathon-winner-projects

A list of all the projects submitted in all zksync hackathons.
25
star
52

era-boojum-cuda

A library implementing GPU-accelerated cryptographic functionality for the zkSync prover.
Rust
25
star
53

era-heavy-ops-service

Specialized GPU Prover for zkSync Era
Rust
24
star
54

vm2

High performance EraVM for zkSync.
Rust
22
star
55

compiler-solidity

The zkEVM Solidity compiler.
Rust
22
star
56

era-boojum-validator-cli

Rust
21
star
57

risc_v_simulator

Rust
20
star
58

custom-paymaster-tutorial

Full example for the custom paymaster tutorial in the documentation
TypeScript
20
star
59

zksync-web-landing

zkSync.io landing page
CSS
20
star
60

era-zkevm_tester

Adapter between zk_evm and era-compiler-tester
Rust
19
star
61

era-compiler-llvm-context

Shared front-end code of the ZKsync compilers
Rust
19
star
62

z-prize-msm-gpu

Submission for https://www.zprize.io/prizes/accelerating-msm-operations-on-gpu-fpga
Cuda
19
star
63

era-compiler-tests

Collection of tests for ZKsync compilers
Solidity
17
star
64

era-compiler-tester

Integration testing framework for ZKsync compilers
Rust
17
star
65

z-prize-msm-gpu-combined

Combined solution from Matter Labs and Yrrid based on their respective submissions for the Z-Prize category Accelerating MSM Operations on GPU/FPGA
Cuda
15
star
66

eravm-spec

Coq
15
star
67

zksync-crypto

Cryptography libraries for ZKsync
Rust
14
star
68

teepot

Key Value store in a TEE with Remote Attestation for Authentication
Rust
13
star
69

era-compiler-llvm-builder

ZKsync LLVM framework builder
Rust
12
star
70

compiler-llvm

The zkEVM fork of the LLVM framework
12
star
71

zksync-packages-info

Information about the different packages and SDKs by MatterLabs to interact with zkSync Era
Vue
12
star
72

.github

zkSync Frontend Team workflow configuration
12
star
73

era-solidity

ZKsync fork of the original Solidity compiler
C++
12
star
74

era-hardhat-with-plugins

A zkSync Hardhat project configured with multiple plugins to improve the developer experience
TypeScript
11
star
75

era-revm

revm (Rust Ethereum VM) translation for Era / zkEVM
Rust
11
star
76

zksync-frontend-templates

Frontend Templates for ZKsync: vue, react, next, wagmi
TypeScript
10
star
77

ETHLisbon-2022-hackathon

Information about MatterLabs bounty program for ETH Lisbon 2022 hackathon
TypeScript
10
star
78

era-zkEVM-assembly

The zkEVM assembly tools
Rust
10
star
79

aa-signature-checker

TypeScript
9
star
80

era-zk_evm_abstractions

Rust
9
star
81

zksync-v2-issues

Report issues encountered when using the zkSync 2.0 testnet.
9
star
82

vault-auth-tee

Hashicorp Vault plugin for authenticating Trusted Execution Environments (TEE) like SGX enclaves
Go
9
star
83

proof_system_info_v1.0

Information about proof system used in zkSync v1.0
8
star
84

zksync-hardhat-ft-template

Template for a fungible token project on zkSync Era
TypeScript
8
star
85

vise

Tools to define and export metrics in Rust libraries and apps
Rust
8
star
86

l2-intro-ethdenver

Introduction to layer 2 protocols and smart contract examples on zkSync for ETH Denver
Vue
8
star
87

nixsgx

Reproducible Nix packages for TEEs
Nix
8
star
88

eip1962_specs

Specification documents for EIP1962
7
star
89

compiler-infra

Docker images with build tools for compiler repos.
Dockerfile
7
star
90

era-compiler-common

Shared constants of the ZKSync compilers
Rust
7
star
91

demo-circuit

Rust
7
star
92

zkcli-block-explorer

zkSync Block Explorer module for zkcli
TypeScript
7
star
93

zksync-hardhat-vyper-template

[DEPRECATED] Template project for zksync-cli. Includes a Vyper smart contract, tests and script to deploy to zkSync Era
TypeScript
7
star
94

compiler-tests

The compiler tests collection
Solidity
6
star
95

ansible-en-role

Ansible role for zkSync Era External Node
Jinja
6
star
96

zksync-dapp-forced-exit

CSS
6
star
97

simple-oracle-benchmarking

Deploy a simplified oracle, track gas usage.
TypeScript
6
star
98

zksync-crypto-gpu

GPU-acceselerated cryptography libraries for ZKsync
Rust
6
star
99

zksync-docs

Developer documentation site for zkSync community.
Vue
5
star
100

hyperchain-da

Common clients and contracts for DA solutions for zkSync hyperchains.
Rust
5
star