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

WIP: Support bandersnatch group #139

Draft
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

dragan2234
Copy link

@dragan2234 dragan2234 commented Feb 22, 2024

This is being built on top of #87

Base field is taken from bls12-381, scalar field is built following bandersnatch paper https://eprint.iacr.org/2021/1152.pdf and other implementations. All tests are passing for short weistrass form. But we need twisted Edwards form, WIP.

cc @CPerezz just to keep you in the loop

@CPerezz
Copy link
Member

CPerezz commented Feb 25, 2024

Awesome @dragan2234 !! Thanks a lot for the ping.

This is looking good so far. You might need to impl FieldBits and SerdeObject. But aside from that all looking good! :)

@dragan2234
Copy link
Author

dragan2234 commented Feb 26, 2024

Saving script for generating Z (SSVDW_Z) param:

def find_z_sswu(F, A, B):
    R.<xx> = F[]                       # Polynomial ring over F
    g = xx^3 + F(A) * xx + F(B)        # y^2 = g(x) = x^3 + A * x + B
    ctr = F.gen()
    while True:
        for Z_cand in (F(ctr), F(-ctr)):
            # Criterion 1: Z is non-square in F.
            if is_square(Z_cand):
                continue
            # Criterion 2: Z != -1 in F.
            if Z_cand == F(-1):
                continue
            # Criterion 3: g(x) - Z is irreducible over F.
            if not (g - Z_cand).is_irreducible():
                continue
            # Criterion 4: g(B / (Z * A)) is square in F.
            if is_square(g(B / (Z_cand * A))):
                return Z_cand
        ctr += 1
        
F = GF(52435875175126190479447740508185965837690552500527637822603658699938581184513)
A = 52435875175126190479447740508185965837690552500527637822603658699934817984513
B = 52435875175126190479447740508185965837690552500527637822603658621262613184513
Z = find_z_sswu(F,A,B)

print(Z)

Z returns 7, bandersnatch::curve::tests::test_curve still failing

test bandersnatch::curve::tests::test_hash_to_curve behaves strangly, works fine with 7, with 6 fails, with some other random examples works fine

@dragan2234
Copy link
Author

All tests are passing :) .

But I realized this is not exactly what we need, since this curve is generated in Short Weistrass form and we need Twisted Edwards form. Some explanation is in Sectio 6 of this paper: "6 Elliptic curves inside SNARKs" https://eprint.iacr.org/2022/586.pdf

"Later, Zcash
engineers proposed the use of a twisted Edwards curve instead that is more efficient
than the CØCØ Montgomery curve. It was built on top of the BLS12-381 curve
and named Jubjub. In fact, conditional statements are costly in R1CS and one
resorts to a double-and-always-add-like algorithm (as in a side-channel resistant
implementation) instead of the classical double-and-add algorithm to express a
scalar multiplication. Instinctively, it would seem that windowed multiplications
would be expensive in this context but it turns out that constant-time windowed
methods can be achieved efficiently in R1CS using a twisted Edwards curve. The
affine group law on these curves is complete meaning that one can use a lookup
table to select the precomputed points (xi
, yi) or the zero point (x0, y0) = (0, 1)
to add in the algorithm. This is done through polynomials which vanish at the
inputs that are not being selected."

This refers to R1CS but should be similar to plonkish arithmetization if i'm not mistaken?

Also arkworks(besu uses this for verkle) and go-ipa(geth uses this for verkle) both use twisted edwards form.

Found this repo: https://github.com/zkcrypto/jubjub . This implements jubjub in twisted edwards form, so I hope some parts can be reused if it's not too outdated? cc @CPerezz

@CPerezz
Copy link
Member

CPerezz commented Mar 1, 2024

Hey @dragan2234 the main issue here will be that halo2curves is not prepared to support TWEd curves (there aren't any traits for it).

We can try to do some frankestein. But sounds a bit complex.
Specially because Halo2 is quite bound to some of these traits.

In any case, I think we can for now porsue the JubJub way. And see how it plugs in with halo2. And we can re-evaluate later.

@dragan2234
Copy link
Author

@CPerezz Per my understanding halo2 as a proof system only needs bls12-381 traits for proving, here we need bandersnatch points in TE form where computation of point addition and scalar multiplication is done in circuit, which is not related to halo2 traits?

That's if we do these computations in-circuit. If we need precomputations like wNAF and/or GLV that means we need these computation outside-of-circuit too but that's still not related to halo2 if my understanding is correct?

@CPerezz
Copy link
Member

CPerezz commented Mar 1, 2024

@CPerezz Per my understanding halo2 as a proof system only needs bls12-381 traits for proving, here we need bandersnatch points in TE form where computation of point addition and scalar multiplication is done in circuit, which is not related to halo2 traits?

That's if we do these computations in-circuit. If we need precomputations like wNAF and/or GLV that means we need these computation outside-of-circuit too but that's still not related to halo2 if my understanding is correct?

That makes sense. Sounds good!

@dragan2234
Copy link
Author

Made some progress on the TE form of bandersnatch, still looking ugly and not working properly.

Small comment regarding formulas for point addition (doubling etc.):

JubJub has the parameter a = -1 which makes formulas different so we'll need to adapt them too. More info here: https://hyperelliptic.org/EFD/g1p/auto-twisted.html

@CPerezz
Copy link
Member

CPerezz commented Mar 2, 2024

AFAIR if we have a twisted Edwards, we should go (out of circuit) for https://eprint.iacr.org/2008/522 which are complete formulas.

These are the ones I implemented back in the days of BulletProofs in https://github.com/dusk-network/dusk-zerocaf

@dragan2234
Copy link
Author

These are the ones I implemented back in the days of BulletProofs in https://github.com/dusk-network/dusk-zerocaf

Thanks, this helps!

It's a bit confusing that https://github.com/zkcrypto/jubjub/blob/main/src/lib.rs#L127 uses t1 and t2. Also, I think we could simplify this by not implementing AffineNielsPoint and ExtendedNielsPoint, not sure if that's necessary. Your implementation and other implementations like https://github.com/jsign/verkle-crypto/blob/main/src/bandersnatch/points/extended.zig are much simpler.

Will continue the work

@dragan2234
Copy link
Author

Point addition, doubling, subtraction and scalar multiplication are working fine. Implemented for ExtendedPoints trait (extended projective coordinates) and smoke tested against arkworks.

File src/bandersnatch/te_curve.rs is the only relevant since that's where the twisted edwards operations are created. Note that I left some serialization traits from Jubjub, this will probably change for us.

These should be enough for our purposes - testing against in-circuit implementation and building a precomputed table for in-circuit implementation.

As a next step, I thought looking into: https://github.com/zhenfeizhang/halo2-native-ecc and trying to do the same with bandersnatch twisted edwards and getting some conclusions.

cc @CPerezz

@kilic
Copy link
Collaborator

kilic commented May 1, 2024

Can this be implemented on top of #154 before BLS12381 comes? @dragan2234

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.

None yet

3 participants