herumi / mcl

a portable and fast pairing-based cryptography library
BSD 3-Clause "New" or "Revised" License
458 stars 157 forks source link

how to get G1::zero() and G1::one()? #30

Closed huyuguang closed 6 years ago

huyuguang commented 6 years ago

I think it's a stupid question...

How can I get the zero and one element in G? Should I use G1 zero(Fp(0), Fp(0))? And, as my understanding, the one is the generator of the G, but how to get it?

huyuguang commented 6 years ago

the class EcT only has two parameters constructor, so now I wrote the code like: (bn_zksnark curve)

G1 G1Zero() {
    G1 r;
    r.x = Fp(0);
    r.y = Fp(1);
    r.z = Fp(0);
    return r;
}

G1 G1One() {
    G1 r(Fp(1),Fp(2));
    return r;
}

G2 G2Zero() {
    G2 r;
    r.x = Fp2(0,0);
    r.y = Fp2(1,0);
    r.z = Fp2(0,0);
    return r;
}

G2 G2One() {
    G2 r(Fp2("10857046999023057135944570762232829481370756359578518086990519993285655852781",
        "11559732032986387107991004021392285783925812861821192530917403151452391805634"),
        Fp2("8495653923123431417604973247489272438418190587263600148770280649306958101930",
            "4082367875863433681332203403145435568316851327593401208105741076214120093531"));
    return r;
}

Hope you can check if it is right.

herumi commented 6 years ago

Could you use G1::clear() and G2::clear() to get zero point?

(1, 2) is not on G1, so G1(1, 2) throws an exception. G1(-1, 1) is a correct point on G1 over BN-curve and you can use it as one. A simple way to get a generator of G1 is hashAndMapToG1.

G1 P;
BN::hashAndMapToG1(P, "abc");
G2 Q;
BN::hashAndMapToG2(Q, "abc");

You can change "abc" to any message.

huyuguang commented 6 years ago

I use bn-zksnark curve, in libsnark, it uses point (1,2) as one.

Another question, now I use the following code to implement G1::rand():

Fr FrRand() {
    Fr r;
    r.setByCSPRNG();
    return r;
}

G1 G1Rand() {
    G1 out;
    for (;;) {
        bool b;
        mcl::bn256::mapToG1(&b, out, FpRand());
        if (b) break;
    }
    return out;
}

Am I right?

And, the last question: Could you please implment function multiexp? G multiexp(vector<G> const& g, vector<F> const& f);

herumi commented 6 years ago

Am I right?

Yes.

G multiexp(vector const& g, vector const& f);

Does it return prod_i g[i]^f[i]? How about implementing it yourself?

herumi commented 6 years ago

It is not two multi scalar (aP + bQ), but multi scalar for many base points?

huyuguang commented 6 years ago

the basic implement about multiexp(vector const& g, vector const& f) is like:

G multiexp(g, f) {
   assert(g.size() == f.size());
   G ret = G::zero();
   for(i=0;i<g.size();++i) {
      ret += f[i] * g[i];
   }
   return ret;
}

But the above implementation is not optimized, I heard there are exist some optimize algorithms (I do not understand that) which can do it much faster. For example: https://github.com/scipr-lab/libff/blob/master/libff/algebra/scalar_multiplication/multiexp.tcc

herumi commented 6 years ago

Okay, I'll see it later.