Giter Club home page Giter Club logo

halo2-lib's Introduction

halo2-lib

⚠️ This branch contains un-audited contributions from the community. Community contributions in this branch have been reviewed by maintainers of this repository, but they have not undergone official audit. To use the latest audited version make sure to use the correct commit. The tagged versions that have undergone official audit and are ready for production use can be found in the releases.

This repository aims to provide basic primitives for writing zero-knowledge proof circuits using the Halo 2 proving stack. To discuss or collaborate, join our community on Telegram.

Getting Started

For a brief introduction to zero-knowledge proofs (ZK), see this doc.

Halo 2 is written in Rust, so you need to install Rust to use this library:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Clone this repo and start off in the halo2-lib directory.

git clone https://github.com/axiom-crypto/halo2-lib.git
cd halo2-lib

Projects built with halo2-lib

halo2-base

This crate provides an additional API for writing circuits in Halo 2 using our simple vertical gate. It also provides basic functions built using this API. The provided methods can be found in GateInstructions and RangeInstructions. The latter are operations that require using a lookup table for range checks.

  • Read the Rust docs for this crate.
  • To get started with Halo 2 and to learn how to build using the halo2-base API, see the Getting Started guide.

To run some basic tests, run the following command:

cargo test -- --nocapture test_gates
cargo test -- --nocapture test_range

(Rust tests by default do not display stdout, so we use --nocapture to enable streaming stdout.) These tests use the MockProver to check circuits are properly constrained, however it does not mimic a true production proving setup.

For benchmarks of native field multiplication and inner product where a production proving setup is run, run the following command:

cargo bench --bench mul
cargo bench --bench inner_product

These benchmarks use the criterion crate to run create_proof 10 times for statistical analysis. Note the benchmark circuits perform more than a one multiplication / inner product per circuit.

halo2-ecc

This crate uses halo2-base to provide a library of elliptic curve cryptographic primitives. In particular, we support elliptic curves over base fields that are larger than the scalar field used in the proving system (e.g., F_r for bn254 when using Halo 2 with a KZG backend).

Features

We recommend ignoring this section and using the default features if you are new to Rust. The default features are: "jemallocator", "halo2-axiom", "display". You can turn off "display" for a very small performance increase, where certain statistics about the circuit are not computed and printed.

Exactly one of "halo2-axiom" or "halo2-pse" feature should be turned on at all times.

  • The "halo2-axiom" feature uses our halo2_proofs which is a fork of the PSE one which we have slightly optimized for proving speed.
  • The "halo2-pse" feature uses the Privacy Scaling Explorations halo2_proofs which is the most stable and has the most reviewers.

We guarantee that the proofs generated by the two forks are identical.

Memory allocator

The "jemallocator" feature uses the jemallocator crate for memory allocation. You can turn it off to use the system allocator. Or use feature "mimalloc" to use the mimalloc crate. We have found the performance of these allocators heavily depends on what machine you are running on.

Modules

  • bigint: Provides support for optimized big integer arithmetic in ZK.
  • fields: Provides common functions for prime field arithmetic, optimized for prime fields that are larger than the scalar field used in the proving system.
    • fp2: Field operations over certain quadratic extension fields.
    • fp12: Field operations over certain degree 12 extension fields (designed with BN254 and BLS12-381 in mind).
  • ecc: Library of elliptic curve cryptographic primitives, currently for short Weierstrass curves over base fields compatible with fields module (in particular field extension are allowed).
    • Elliptic curve addition and doubling.
    • Scalar multiplication and multiscalar multiplication (MSM, multiexp). Implementations are ZK-optimized, using windowed methods and Pippenger's algorithm when appropriate.
    • ECDSA signature verification.
  • secp256k1: Specialization of the ecc module for the secp256k1 curve.
    • test_secp256k1_ecdsa and bench_secp256k1_ecdsa show how to implement ECDSA signature verification for secp256k1. (More details below.)
  • bn254: Specialization of the ecc module for the BN254 curve.
    • final_exp and pairing modules together implement the optimal Ate pairing for BN254 in ZK. The implementation has been optimized for the specifics of BN curves, but can be easily adapted to BLS curves (coming soon!).

Tests with MockProver

Do not run cargo test without any filters. Some of the tests are actually benchmarks, and will take a long time to run.

Setup

All tests should be run in the halo2-lib/halo2-ecc directory. Some tests read files from specific directories, so they will not work if you are in the halo2-lib root directory.

For benchmarks below, you can symlink a params folder within halo2-ecc directory with previously generated universal trusted setup files. Otherwise, the benchmarks will generate a new random setup and save them in the params directory. Warning: These trusted setups are generated using a known random seed, so they are not secure. They should NOT be used in production. For more a production suitable trusted setup, see KZG Trusted Setup.

Tests can be run in the same way as in the previous section. The available commands are:

cargo test -- --nocapture test_fp
cargo test -- --nocapture test_fp12
cargo test -- --nocapture test_ecc
cargo test -- --nocapture test_secp256k1_ecdsa
cargo test -- --nocapture test_ec_add # for BN254
cargo test -- --nocapture test_fixed_base_msm # for BN254
cargo test -- --nocapture test_msm # for BN254
cargo test -- --nocapture test_pairing # for BN254

Configurable Circuits

A special features of circuits written using halo2-base is that any such circuit can be configured to have a different number of rows vs. columns, while keeping the total number of cells roughly the same. Different configurations make sense for different circumstances. For example, more rows vs. columns always leads to a cheaper gas cost for on-chain verification, but often at the cost of slower proving speed. For a rough mental model, see Cost Modeling.

In some of the tests above, the circuit configuration is read from a file. You can change the configuration by changing the numbers in the file. If some numbers are too small, the test will panic because there are not enough cells to construct the circuit. If you put numbers that are too large, the test will display suggestions for what the optimal numbers should be. In a future version we will have the circuits auto-configure themselves.

The benchmark config files below also give a list of possible configurations you can put in a test config files.

The test config file locations are (relative to halo2-ecc directory):

Test Config File
test_secp256k1_ecdsa src/secp256k1/configs/ecdsa_circuit.config
test_ec_add src/bn254/configs/ec_add_circuit.config
test_fixed_base_msm src/bn254/configs/fixed_msm_circuit.config
test_msm src/bn254/configs/msm_circuit.config
test_pairing src/bn254/configs/pairing_circuit.config

Benchmarks

We have tests that are actually benchmarks using the production Halo2 prover. As mentioned above, there are different configurations for each circuit that lead to very different proving times. The following benchmarks will take a list of possible configurations and benchmark each one. The results are saved in a file in the results directory. We currently supply the configuration lists, which should provide optimal configurations for a given circuit degree k (however you can check versus the stdout suggestions to see if they really are optimal!).

We run the benchmarks in --release mode for maximum speed.

Commands

The available benchmark commands are:

cargo test --release -- --nocapture bench_secp256k1_ecdsa
cargo test --release -- --nocapture bench_ec_add
cargo test --release -- --nocapture bench_fixed_base_msm
cargo test --release -- --nocapture bench_msm
cargo test --release -- --nocapture bench_pairing

The locations of the config and result files (relative to halo2-ecc directory) are:

Benchmark Config File Results File
bench_secp256k1_ecdsa src/secp256k1/configs/bench_ecdsa.config src/secp256k1/results/ecdsa_bench.csv
bench_ec_add src/bn254/configs/bench_ec_add.config src/bn254/results/ec_add_bench.csv
bench_fixed_base_msm src/bn254/configs/bench_fixed_msm.config src/bn254/results/fixed_msm_bench.csv
bench_msm src/bn254/configs/bench_msm.config src/bn254/results/msm_bench.csv
bench_pairing src/bn254/configs/bench_pairing.config src/bn254/results/pairing_bench.csv

To speed up benching time you can remove certain lines from the .config file for configurations you don't want to bench.

Criterion Benchmarks

To run more accurate benchmarks using the criterion crate, you can run the following commands:

cargo bench --bench msm
cargo bench --bench fixed_base_msm
cargo bench --bench fp_mul

This run the same proof generation over 10 runs and collect the average. Each circuit has a fixed configuration chosen for optimal speed. These benchmarks are mostly for use in performance optimization.

Secp256k1 ECDSA

We provide benchmarks for ECDSA signature verification for the Secp256k1 curve on several different machines. All machines only use CPUs.

On AWS EC2 instances r6a.8xl (AMD, x86) and r6g.8xl (Graviton, arm64), both with 32 CPU cores, 256 GB RAM, the bench is run using

cargo test --release --no-default-features --features "halo2-axiom, jemallocator" -- --nocapture bench_secp256k1_ecdsa

To optimize memory allocation to prioritize CPU utilization, we tune jemallocator with

export JEMALLOC_SYS_WITH_MALLOC_CONF="background_thread:true,metadata_thp:always,dirty_decay_ms:100000,muzzy_decay_ms:100000,narenas:1,abort_conf:true"

(in practice this did not make a big difference).

On a M2 Max Macbook Pro (12 CPU cores, 96 GB RAM) we ran the bench using

cargo test --release --no-default-features --features "halo2-axiom, mimalloc" -- --nocapture bench_secp256k1_ecdsa

(the performance of "mimalloc" vs "jemallocator" was similar).

The other columns provide information about the PLONKish arithmetization.

k Num Advice Num Lookup Advice Num Fixed Proof Time (M2 Max) Proof Time (r6a.8xl) Proof Time (r6g.8xl)
11 291 53 4 3.5s 7.3s 7.2s
12 139 24 2 2.6s 3.3s 5.3s
13 68 12 1 2.2s 2.6s 4.7s
14 34 6 1 2.1s 2.4s 4.5s
15 17 3 1 1.98s 2.28s 4.5s
16 8 2 1 2.3s 2.5s 5.2s
17 4 1 1 2.7s 2.9s 6s
18 2 1 1 4.4s 4.7s 9.5s
19 1 1 1 7.6s 7.6s 16s

The r6a has a higher clock speed than the r6g.

BN254 Pairing

We provide benchmarks of the optimal Ate pairing for BN254 on several different machines. All machines only use CPUs.

On AWS EC2 instances r6a.8xl (AMD, x86) and r6g.8xl (Graviton, arm64), both with 32 CPU cores, 256 GB RAM, the bench is run using

cargo test --release --no-default-features --features "halo2-axiom, jemallocator" -- --nocapture bench_pairing

To optimize memory allocation to prioritize CPU utilization, we tune jemallocator with

export JEMALLOC_SYS_WITH_MALLOC_CONF="background_thread:true,metadata_thp:always,dirty_decay_ms:100000,muzzy_decay_ms:100000,narenas:1,abort_conf:true"

(in practice this did not make a big difference).

On a M2 Max Macbook Pro (12 CPU cores, 96 GB RAM) we ran the bench using

cargo test --release --no-default-features --features "halo2-axiom, mimalloc" -- --nocapture bench_pairing

(the performance of "mimalloc" vs "jemallocator" was similar).

The other columns provide information about the PLONKish arithmetization.

k Num Advice Num Lookup Advice Num Fixed Proof Time (M2 Max) Proof Time (r6a.8xl) Proof Time (r6g.8xl)
14 211 27 1 11.8s 16.9s 24.8s
15 105 14 1 10.4s 12.7s 23.6s
16 50 6 1 9.5s 10.96s 21.6s
17 25 3 1 9.7s 11.2s 22.7s
18 13 2 1 11.9s 13.5s 27.3s
19 6 1 1 14.8s 15.3s 30.6s
20 3 1 1 23.7s 23.8s 48.1s
21 2 1 1 40.3s 40.8s 82.5s
22 1 1 1 69.1s 66.9s 135s

The r6a has a higher clock speed than the r6g. We hypothesize that the Apple Silicon integrated memory leads to the faster performance on the M2 Max.

BN254 MSM

We provide benchmarks of multi-scalar multiplication (MSM, multi-exp) with a batch size of 100 for BN254.

On a M2 Max Macbook Pro (12 CPU cores, 96 GB RAM) we ran the bench using

cargo test --release --no-default-features --features "halo2-axiom, mimalloc" -- --nocapture bench_msm
k Num Advice Num Lookup Advice Num Fixed Proof Time (M2 Max)
17 84 11 1 27.8s
18 42 6 1 29.95s
19 20 3 1 32.6s
20 11 2 1 41.3s
21 6 1 1 51.9s

halo2-lib's People

Contributors

0xisk avatar adventureseeker987 avatar antonio95 avatar divide-by-0 avatar enricobottazzi avatar ethan-000 avatar flyingnobita avatar goofylfg avatar haoyuathz avatar jonathanpwang avatar kevaundray avatar lispc avatar mattsse avatar mmagician avatar monkeyking-1 avatar nyunyunyunyu avatar odyssey2077 avatar patstiles avatar shuklaayush avatar xiaolou86 avatar yi-sun avatar zemse avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

halo2-lib's Issues

Dynamic lookup table does not contain fixed/selector columns

The dynamic lookup table functionality provided in /halo2-base/src/virtual_region/lookups/basic.rs -

pub fn new<P: Phase, F: Field>(
meta: &mut ConstraintSystem<F>,
phase: impl Fn() -> P,
num_lu_sets: usize,
) -> Self {
let mut make_columns = || {
[(); KEY_COL].map(|_| {
let advice = meta.advice_column_in(phase());
meta.enable_equality(advice);
advice
})
};
let table = make_columns();
let to_lookup: Vec<_> = (0..num_lu_sets).map(|_| make_columns()).collect();
for to_lookup in &to_lookup {
meta.lookup_any("dynamic lookup table", |meta| {
let table = table.map(|c| meta.query_advice(c, Rotation::cur()));
let to_lu = to_lookup.map(|c| meta.query_advice(c, Rotation::cur()));
to_lu.into_iter().zip(table).collect()
});
}
Self { table, to_lookup }
}

does not include any fixed/selector columns for the table columns. So all table columns are advice columns. This can easily lead to bugs when all rows of these advice columns are not constrained. The unconstrained rows can have any input value by the attacker, allowing them to include a false lookup.

This bug was originally seen in the Scroll/PSE zkevm circuits - privacy-scaling-explorations/zkevm-circuits#866

Adding a fixed/selector column to the lookup table allows lookups to succeed only for rows where the selector is 1. This selector should be enabled only on rows where the lookup table's advice values are set.

Mock prover `assert_satisfied_par` always fail "cell not assigned"

If a circuit builder has at least one relation between cells (e.g. addition, etc), the MockProver::assert_satisfied_par() fails with the errors bellow. The assert_satisfied() method works without an issue.

Total 1 fixed cells
Total range check advice cells to lookup per phase: [0, 0, 0]
error: cell not assigned

  Cell layout in region 'BaseCircuitBuilder generated circuit':
    | Offset | A0 |
    +--------+----+
    |    1   |  X | <--{ X marks the spot! 🦜
    |    2   | x1 |
    |    3   | x2 |
    |    4   | x3 |

  Gate '1 column a + b * c = out' (applied at offset 1) queries these cells.

error: cell not assigned

  Cell layout in region 'BaseCircuitBuilder generated circuit':
    | Offset | A0 |
    +--------+----+
    |    1   | x0 |
    |    2   |  X | <--{ X marks the spot! 🦜
    |    3   | x2 |
    |    4   | x3 |

  Gate '1 column a + b * c = out' (applied at offset 1) queries these cells.

thread 'sync_step_circuit::tests::test_step_circuit' panicked at /Users/timofey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/halo2-axiom-0.4.2/src/dev.rs:1571:13:
circuit was not satisfied
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
test sync_step_circuit::tests::test_step_circuit ... FAILED

Check wasm support and enable `no-std`

Currently circuit are not written with no-std support in mind. Testing needs to be done to see what needs to be fixed to support it. Hopefully changes needed are minimal.

Use line function for ec addition enforcement

Instead of mimicking affine addition formula here we can just enforce the line function from p0, p1 to -res where p0 + p1 = res. So that it should become 2MUL, 4ADD rather than 3MUL, 6ADD. Pseudo enforcement:

    let p0 = G1Affine::random(OsRng);
    let p1 = G1Affine::random(OsRng);
    let res = (p0 + p1).to_affine();

    let (x0, y0) = p0.into_coordinates();
    let (x1, y1) = p1.into_coordinates();
    let (xres, yres) = res.into_coordinates();

    let t_0 = (yres + y0) * (x0 - x1);
    let t_1 = (xres - x0) * (y1 - y0);
    assert!(t_0 == t_1);

halo2-lib build failure

I am trying to build halo2-lib by cloning the community-edition from this repository and running cargo build. I am running into an error which is shown below.

vikra@MSI MINGW64 /C/Users/vikra/OneDrive/Desktop/halo2-lib (community-edition)
$ cargo build --release
info: syncing channel updates for 'nightly-2024-02-08-x86_64-pc-windows-msvc'
info: latest update on 2024-02-08, rust version 1.78.0-nightly (8ace7ea1f 2024-02-07)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
info: installing component 'rust-std'
info: installing component 'rustc'
info: installing component 'rustfmt'
    Updating crates.io index
    Updating git repository `https://github.com/privacy-scaling-explorations/halo2.git`
    Updating git repository `https://github.com/axiom-crypto/pse-poseidon.git`
    Updating git repository `https://github.com/axiom-crypto/snark-verifier.git`
    Updating git repository `https://github.com/axiom-crypto/halo2-lib.git`
  Downloaded maybe-rayon v0.1.1
  Downloaded crossbeam v0.8.4
  Downloaded serde_derive v1.0.204
  Downloaded test-case-macros v3.3.1
  Downloaded strum v0.26.3
  Downloaded type-map v0.5.0
  Downloaded test-case-core v3.3.1
  Downloaded syn v2.0.70
  Downloaded test-case v3.3.1
  Downloaded serde_arrays v0.1.0
  Downloaded pairing v0.23.0
  Downloaded getset v0.1.2
  Downloaded halo2-axiom v0.4.4
  Downloaded poseidon-primitives v0.1.1
  Downloaded pasta_curves v0.5.1
  Downloaded halo2curves-axiom v0.5.3
  Downloaded 16 crates (4.4 MB) in 4.08s (largest was `halo2curves-axiom` at 3.3 MB)
   Compiling proc-macro2 v1.0.86
   Compiling unicode-ident v1.0.12
   Compiling cfg-if v1.0.0
   Compiling version_check v0.9.4
   Compiling serde v1.0.204
   Compiling syn v1.0.109
   Compiling subtle v2.6.1
   Compiling typenum v1.17.0
   Compiling zeroize v1.8.1
   Compiling const-oid v0.9.6
   Compiling ppv-lite86 v0.2.17
   Compiling radium v0.7.0
   Compiling arrayvec v0.7.4
   Compiling tap v1.0.1
   Compiling equivalent v1.0.1
   Compiling hashbrown v0.14.5
   Compiling funty v2.0.0
   Compiling crossbeam-utils v0.8.20
   Compiling winnow v0.5.40
   Compiling static_assertions v1.1.0
   Compiling getrandom v0.2.15
   Compiling toml_datetime v0.6.6
   Compiling autocfg v1.3.0
   Compiling rand_core v0.6.4
   Compiling wyz v0.5.1
   Compiling spin v0.9.8
   Compiling cpufeatures v0.2.12
   Compiling crunchy v0.2.2
   Compiling windows_x86_64_msvc v0.48.5
   Compiling lazy_static v1.5.0
   Compiling rayon-core v1.12.1
   Compiling once_cell v1.19.0
   Compiling byte-slice-cast v1.2.2
   Compiling generic-array v0.14.7
   Compiling either v1.13.0
   Compiling rand_chacha v0.3.1
   Compiling rustc-hex v2.1.0
   Compiling thiserror v1.0.61
   Compiling proc-macro-error-attr v1.0.4
   Compiling paste v1.0.15
   Compiling arrayref v0.3.7
   Compiling byteorder v1.5.0
   Compiling keccak v0.1.5
   Compiling constant_time_eq v0.3.0
   Compiling rand v0.8.5
   Compiling indexmap v2.2.6
   Compiling num-traits v0.2.19
   Compiling serde_json v1.0.120
   Compiling proc-macro-error v1.0.4
   Compiling blake2b_simd v1.0.2
   Compiling windows-targets v0.48.5
   Compiling itoa v1.0.11
   Compiling ryu v1.0.18
   Compiling halo2curves-axiom v0.5.3
   Compiling tiny-keccak v2.0.2
   Compiling windows-sys v0.48.0
   Compiling tracing-core v0.1.32
   Compiling der v0.7.9
   Compiling windows_x86_64_msvc v0.52.6
   Compiling pin-project-lite v0.2.14
   Compiling bitvec v1.0.1
   Compiling rustc-hash v1.1.0
   Compiling itertools v0.11.0
   Compiling rand_xorshift v0.3.0
   Compiling base16ct v0.2.0
   Compiling memchr v2.7.4
   Compiling quote v1.0.36
   Compiling rustversion v1.0.17
   Compiling crossbeam-epoch v0.9.18
   Compiling crossbeam-queue v0.3.11
   Compiling crossbeam-channel v0.5.13
   Compiling syn v2.0.70
   Compiling toml_edit v0.21.1
   Compiling fixed-hash v0.8.0
   Compiling colored v2.1.0
   Compiling log v0.4.22
   Compiling crossbeam-deque v0.8.5
   Compiling regex-syntax v0.8.4
   Compiling windows-targets v0.52.6
   Compiling heck v0.5.0
   Compiling num-integer v0.1.46
   Compiling crossbeam v0.8.4
   Compiling aho-corasick v1.1.3
   Compiling ark-std v0.3.0
   Compiling bytes v1.6.0
   Compiling block-buffer v0.10.4
   Compiling crypto-common v0.1.6
   Compiling num-bigint v0.4.6
   Compiling crypto-bigint v0.5.5
   Compiling windows-sys v0.52.0
   Compiling fastrand v2.1.0
   Compiling chrono v0.4.38
   Compiling unicode-xid v0.2.4
   Compiling digest v0.10.7
   Compiling sec1 v0.7.3
   Compiling rayon v1.10.0
   Compiling spki v0.7.3
   Compiling type-map v0.5.0
   Compiling sha2 v0.10.8
   Compiling sha3 v0.10.8
   Compiling hmac v0.12.1
   Compiling signature v2.2.0
   Compiling tempfile v3.10.1
   Compiling array-init v2.1.0
   Compiling rfc6979 v0.4.0
   Compiling proc-macro-crate v3.1.0
   Compiling regex-automata v0.4.7
   Compiling test-case-core v3.3.1
   Compiling ff v0.13.0
   Compiling group v0.13.0
   Compiling pasta_curves v0.5.1
   Compiling pairing v0.23.0
   Compiling elliptic-curve v0.13.8
   Compiling serde_derive v1.0.204
   Compiling thiserror-impl v1.0.61
   Compiling derive_more v0.99.18
   Compiling tracing-attributes v0.1.27
   Compiling strum_macros v0.26.4
   Compiling num_enum_derive v0.7.2
   Compiling auto_impl v1.2.0
   Compiling test-case-macros v3.3.1
   Compiling ecdsa v0.16.9
   Compiling test-case v3.3.1
   Compiling k256 v0.13.3
   Compiling maybe-rayon v0.1.1
   Compiling num_enum v0.7.2
   Compiling tracing v0.1.40
   Compiling poseidon-primitives v0.1.1
   Compiling regex v1.10.5
   Compiling strum v0.26.3
   Compiling impl-trait-for-tuples v0.2.2
   Compiling parity-scale-codec-derive v3.6.12
   Compiling rlp-derive v0.1.0
   Compiling scale-info-derive v2.11.3
   Compiling getset v0.1.2
   Compiling open-fastrlp-derive v0.1.1
error[E0658]: `#[diagnostic]` attribute name space is experimental
   --> C:\Users\vikra\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde-1.0.204\src\de\mod.rs:537:5
    |
537 |     diagnostic::on_unimplemented(
    |     ^^^^^^^^^^
    |
    = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information
    = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable
    = note: this compiler was built on 2024-02-07; consider upgrading it if it is out of date

error[E0658]: `#[diagnostic]` attribute name space is experimental
   --> C:\Users\vikra\.cargo\registry\src\index.crates.io-6f17d22bba15001f\serde-1.0.204\src\ser\mod.rs:220:5
    |
220 |     diagnostic::on_unimplemented(
    |     ^^^^^^^^^^
    |
    = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information
    = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable
    = note: this compiler was built on 2024-02-07; consider upgrading it if it is out of date

For more information about this error, try `rustc --explain E0658`.
The following warnings were emitted during compilation:

warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag
warning: [email protected]: cargo:rustc-check-cfg requires -Zcheck-cfg flag

error: could not compile `serde` (lib) due to 2 previous errors
warning: build failed, waiting for other jobs to finish...

Please let me know what should I do to make it build.

Can I use `div_mod` on an arbitrary field element?

In your tests the element that I'm dividing is known to have a fixed number of bits.

However, I would like to apply this function to an arbitrary field element - the problem is that the number of bits can be up to F::NUM_BITS, so I end up with something like:

let small_mod: usize = 1 << 16;
let (_, r) = range_gate.div_mod(ctx, arbitrary_field_element, small_mod, F::NUM_BITS as usize);

which doesn't actually work (aside from not being efficient, if it did) as I get an index out of bounds error. By increasing the param a_num_bits to F::NUM_BITS + 2 circumvents this error but then it panics with some low level assert failure.

Perhaps the specific errors aren't very relevant, because I suspect that using div_mod for this purpose is simply not the best approach in the first place. If you're wondering why I care about arbitrary elements, it's because these elements comes from a hash output, and at a later stage I want to treat them as indices to an array.

Let me know if you have any better ideas for modular reduction of F to "usize" and constraining that the resulting F is indeed less than the modulus - many thanks!

Avoid self-referential struct patterns

It was a mistake to have FpChip contain RangeChip as a reference. This makes it near-impossible to create a struct that stores both FpChip and RangeChip at the same time (without using Rust crates like ouroboros or rental).

We should have either just had FpChip own RangeChip, or have it own Arc<RangeChip> (some minor performance impact).

Set up more advanced fuzzing

Current tests all still use our provided witness generation, so they will not fully test the air tightness of circuit constraints. We need to set up tests, either with MockProver or actual keygen and create_proof, where user can submit witness values to test against our circuits' constraints.

`halo2-ecc` lacks documentation

While halo2-base functions now all have documentation, many halo2-ecc functions still do not. The documentation should clearly explain what the logic behind the circuits is and what the input/output assumptions are.

Faster pairings

Introduction

As discussed with @yi-sun during EthCC, here is my internal Taiko note on pairing acceleration.

cc @ggkitsas who has been looking into this, @Brechtpd.

cc @yelhousni who had the original idea of using RS03 for circuits (in Gnark) and @nikkolasg who was looking into this very recently.

Extra review note, the current final exponentiation in Axiom is using

in https://github.com/axiom-crypto/halo2-lib/blob/a74c594/halo2-ecc/src/bn254/final_exp.rs#L303-L370

But there are 2 faster developments:

Impl: https://github.com/mratsim/constantine/blob/47b4f48/constantine/math/pairings/pairings_bn.nim#L112-L162


Circuit - Fast Pairings

Pairing (ECPAIRING - EIP197) is likely the slowest operation in the EVM.

However if we want to allow L3s to work on Taiko, it needs to be fast enough.

This document gives an overview of the state-of-the-art to significantly reduce pairings constraint requirement.

2 optimizations are available to significantly reduce pairings cost.

Current EIP197 PR from Scroll (pending merge as of july 2023):

Scroll forks Halo2-ecc from Axiom for the “PairingChip”

https://github.com/axiom-crypto/halo2-lib/tree/community-edition/halo2-ecc

I. Multi-pairings

note: a version of multi-pairings has been implemented in Axiom’s codebase #65

Overview

Pairings are computed in 2 expensive main steps:

  • Miller Loop
  • Final exponentiation

Their cost is similar, if pairings cost is 100, each costs 50.

However, for n pairings, we can accumulate n Miller Loop and do a single final exponentiation, reducing the asymptotic cost by 2x. It is worth it even with only 2 pairings, as needed for BLS signatures or KZG commitments or 3 pairings as needed for Groth16.

Implementation

There are 2 ways to implement multi-pairings, they are detailed in

https://github.com/mratsim/constantine/blob/47b4f48dfb08c9ab9188c5308d4185156b8cb0bd/constantine/math/pairings/multi_pairings.md

Savings

In this PR, gas cost has been reduced from 1.4M gas to 872k gas

metacraft-labs/DendrETH@6b3c652#diff-f9d3c1274a560fb7a19b949feb0601823fa0d96eb8fb7d7f8603ad00b97230d7

II. Compressed pairings

Overview

Pairings are done on a subgroup of the Fp12 extension field (k=12 is the embedding degree of BN and BLS12 curves) of order r that is cyclotomic.

In particular they respect the cyclotomic polynomial equation ϕ₁₂(x) = x⁴-x²+1

This allows compressed representations for cheaper arithmetic, in particular squaring.

Some representations do not allow multiplication (only squaring) and some representations do not allow decompression.

Implementation

Pairings in circuit can be accelerated using number theoretic properties of cyclotomic fields (https://en.wikipedia.org/wiki/Cyclotomic_field)

In particular the final exponentiation can be done in a compressed representation using either:

  • Torus-based compression (1/2 in Gnark, 1/3 as a research direction proposed by Karabina)
  • Trace-of-Frobenius compression (XTR) (1/3 in Miracl)
  • Lucas compression (1/2 in Miracl)

Operations

Operations using a compressed representation can save 1/3, 1/2 or 2/3 of space and also a significant amount field operations, hence constraints.

For regular computation on a CPU, compression is problematic due to either the absence of decompression or decompression requiring a field inversion, a very expensive operations (80x to 120x more expensive than field multiplication).

In constraint system however, it’s free as we can provide the inverse as a witness and the cost becomes the same as proving a multiplication.

image

Presentations:

Implementation

See also all “emulated pairing” PRs like:

Other impl in regular arithmetic (not a constraint system)

Research papers:

Gnark implements “T2” arithmetic (Torus with 1/2 compression) according to

A paper with a nice high-level overview of compression techniques is Karabina’s:

image

TODOs (research)

Evaluate

backlog: cargo check fails for latest nightly toolchain

i change the toolchain to nightly-2023-04-24, and run cargo check, it reports error like

error[E0599]: no associated item named `NUM_BITS` found for associated type `<FpChip as FieldChip<F>>::FieldType` in the current scope
   --> halo2-ecc/src/fields/fp12.rs:108:58
    |
108 |     const PRIME_FIELD_NUM_BITS: u32 = FpChip::FieldType::NUM_BITS;
    |                                                          ^^^^^^^^ associated item not found in `<FpChip as FieldChip<F>>::FieldType`
    |
    = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
    |
1   + use ff::PrimeField;
    |

branch i use: release-0.3.0
(it works well for the default nightly-2022-10-28, so i just mark this as a backlog)

due to this commit: rust-lang/rust@8996ea9

`PoseidonChip` compatibility

Do you know whether the PoseidonChip is meant to be spec compatible with the native one? Perhaps I'm doing something wrong, but the following fails for me (Scroll's impl claims to be "in line with the reference and the test vectors"):

poseidon-native = { git = "https://github.com/scroll-tech/poseidon/", package = "poseidon"}
poseidon = { git = "https://github.com/axiom-crypto/halo2-lib", branch = "community-edition" }
let gate = GateChip::<F>::default();

let mut sponge = PoseidonChip::<F, T, RATE>::new(ctx, R_F, R_P).unwrap();
let assigned = sponge.squeeze(ctx, &gate).unwrap();

let mut native_sponge = poseidon_native::Poseidon::<F, T, RATE>::new(R_F, R_P);
let native = native_sponge.squeeze();

assert_eq!(assigned.value(), &native); // this fails

I know that you guys got inspiration for the PoseidonChip from the scroll sponge, so apologies if this is completely the wrong place for this issue, but at least I can run meaningful tests between the native & in-circuit Poseidon sponge using your repo 🙏🏼 (as the Scroll halo2-snark-aggregator is a little out of date).

Also @zhenfeizhang @noel2004

halo2-scaffold has compile errors when using the community-edition branch of halo2-lib

I updated my cargo.toml file in halo2-scaffold to use the community-edition of halo2-lib, and when I compiled I got the following error:

error[E0277]: the trait bound `[u64; 4]: From<F>` is not satisfied --> src/scaffold/mod.rs:256:34 | 256 | fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error> { | ^^^^^^^^^^^^ the trait `From<F>` is not implemented for `[u64; 4]` | = note: required for `F` to implement `Into<[u64; 4]>` = note: required for `F` to implement `halo2_base::utils::ScalarField` note: required by a bound in `snark_verifier_sdk::halo2::aggregation::RangeWithInstanceConfig` --> /home/raju/.cargo/git/checkouts/snark-verifier-d84de59606f606ae/b162586/snark-verifier-sdk/src/halo2/aggregation.rs:156:39

I get the same error re: type Config = RangeWithInstanceConfig<F>; and fn synthesize(&self, config: Self::Config, layouter: impl Layouter<F>) -> Result<(), Error> {

MSM when output is identity

ec_sub_unequal(chip, ctx, &sum, &rand_sum, true)

Right now our MSM can handle when input points contain identity, but there is undefined behavior (or panic) if the true value of the MSM is the identity. Depending on the use case we may want an extra select at the end to return (0,0) when that is the expected answer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.