Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: BLS12-381 pairing #175

Open
wants to merge 24 commits into
base: community-edition
Choose a base branch
from

Conversation

nulltea
Copy link

@nulltea nulltea commented Oct 2, 2023

Add pairing (miller_loop + final_exp) and pairing_check (multi_miller_loop + final_exp) for BLS12-381. Relies on axiom-crypto/halo2curves#8.

This implementation is over affine points , inspired by BN254 pairing in this repo. This variant performs better than https://github.com/DelphinusLab/halo2ecc-s (over projective points).

Originally implemented in dev/bls12_381.

Notable changes

  1. Constant const XI_0: i64 = 1 value is taken from circom-pairing.
  2. To avoid unnecessary work in-circuit, the first two iterations of the Miller loop are skipped, and the loop itself is slightly resequenced: first doubling step outside the loop, addition step leads the loop if previous_bit (based on BLS-X), Gt squaring and doubling step follows as usual.
  3. Final Gt conjugation is skipped (only) in multi_miller_loop as it appears to make no difference (there). I wasn't able to find evidence, so am happy to be proven wrong!
  4. FieldExtConstructor is implemented for Fp2, and Fp12
  5. Blanket impl of BigPrimeField was replaced with per curve impls to account for bigger size of BLS12-381's Fq.
  6. Import halo2curves = "https://github.com/axiom-crypto/halo2curves" when halo2-pse feature is enabled and use halo2curves::bls12_381 instead one from halo2_proofs::halo2_curves. The reason is that PSE fork of halo2 still uses halo2curves v0.1.0, so patching is not an option.
  7. Some asserts (off/in-circuit) were disabled to allow limb sizes of BLS12-381 in carry_mod.rs (1, 2) and check_carry_mod_to_zero.rs (1, 2).

The last (7) change could be breaking. I could use some help to fix it more cleanly 🙏

Benchmarks

k=19 lookup_bits=18:

Gate Chip | Phase 0: 6621026 advice cells
Total 73 fixed cells
Total range check advice cells to lookup per phase: [864978, 0, 0]

Using optimized cyclotomic_pow_bls_x that exploits structure of cyclotomic_pow for greater constraint efficiency:

Gate Chip | Phase 0: 4960328 advice cells
Total 72 fixed cells
Total range check advice cells to lookup per phase: [619112, 0, 0]

impl super::BigPrimeField for Fr {
#[inline(always)]
fn from_u64_digits(val: &[u64]) -> Self {
let mut raw = [0u64; 4];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be 6

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@jonathanpwang jonathanpwang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initial review just to address the carry_mod and check_carry_mod_to_zero implementations, which need to change for BLS12-381. We should make it fully general for any large field.

This is point #7 in the PR description.

halo2-ecc/Cargo.toml Outdated Show resolved Hide resolved
halo2-ecc/src/bigint/carry_mod.rs Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants