Giter Club home page Giter Club logo

bls12_381's Introduction

bls12_381 Crates.io

This crate provides an implementation of the BLS12-381 pairing-friendly elliptic curve construction.

  • This implementation has not been reviewed or audited. Use at your own risk.
  • This implementation targets Rust 1.56 or later.
  • This implementation does not require the Rust standard library.
  • All operations are constant time unless explicitly noted.

RFC process

This crate follows the zkcrypto RFC process. If you want to propose "substantial" changes to this crate, please create an RFC for wider discussion.

Features

  • bits (on by default): Enables APIs for obtaining bit iterators for scalars.
  • groups (on by default): Enables APIs for performing group arithmetic with G1, G2, and GT.
  • pairings (on by default): Enables some APIs for performing pairings.
  • alloc (on by default): Enables APIs that require an allocator; these include pairing optimizations.
  • nightly: Enables subtle/nightly which tries to prevent compiler optimizations that could jeopardize constant time operations. Requires the nightly Rust compiler.
  • experimental: Enables experimental features. These features have no backwards-compatibility guarantees and may change at any time; users that depend on specific behaviour should pin an exact version of this crate. The current list of experimental features:

Curve Description

BLS12-381 is a pairing-friendly elliptic curve construction from the BLS family, with embedding degree 12. It is built over a 381-bit prime field GF(p) with...

  • z = -0xd201000000010000
  • p = (z - 1)2(z4 - z2 + 1) / 3 + z
    • = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab
  • q = z4 - z2 + 1
    • = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001

... yielding two source groups G1 and G2, each of 255-bit prime order q, such that an efficiently computable non-degenerate bilinear pairing function e exists into a third target group GT. Specifically, G1 is the q-order subgroup of E(Fp) : y2 = x3 + 4 and G2 is the q-order subgroup of E'(Fp2) : y2 = x3 + 4(u + 1) where the extension field Fp2 is defined as Fp(u) / (u2 + 1).

BLS12-381 is chosen so that z has small Hamming weight (to improve pairing performance) and also so that GF(q) has a large 232 primitive root of unity for performing radix-2 fast Fourier transforms for efficient multi-point evaluation and interpolation. It is also chosen so that it exists in a particularly efficient and rigid subfamily of BLS12 curves.

Curve Security

Pairing-friendly elliptic curve constructions are (necessarily) less secure than conventional elliptic curves due to their small "embedding degree". Given a small enough embedding degree, the pairing function itself would allow for a break in DLP hardness if it projected into a weak target group, as weaknesses in this target group are immediately translated into weaknesses in the source group.

In order to achieve reasonable security without an unreasonably expensive pairing function, a careful choice of embedding degree, base field characteristic and prime subgroup order must be made. BLS12-381 uses an embedding degree of 12 to ensure fast pairing performance but a choice of a 381-bit base field characteristic to yield a 255-bit subgroup order (for protection against Pollard's rho algorithm) while reaching close to a 128-bit security level.

There are known optimizations of the Number Field Sieve algorithm which could be used to weaken DLP security in the target group by taking advantage of its structure, as it is a multiplicative subgroup of a low-degree extension field. However, these attacks require an (as of yet unknown) efficient algorithm for scanning a large space of polynomials. Even if the attack were practical it would only reduce security to roughly 117 to 120 bits. (This contrasts with 254-bit BN curves which usually have less than 100 bits of security in the same situation.)

Alternative Curves

Applications may wish to exchange pairing performance and/or G2 performance by using BLS24 or KSS16 curves which conservatively target 128-bit security. In applications that need cycles of elliptic curves for e.g. arbitrary proof composition, MNT6/MNT4 curve cycles are known that target the 128-bit security level. In applications that only need fixed-depth proof composition, curves of this form have been constructed as part of Zexe.

Acknowledgements

Please see Cargo.toml for a list of primary authors of this codebase.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

bls12_381's People

Contributors

a-manning avatar andrewwhitehead avatar daniel-aaron-bloom avatar dignifiedquire avatar ebfull avatar erikzhang avatar iamalwaysuncomfortable avatar joebebel avatar justindrake avatar mmaker avatar nuttycom avatar rex4539 avatar saitima avatar str4d 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  avatar  avatar  avatar  avatar  avatar

bls12_381's Issues

Fix `Gt::default()` implementation

Currently we have a #[derive(Default)] on Gt. This will return Gt(Fp12::default()) which is Gt(Fp12::zero()) - which is nonsensical. Gt::default() should actually return Gt::identity() which is Gt(Fp12::one()).

This is a bugfix, but as it materially affects the API, it should go into the next breaking change release.

question about the code

Hi, I just started learning pairing crypto, and try to read the code, I am confused about the following code:

bls12_381/src/fp6.rs

Lines 113 to 119 in 34dab74

pub fn mul_by_1(&self, c1: &Fp2) -> Fp6 {
let b_b = self.c1 * c1;
let t1 = (self.c1 + self.c2) * c1 - b_b;
let t1 = t1.mul_by_nonresidue();
let t2 = (self.c0 + self.c1) * c1 - b_b;

why not using the following expression to calculate t1 ?:

      let t1 = self.c2 * c1; 

Performance benchmarks?

Where can I find performance benchmarks? For instance, point doubling, point addition, inversion etc.

Acceptable encoding of infinite points

The current serialization notes (https://github.com/zkcrypto/bls12_381/blob/main/src/notes/serialization.rs#L23-L25) state that for points with infinity bit set "the remaining bits of the group element's encoding should be set to zero."

Is this a should in the "SHOULD" sense of RFC 2119; a behavior that is preferential but can be ignored if useful? Or is it an informal statement of a strict requirement (aka a "MUST")? This crate seems to strictly require that if the infinity bit is set that all other bits are zeroed.

How can I multiply elements in Gt with another Gt?

I was trying to implement https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.9. The algorithm is:

   1.  R = signature_to_point(signature)
   2.  If R is INVALID, return INVALID
   3.  If signature_subgroup_check(R) is INVALID, return INVALID
   4.  C1 = 1 (the identity element in GT)
   5.  for i in 1, ..., n:
   6.      If KeyValidate(PK_i) is INVALID, return INVALID
   7.      xP = pubkey_to_point(PK_i)
   8.      Q = hash_to_point(message_i)
   9.      C1 = C1 * pairing(Q, xP)
   10. C2 = pairing(R, P)
   11. If C1 == C2, return VALID, else return INVALID

I'm stuck on line#9, the current code allows multiplying Gt * Scalar (if I'm reading the code correctly); is there a way to do Gt * Gt?

Thanks!
Specifically line#9;

Architecture-specific backends?

Does it fit with the goals of this crate to have architecture-specific backends? For instance, a specialized NEON backend for mobile or embedded devices, or an ADX backend for x86. This conflicts with some stated goals of the crate (no unsafe code), and would require some planning on how to abstract over the backend, so I wanted to check first. It is totally reasonable for the strategy to be to instead provide a pure-rust, all-safe-code implementation as is the case now.

Change BLS parameter to z

Right now README.md calls the parameter for the curve z, but in various places in the code it is called x. Probably the code should be changed to match the README. (This shouldn't affect the API.)

Serde support

We'd like to have Serde support for use implementing FROST for redjubjub (tracking issue: ZcashFoundation/redjubjub#21). I'd be happy to implement this (probably feature-gated behind a serde feature?) if it would fit with the library.

Tests can't compile due to rayon MSRV update without new minor bump

If you try to run the tests for this lib, you'll see that you get:

error: package rayon-core v1.11.0 cannot be built because it requires rustc 1.59 or newer, while the currently active rustc version is 1.56.0

This is due to the fact that:

❯ cargo tree -i rayon-core       
rayon-core v1.11.0
└── rayon v1.7.0
    └── criterion v0.3.6
        [dev-dependencies]
        └── bls12_381 v0.8.0 

As you can see here, criterion depends on rayon_core with ^0.3. After rayon moved up MSRV without bumping minor version, everything broke.

We might want to either:

  • Bump MSRV.
  • Fix Cargo.lock (doesn't make any sense to me as this is a lib).
  • Downgrade Criterion in hopes it uses a version of rayon compatible with rustc 1.56.0 or older.

@str4d let me know what you prefer and I'll push a PR.

Zero point for SWJacobian

Hi, shouldn't the zero point in SW Jacobian be any point of the form (t^2:t^3:0) with t <> 0 (conventionally represented with (1:1:0)), instead of (0:1:0), which is actually the zero point in SWProjective ?

pub fn identity() -> G1Projective {

Scalar::pow not ergonomic between two Scalars

Exponentiation between two scalars is currently difficult because exponentiation is implemented as fn pow(&self, by: &[u64; 4]) -> Self. Whilst Scalar::to_bytes converts to a little endian byte encoded integer, it is not directly usable for pow as it does not yield an array of [u64; 4].

Consider adding a variant of pow that directly accepts Scalars.

Upgrade sha2/sha3/digest from 0.9 to 0.10

I'd like to upgrade sha2 in my codebase to 0.10, which is used for ExpandMsgXmd<H: Digest> here. It would be great if that could be upgraded when someone gets the chance.

I spent some time on an upgrade but then gave up since I am not at all familiar with the digest traits and how hash_to_curve is implemented here.

Interest in faster implementation of scalar multiplication in G1/G2

Hi,

I have a bunch of optimizations for faster G1/G2 scalar multiplications sitting in a fork at https://github.com/dfaranha/bls12_381

These provide a 2x speedup and include:

  • Regular w-NAF recodings to reduce the number of point additions in comparison to double-and-always add
  • GLV recoding for scalar decomposition, combined with interleaving to save half of the point doublings
  • Moving to homogeneous projective coordinates for pairing computation to unify point arithmetic

Some technical details can be found at https://skillsmatter.com/skillscasts/17052-experimenting-with-faster-elliptic-curves-in-rust

I would like to know if there is interest in merging, so it makes sense to put time on preparing a proper pull request.

Thank you for your attention!

Support Zeroize

Cryptographic applications should be able to wipe sensitive data from memory before deallocating it. E.g. the elements of Fr can be used as secret BLS keys.

Without support from the bls12_381 crate itself, any attempt to clear such data necessarily depends on an implementation detail of bls12_381 that is not part of the public API, e.g. Fr not using any pointers internally.

The safest way to support this would be to add explicit methods for clearing, or to impl Zeroize for Fr. If the added zeroize dependency is a concern, it could be made optional, and put behind a feature flag.

Get access to the `Fp12` representation from `Gt`

The https://docs.rs/bls12_381/0.7.0/bls12_381/struct.Gt.html has very little functionality exposed at the moment.
It implements the Group trait and a few helpers, however this is not enough for one of the ZK protocols we have.

What would suffice for us is a way to get the underlying Fp12 representation of Gt. For example,

impl AsRef<Fp12> for Gt {
   ...
}

would be perfectly adequate, or any other alternative you would prefer.

Is this something you are open to adding to the library? Without this we cannot upgrade from the old pairing crate that embedded the bls implementation to the recent one.

This is related to #10 although I need less than that.

Migrate to property-based testing.

Rather than just having unit tests, I think it would be nice to have property-based testing for the library using proptest; this would allow much more detailed testing / structured fuzzing. Also, some existing unit tests could probably be replaced with property-based tests. Would you be interested in a PR that added property-based tests and refactored existing unit tests (as appropriate, obviously only the ones that are really just testing a property on a single example)?

Remove operations on full-group elements from the public API

G1 and G2 are prime-order subgroups, but they currently have several public APIs that don't apply to prime-order groups:

  • G1Affine::is_torsion_free
  • G1Affine::is_on_curve
  • G1Projective::clear_cofactor
  • G1Projective::is_on_curve
  • Similarly for G2Affine and G2Projective.

The is_* APIs are all documented as "Always returns true unless the unchecked APIs were [mis]used". Meanwhile, clear_cofactor (added in #18) is defined as mapping elliptic curve points to elements of G{1,2}, but the type it is defined on is already an element of G{1,2}.

These APIs were implemented because of the G*Affine::from_[un]compressed_unchecked APIs, which can technically be used to load full-group elements, but doing so is explicitly breaking the requirements set by the *_unchecked APIs, so this shouldn't be a supported case.

We should make the above APIs private (all except G*Projective::is_on_curve are used internally), and then consider on a case-by-case basis how to handle full-group elements (which in general we do not want to expose or support).

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.