|
|
|
@ -14,16 +14,75 @@ namespace mcl { namespace bls12 { |
|
|
|
|
using mcl::CurveParam; |
|
|
|
|
using mcl::getCurveParam; |
|
|
|
|
|
|
|
|
|
template<class Fp> |
|
|
|
|
struct MapToT { |
|
|
|
|
typedef mcl::Fp2T<Fp> Fp2; |
|
|
|
|
typedef mcl::EcT<Fp> G1; |
|
|
|
|
typedef mcl::EcT<Fp2> G2; |
|
|
|
|
typedef util::HaveFrobenius<G2> G2withF; |
|
|
|
|
mpz_class z_; |
|
|
|
|
/*
|
|
|
|
|
Q = (z(z-1)-1)P + Frob((z-1)P) + Frob^2(2P) |
|
|
|
|
*/ |
|
|
|
|
void mulByCofactor(G2& Q, const G2& P) const |
|
|
|
|
{ |
|
|
|
|
G2 T0, T1; |
|
|
|
|
G2::mulGeneric(T0, P, z_ - 1); |
|
|
|
|
G2::mulGeneric(T1, T0, z_); |
|
|
|
|
T1 -= P; |
|
|
|
|
G2withF::Frobenius(T0, T0); |
|
|
|
|
T0 += T1; |
|
|
|
|
G2::dbl(T1, P); |
|
|
|
|
G2withF::Frobenius2(T1, T1); |
|
|
|
|
G2::add(Q, T0, T1); |
|
|
|
|
} |
|
|
|
|
void init(const mpz_class& z) |
|
|
|
|
{ |
|
|
|
|
z_ = z; |
|
|
|
|
} |
|
|
|
|
template<class G, class F> |
|
|
|
|
void calc(G& P, const F& t) const |
|
|
|
|
{ |
|
|
|
|
F x = t; |
|
|
|
|
for (;;) { |
|
|
|
|
F y; |
|
|
|
|
G::getWeierstrass(y, x); |
|
|
|
|
if (F::squareRoot(y, y)) { |
|
|
|
|
P.set(x, y, false); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
*x.getFp0() += Fp::one(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void calcG1(G1& P, const Fp& t) const |
|
|
|
|
{ |
|
|
|
|
calc<G1, Fp>(P, t); |
|
|
|
|
assert(P.isValid()); |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
get the element in G2 by multiplying the cofactor |
|
|
|
|
*/ |
|
|
|
|
void calcG2(G2& P, const Fp2& t) const |
|
|
|
|
{ |
|
|
|
|
calc<G2, Fp2>(P, t); |
|
|
|
|
assert(cofactor_ != 0); |
|
|
|
|
mulByCofactor(P, P); |
|
|
|
|
assert(!P.isZero()); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template<class Fp> |
|
|
|
|
struct ParamT : public util::CommonParamT<Fp> { |
|
|
|
|
typedef util::CommonParamT<Fp> Common; |
|
|
|
|
typedef Fp2T<Fp> Fp2; |
|
|
|
|
typedef mcl::EcT<Fp> G1; |
|
|
|
|
typedef mcl::EcT<Fp2> G2; |
|
|
|
|
MapToT<Fp> mapTo; |
|
|
|
|
|
|
|
|
|
void init(const CurveParam& cp = CurveFp381, fp::Mode mode = fp::FP_AUTO) |
|
|
|
|
{ |
|
|
|
|
Common::initCommonParam(cp, mode, true); |
|
|
|
|
mapTo.init(this->z); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -107,6 +166,29 @@ struct BLS12T { |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
static void mapToG1(G1& P, const Fp& x) { param.mapTo.calcG1(P, x); } |
|
|
|
|
static void mapToG2(G2& P, const Fp2& x) { param.mapTo.calcG2(P, x); } |
|
|
|
|
static void hashAndMapToG1(G1& P, const void *buf, size_t bufSize) |
|
|
|
|
{ |
|
|
|
|
Fp t; |
|
|
|
|
t.setHashOf(buf, bufSize); |
|
|
|
|
mapToG1(P, t); |
|
|
|
|
} |
|
|
|
|
static void hashAndMapToG2(G2& P, const void *buf, size_t bufSize) |
|
|
|
|
{ |
|
|
|
|
Fp2 t; |
|
|
|
|
t.a.setHashOf(buf, bufSize); |
|
|
|
|
t.b.clear(); |
|
|
|
|
mapToG2(P, t); |
|
|
|
|
} |
|
|
|
|
static void hashAndMapToG1(G1& P, const std::string& str) |
|
|
|
|
{ |
|
|
|
|
hashAndMapToG1(P, str.c_str(), str.size()); |
|
|
|
|
} |
|
|
|
|
static void hashAndMapToG2(G2& P, const std::string& str) |
|
|
|
|
{ |
|
|
|
|
hashAndMapToG2(P, str.c_str(), str.size()); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template<class Fp> |
|
|
|
|