Skip to content

Switch from BN254 to BLS12-381 #2502

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

Closed
ebfull opened this issue Jul 2, 2017 · 23 comments
Closed

Switch from BN254 to BLS12-381 #2502

ebfull opened this issue Jul 2, 2017 · 23 comments
Labels
M-requires-nu A network upgrade is required to implement this. NU1-sapling Network upgrade: Sapling-specific tasks

Comments

@ebfull
Copy link
Contributor

ebfull commented Jul 2, 2017

Our zk-SNARKs currently rely on BN254, a pairing-friendly Barreto-Naehrig curve construction over a 254-bit base field. After some recent optimizations to the NFS algorithm, our team did an analysis to understand the concrete security level of BN254.

@zooko's conclusion:

Okay, done! We've understood the concrete security level BN_128. Answer: everyone agrees that it is at least 110 bits, and either everyone or almost-everyone agrees that if you counted all of the costs it would be at least 128 bits.

Pairing-friendly curves are inherently more susceptible to advances in crypto research due to their small embedding degrees, so although the BN curve is currently good enough there is wisdom in adopting current academic recommendations wherever possible.

Sapling is a great opportunity to switch to a more secure pairing curve, since our protocol currently doesn't depend on the underlying curve, and we're considering many changes to the protocol which will. Switching later will be irritating, as it will require re-implementing everything again: new embedded curves, new hash functions, etc. We can buy more time by switching now when it's not as painful.

I've designed a new curve construction called BLS12-381 which targets 128-bit security given current recommendations.

Performance of BLS12-381

Currently, Zcash uses the BN254 implementation inside of libsnark, with USE_ASM disabled. I have recently implemented BLS12-381 in Rust.

Here are some preliminary benchmarks run on my i7-3770S:

As you can see, my implementation of BLS12-381 (which doesn't use any unsafe{} code or any hand-optimized assembly) is faster than the implementation of BN254 that we currently use in Zcash.

In fact, due to the small Hamming weight of its parameterization and its more efficient extension field tower, its G2 and pairing performance are on par with libsnark's assembly-optimized code that we don't use. This makes adopting BLS12-381 a strict performance improvement in all areas, without the auditing cost of assembly optimization.

Here are my current benchmarks:

BLS12-381 (Rust):
    G1 addition: 1,249 ns/iter
    G2 addition: 4,141 ns/iter
    Full pairing: 2,557,330 ns/iter
        G1 precomputation: 12,894 ns/iter
        G2 precomputation: 223,809 ns/iter
        Miller loop: 606,379 ns/iter
        Final exponentiation: 1,696,878 ns/iter

libsnark USE_ASM off:
    G1 addition: 1,366 ns/iter.
    G2 addition: 6,509 ns/iter.
    Full pairing: 4,199,397 ns/iter.
        G1 precomputation: 3,102 ns/iter.
        G2 precomputation: 540,984 ns/iter.
        Miller loop: 1,339,208 ns/iter.
        Final exponentiation: 2,332,928 ns/iter.

libsnark USE_ASM on:
    G1 addition: 900 ns/iter.
    G2 addition: 3,990 ns/iter.
    Full pairing: 2,627,332 ns/iter.
        G1 precomputation: 3,002 ns/iter.
        G2 precomputation: 338,027 ns/iter.
        Miller loop: 838,821 ns/iter.
        Final exponentiation: 1,437,695 ns/iter.

ate-pairing:
    G1 addition: 735 ns/iter.
    G2 addition: 1,897 ns/iter.
    Full pairing: 659,231 ns/iter.
        G1 precomputation: 2,615 ns/iter.
        G2 precomputation: 91,191 ns/iter.
        Miller loop: 216,609 ns/iter.
        Final exponentiation: 346,264 ns/iter.

Obviously, ate-pairing is way faster, but it relies on dynamic code compilation and tons of tricky optimizations. Hence, we don't use it in Zcash.

Security of BLS12-381

BLS12-381 follows the recommendations of several papers that pairing-friendly curves with embedding degree 12 should be instantiated over approximately 384-bit fields. (BN curves are thus unacceptable for us, because they will have exceedingly large scalar fields.)

BLS12-381 is also a far more rigid construction; it is part of a subfamily of BLS curves that have optimal extension field towers, simple twisting isomorphisms, and immediately determined curve parameters. It is the largest curve that meets our requirements for zk-SNARK efficiency, and so it's likely that others would arrive to the same curve as well.

The same cannot be said of BN254, which was chosen without respect to pairing and G2 performance.

Matthew Green and Ian Miers had Paulo Barreto and Diego Aranha, both experts in these curves, take a look at the BLS12-381 construction. Diego even implemented it in his RELIC library. It is also slated to appear in an upcoming academic paper.

Implementation of BLS12-381

As I previously mentioned, I have an implementation of BLS12-381 in Rust. This implementation follows over a year of refinement, testing, and auditing in which I uncovered several bugs in libsnark, one of which was a subgroup attack vulnerability (now fixed) and others that could have manifested as remote DoS. I carefully avoid some of the mistakes made in libsnark's BN254 implementation.

I'm also automatically testing my implementation on 64-bit and 32-bit Linux/Windows.

I'm not entirely finished with this implementation, but when I'm finished it should have strong guarantees against memory safety problems and API misuse, without the portability problems of libsnark's curve implementations. It already has and will continue to accrue extensive test coverage.

@ebfull ebfull added the NU1-sapling Network upgrade: Sapling-specific tasks label Jul 2, 2017
@daira
Copy link
Contributor

daira commented Jul 2, 2017

Concept ACK.

I assume that the recent improvements to libsnark's multiexp algorithm (using the simplification of Pippenger's algorithm) are orthogonal to the choice of curve, and haven't yet but could be applied to the Rust implementation?

@daira
Copy link
Contributor

daira commented Jul 2, 2017

Let's not forget that BLS12-381 comes also along with an inner curve (that I called Ed255-Jubjub here) which we intend to use for Pedersen hashes and commitments, and possibly note encryption. The security of that curve also needs to be analysed, although it does not need to be pairing-friendly so is subject to fewer design constraints.

@ebfull
Copy link
Contributor Author

ebfull commented Jul 3, 2017

I assume that the recent improvements to libsnark's multiexp algorithm (using the simplification of Pippenger's algorithm) are orthogonal to the choice of curve, and haven't yet but could be applied to the Rust implementation?

Indeed, the choice of curve does not affect that algorithm.

@nathan-at-least
Copy link
Contributor

I've removed this from DevInfra project. It seems to fit Sapling much better. The Dev Infra tasks that might be associated, though, are adding proper CI support to test the switch. I assume those tickets will come later in the process.

@nathan-at-least
Copy link
Contributor

It sounds like this construct has review from a couple of domain experts, two implementations, and the performance and security benefits described above. We're proceeding with this curve for the Sapling upgrade, barring surprises.

@arielgabizon
Copy link
Contributor

arielgabizon commented Jul 3, 2017

References for recent security recommendations from bls-12 curves to obtain 128 bit security

According to the extremely conservative estimates of https://eprint.iacr.org/2017/334.pdf,
see 2.2 together with 7.2 there.
We would need an ever larger field - 462 bits (to be precise they recommend this field size for the 128 bit security level but say you get 131.8 security bits with it)

https://eprint.iacr.org/2016/1102.pdf , page 18, which are also very conservative in my opinion.
Say 384 bits are enough - slightly more than the 381 bits here.

@daira
Copy link
Contributor

daira commented Jul 4, 2017

The difference between 381 and 384 bits is neither here nor there. (Note that our current construction targets 126-bit security, not 128.)

https://eprint.iacr.org/2017/334.pdf claims (table 8) that the GT field size needs to be 5530 bits for BLS12, which is really very conservative indeed.

@ebfull
Copy link
Contributor Author

ebfull commented Jul 4, 2017

Note that we can't go much larger than BLS12-381 without blowing past our performance budget. It was hard enough to get the curve implementation faster than libsnark despite the fact the curve is bigger.

@ebfull
Copy link
Contributor Author

ebfull commented Jul 4, 2017

I wanted to point out a neat coincidence: 381/3 = 127, and 127*2 = 254. 254 bits is the capacity of the scalar field. This means that Fq multiplications/squarings inside the circuit (for things like #2425) can be achieved through elegant 127-bit limb arithmetic.

@ebfull
Copy link
Contributor Author

ebfull commented Jul 8, 2017

I've just published a work-in-progress implementation of BLS12-381:

https://github.com/ebfull/pairing

At this point, it merely needs more testing and implementations of serialization. Once those are done, I will make it 1.0 and solicit reviews. Everything else can be built on top, including the new multiexp, wNAF, FFTs, etc.

@daira daira added the M-requires-nu A network upgrade is required to implement this. label Sep 27, 2017
@str4d str4d added this to the 1.0.14 milestone Nov 29, 2017
@str4d str4d modified the milestones: 1.0.14, Sapling Specification Jan 2, 2018
@daira
Copy link
Contributor

daira commented Mar 2, 2018

Done.

@NickyYangYang
Copy link

I have a question. In this page(https://github.com/zcash/zcash/tree/master/src/snark), you say you choose the Elliptic curve BN128. Now you say your zk-SNARKs currently rely on BN254.
Then which curve you use in your zk-SNARKs, or BN128 is same with BN254?
And, the signature length of the Elliptic curve is 256 bits?

@daira
Copy link
Contributor

daira commented Aug 9, 2018

@NickyYangYang BN128 is the same as BN-254. The convention was previously to name the pairing according to its conjectured security level, but that does not make sense since the conjectured security level may change for a given pairing. The new convention is to name the pairing by its size — more precisely, by the bit length of its prime field (over which $\mathbb{G}_1$ is defined).

@kamel78
Copy link

kamel78 commented Apr 25, 2019

I have tested your code on an I7. It is very slow 100ms for full pairing.

@kamel78
Copy link

kamel78 commented Apr 25, 2019

Tested On Windows 8
Rust 1.8
Full pairing for BLS128381 : about 100 ms.?????????????????

where is the acceleration are talking about???????????

@daira
Copy link
Contributor

daira commented Apr 26, 2019

@kamel78 Are you compiling the Rust code in release mode? Debug mode will be very slow.

@kamel78
Copy link

kamel78 commented Apr 27, 2019 via email

@kamel78
Copy link

kamel78 commented May 16, 2019

Dear

I am really new in Rust and i try to understand the code for BLS381 in Rust that you have published. Can you please tell me in the module Fq whe the coeifficient B B_COEFF if inititalized using such complex array in the FqRepr while its value is simply 4 ? I can't undersand such representation and how to convert it form and to Big integer One.

Kind regards

@kamel78
Copy link

kamel78 commented Jul 3, 2019

Why not BLS12-461 with same performances !!!

I have Benchmarked your implementation of the BLS12-381, and it is really a great and fast implementation. However, according to recent researches (https://eprint.iacr.org/2017/334.pdf), 381 is not enough secure for 128bit level security. Instead, one have to use at less 460 bit for the base field in order to achieve such security level. I Have implemented the proposed BLS12-461 curve with Rust (i have modified your proposed code accordingly), and i have reach very efficient performances (3 ms only for full pairing, so less than one millisecond of gap with respect to the BLS12-381 runtime ), so that we can get guaranteed security level with negligible supplementary run time.

If you project team is interested i can share my code with you so that you can use it instead of the BLS12-381 and get much better security level with equivalents performances. I have implemented several optimization tricks, and revised several code parts (Miller Loop, Exponentiation and Frobenius).

Kind Regards

@daira
Copy link
Contributor

daira commented Jul 3, 2019

@kamel78 wrote:

Can you please tell me in the module Fq whe the coeifficient B B_COEFF if inititalized using such complex array in the FqRepr while its value is simply 4 ?

FqRepr uses a Montgomery representation of the field element (see also https://eprint.iacr.org/2017/1057.pdf ).

However, according to recent researches (https://eprint.iacr.org/2017/334.pdf), 381 is not enough secure for 128bit level security. Instead, one have to use at less 460 bit for the base field in order to achieve such security level.

The assumptions made in that paper are extremely conservative. My understanding is that there is currently no known attack on BLS12-381 that is better in practice than the generic square-root attacks on G1 (see footnote 1 in https://electriccoin.co/blog/new-snark-curve/ ).

Switching to a new curve would require a complete circuit upgrade and a new setup (both powers-of-tau and the circuit-specific setup), as well as replacing the Jubjub curve which is used for signatures outside the circuit. Since we're pretty confident of the security of BLS12-381, we don't see any need to do that at this time.

Note that there's quite a bit of scope for further optimization of the BLS12-381 implementation, at least for pairing evaluation — e.g. see https://github.com/mikelodder7/bls12-381-comparison . A new implementation is being worked on.

@kamel78
Copy link

kamel78 commented Jul 3, 2019

Thanks for Remarks!
Just to note that the BLS-461 curve i have implemented has a very low hamming weight for the x parameter (only 2 bits), so can achieve better performances that BLS-381 while using Karabiner squaring (that optimization is not implemented by your code). In addition, the miller loop is faster when using Naf representation of X.
My code is available if you want , at any time!!

Regards

ps: just a remark for BLS-381: Frobenius has not to be computed for Fp2 elements (as implemented in your code), it is just the conjugate !!

@daira
Copy link
Contributor

daira commented Jul 3, 2019

Here's a more recent paper, that recommends at least 4352 bits for Fpk at the 128-bit security level when k is composite: https://eprint.iacr.org/2018/1017.pdf . For BLS12-381 it is 4572 bits.

@kamel78
Copy link

kamel78 commented Jul 3, 2019

It is also necessary to consider enhance the implementation of the Miller loop to face side channel attack and fault injection attacks. The cost of the fix is negligible. Otherwise, the implementation is vulnerable to such attacks

@daira
Copy link
Contributor

daira commented Jul 4, 2019

Zcash is not vulnerable to any potential side channel attacks on the pairing implementation, because pairings are only used for proof verification, with public inputs.

(Nevertheless, I think the new implementation we're working on is intended to be side-channel resistant, so that it can be used for other applications where that is important.)

AnnaShaleva added a commit to nspcc-dev/neo-go that referenced this issue Nov 28, 2023
Turns out that Zcash swiched to BLS12-381 since zcash/zcash#2502,
thanks to @EdgeDLT for pointing that out. I've checked that our
TestCubicCircuit_EndToEnd_Prod test passes with response file downloaded
from the attestations page of Zcash ceremony, thus I propose to put theirs
attestations link before the link to PPoT, because PPoT attestations contain
outdated links and not all responses can be downloaded.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
AnnaShaleva added a commit to nspcc-dev/neo-go that referenced this issue Nov 28, 2023
Turns out that Zcash swiched to BLS12-381 since zcash/zcash#2502,
thanks to @EdgeDLT for pointing that out. I've checked that our
TestCubicCircuit_EndToEnd_Prod test passes with response file downloaded
from the attestations page of Zcash ceremony, thus I propose to put theirs
attestations link before the link to PPoT, because PPoT attestations contain
outdated links and not all responses can be downloaded.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
M-requires-nu A network upgrade is required to implement this. NU1-sapling Network upgrade: Sapling-specific tasks
Projects
None yet
Development

No branches or pull requests

7 participants