GithubHelp home page GithubHelp logo

pairing's People

Contributors

bmerge avatar dignifiedquire avatar ebfull avatar gilescope avatar jasondavies avatar kigawas avatar mmaker avatar nuttycom 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pairing's Issues

Re-enable expl_impl_clone_on_copy

This is a clippy lint that I'm disabling temporarily until the next Rust stable release which automatically implements clone for [T; N] (where T: Copy). The explicit Clone impls can be replaced with derives without affecting the API.

Ordering on curve points

For some applications it might be necessary to define an order on the elliptic curve points.
To give you an example, I am currently building an application using BLS signature built on top of this pairing library that needs to order the public keys by some deterministic ordering.

Currently, the only way to do that is using the encoded forms. And that leaves us with three options:

  • Storing PublicKeys in a serialised form
  • Serialising PublicKeys for every comparison
  • Storing PublicKeys in both, serialised and point form

None of these options is really attractive.

To mitigate this, there would be multiple options available:

  1. Implementing Ord on curve points
  2. Adding a function similar to the Ord::cmp
  3. Adding an option to expose the internals of a curve point

Since the ordering is not really well defined, I am not a big fan of option 1.
I also don't like exposing the internal coordinates too much (could also be done for the specific curve implementations only), although I would see it as a valid option.
Option 2 currently seems to be the cleanest to me.

I'd like to hear other opinions as well.

Edit: I saw that Fq/Fq2 implement Ord as well and define lexicographic ordering, so option 1. might still be in.
An example of how to implement a lexicographic ordering can be found in my fork.

Double reference in `miller_loop`

The function miller_loop takes an IntoIterator<Item = &'a (&'a _, &' _)> which agrees with the IntoIterator for a &Vec<(&_,&_)>, but basically nothing else.

There is no way to construct the outer &'a from iterator adapters, requiring a fresh allocation. Yet, you could easily make any collection work without the outer &'a using .into_iter().map(|t| *t) or |(x,y)| (x,y) or similar. I'd think the G2 prepared points are commonly ephemeral, so this requires two ephemeral data structures, one containing the prepared points, and one containing the references to them, while both sound superfluous.

We cannot wrap the current miller_loop in an interface that takes borrows, but maybe it'd work if miller_loop took them directly, so maybe try

fn miller_loop<I,P1,P2>(i: I) -> Self::Fqk
where
    I: IntoIterator<Item=(P1,P2)>,
    P1: Borrow<<Self::G1Affine as CurveAffine>::Prepared>,
    P2: Borrow<<Self::G2Affine as CurveAffine>::Prepared>,

You could make Item: Borrow<(P1,P2)> too if you wanted backwards compatibility with the current interface, but I'd make callers use .into_iter().map(|t| *t) here myself.

In fact, you allocate internally anyways, so maybe one should favor &[P1,P2] over the iterator anyways, not sure.

Troubles with Fq::pow

Hello!
I'm trying to get Fq::pow to work, but it seems I can't get it right… is this me or is it really a bug?
This is what I can get to do with sage:

sage: def h(x): return hex(int(x))[:-1] # this is only to get a confrontable hex representation 
sage: q = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
sage: Fq = GF(q)
sage: h(q)
'0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'
sage: a = Fq(945268695322731484897977891916087812827587793626675745004848628347665446205888379878456193299686130571287070888667)
sage: h(a)
'0x6243b9d40ce4d8c1d86a603d9ce33eb76736fc8900b1e8da6de01cbdb27177539b472f83366efa4ed5bf6438391d2db'
sage: a**9
1183374762412757565163659156070127511863449313069977006820839763739586492957873774713939591053070945417445562515423
sage: h(a**9)
'0x7b04438ade27f8f2b916ebad4ad86d3941f87b5bbb022113edcf19384b6892c9e5fa522f8d60ab97d5c4ef522adffdf'

but if I attempt to add the following test case to fq.rs:

#[test]
fn test_pow_bug() {
    let e = Fq(FqRepr([0xd5bf6438391d2db, 0x9b472f83366efa4e, 0x6de01cbdb2717753,
                       0x6736fc8900b1e8da, 0xd86a603d9ce33eb7, 0x6243b9d40ce4d8c1]));
    let expected = Fq(FqRepr([0xd5c4ef522adffdf, 0xe5fa522f8d60ab97, 0xedcf19384b6892c9,
                              0x41f87b5bbb022113, 0xb916ebad4ad86d39, 0x7b04438ade27f8f2]));

    let got = e.pow([0x9, 0x0, 0x0, 0x0, 0x0, 0x0]);
    assert_eq!(got, expected)

the test fails:

---- bls12_381::fq::test_pow_bug stdout ----               
        thread 'bls12_381::fq::test_pow_bug' panicked at 'assertion failed: `(left == right)`                          
  left: `Fq(FqRepr([15168336788228049517, 6104148727050941414, 11744620724444176788, 291052430401786830, 12974234119515072997, 720310162563104718]))`,                                                                                         
 right: `Fq(FqRepr([962731235106226143, 16571648143052024727, 17135942836742034121, 4753685040599277843, 13337106476021869881, 8864284230283688178]))`', src/bls12_381/fq.rs:1817:4                                                            
note: Run with `RUST_BACKTRACE=1` for a backtrace. 

am I doing something wrong here?

Document security warnings

One of which is that this library does not provide any constant-time guarantees or guarantees against side-channel attacks.

Operator Overloading

Would it make sense to overload the arithmetic operators (std::ops) for everything that has an add, add_assign, mul or mul_assign method? I would love being able to write x += y; instead of x.add_assign(y), but I know that there are arguments against it, too. It certainly would make some heavy computation "feel" more lightweight than it is.

What's your opinion on this? If you are fine with it, I'd be happy to try and make e.g. Field: AddAssign + MulAssign + SubAssign + Neg, and CurveAffine: Mul + Neg.

Specify serialization

Currently a bit is set to distinguish between elements of compressed and uncompressed form, a bit is set to identify the "parity" of a compressed-form element. I should set another bit to indicate it's not the point at infinity, for the reason @daira suggests here: 3faf8c5#commitcomment-23094853

Looping in zcash/zcash#2517 on this.

Once the serialization is changed (and fully tested against rejection test vectors #10) this ticket should be closed when it is specified in src/bls12_381.

Documentation in impl PartialEq for $projective seems incorrect

A comment in the impl says:

// The points (X, Y, Z) and (X', Y', Z')
// are equal when (X * Z^2) = (X' * Z'^2)
// and (Y * Z^3) = (Y' * Z'^3).

However, the impl seems to actually check this:

                // The points (X, Y, Z) and (X', Y', Z')
                // are equal when (X * Z'^2) = (X' * Z^2)
                // and (Y * Z'^3) = (Y' * Z^3).

I think the comment is wrong and the implementation is correct. Either way, this should be fixed.

Serde support

It would be convenient to have serde's Serialize and Deserialize traits implemented for the groups and fields, so they could be seamlessly used e.g. for storing keys on disk, or sending signatures over the network.

To keep the dependencies minimal, this could be behind a feature flag.

Computation Hardness Assumptions?

I am thinking about using this implementation to implement an encryption scheme. Is the Bilinear Diffie-Hellman assumption believed to hold for this pairing? What about stronger assumptions (e.g., Strong Diffie-Hellman, Bilinear Diffie-Hellman Exponent, etc.)?

If you additionally know any papers/other sources discussing this, that would be very useful.

Updating rand

Rand is at 0.6, while this crate and others around it are still at 0.4. This results in conflicts when I try to use it in combination with other crates which already depend on 0.5 or 0.6.

Would a PR updating to 0.6 be accepted?

Slothful reduction

Is there anything to be gained from applying ideas from https://eprint.iacr.org/2017/437 here? I noticed amcl claims constant time operations based on that. All this is irrelevant for zcash perhaps? Right now, I donno anyone who would care about pairings being constant time, for example.

Block 1.0 on dependencies

The rand crate is currently a dependency of this library, as some facilities for randomly generating scalars or curve points are provided generally over random number generators. The rand crate is not 1.0, and is undergoing refactoring. As such, this library should not be considered 1.0 unless functionality that requires rand is hidden behind an unstable crate feature.

byteorder is another dependency of this crate, but is not "public" in the sense that none of its types are exposed in public APIs by this library. This crate thus does not block 1.0, but should be explicitly marked private when public/private dependencies is stable in Rust/cargo.

Add test vectors for rejected group encodings

  • not on curve
  • not on subgroup
  • each or all of the field elements in the representation are not in the field
  • distinguishers not set for compressed elements
  • distinguisher against point at infinity not set

Implement `Default` for fields.

The primitive numeric types are zero by default, and I wonder whether Fields should be, too.

One use case is if field elements are used as private keys: The clear_on_drop crate helps prevent leaking secrets by overwriting the memory before freeing it, but it requires the type to implement Default. (It's not as trivial as it sounds: it needs to prevent some compiler optimizations.)

It would also enable a few convenience methods from the standard library, like unwrap_or_default, to work on Fields the same way as on u64s and others.

Elevating u128-support to default

I'd like to use u128 only in this library and remove the backup arithmetic, but only if its arithmetic is lowered properly on target platforms that don't support it.

My ideal strategy:

  1. Remove feature(i128_type) invocation, since it is no longer needed on nightly or (eventually) the 1.26 beta compiler. Do patch release.
  2. Once 1.26 stable is released, change documentation to remove mentions of nightly. CI can be changed to always target stable, except for clippy. (See #45)
  3. When u128 lowering definitely works, remove backup arithmetic and use u128-support arithmetic only. The u128-support feature will do nothing. In the next minor release, remove the u128-support feature.

Bellman CI

Hook up Bellman's CI to this library.

some question about bls12-381

hello, I want to ensure whether the security level of BLS12-381 is 128 bit.
And the signature length of BLS12-381. Is 48 Bytes?

Stable wNAF API

Currently you have to opt-in to it because it's a low level API. I want a simple API that you cannot misuse.

Need to choose random y to end up with rand point after scaling?

impl Rand for $projective {

The rand method starts with point on curve and scales by cofactor..
but it doesn't seem to start from random point - the x coordinate is random,
but then the 'get_point_from_x' method seems to deterministically choose the y coord,
rather than randomly from the two options.
So can we still say the final subgroup point is random?

I think there's a good chance it's just random on half the group.
Cause if the equation is of the form y^2=f(x)
(x,y) and (x,-y) are inverses so
also after scaling you always only one of P or -P

Rand should produce points of unknown exponent

This is a stopgap for if we can't manage to get a solid G1/G2 hashing into this library before an audit begins. This allows us to build safe hashing on top, though it won't be as well-specified.

Make wNAF an "unstable" feature

I don't want to stabilize the wNAF API, since I would prefer to have a wrapper around these functions that prevents downstream users from supplying incorrect or inconsistent window table sizes. I'll have to explore all of the ways in which the API is used by bellman and other projects before I settle on a design for such a wrapper.

In the mean time, let's hide the wnaf submodule behind a crate feature marked unstable-wnaf.

Pairing speed relative to the herumi/mcl implementation

For BN254, Dfinity's implementation does pairing in less than 0.8ms (see here):

Notably, we see the signature validation time is 0.8 ms which involves a pairing evaluation.

This contrasts very favourably compared to the numbers given in this post where a BN254 pairing is done 2.5ms with USE_ASM. Why is the discrepancy so high, and does this suggest that this implementation can be sped up significantly?

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.