add maptg2_wb19

update-fork
MITSUNARI Shigeo 5 years ago
parent ecbc4e403c
commit 8ec855f162
  1. 8
      include/mcl/bn.hpp
  2. 3
      include/mcl/curve_type.h
  3. 608
      include/mcl/mapto_wb19.hpp

@ -314,6 +314,8 @@ public:
} }
}; };
#include <mcl/mapto_wb19.hpp>
struct MapTo { struct MapTo {
enum { enum {
BNtype, BNtype,
@ -330,6 +332,7 @@ struct MapTo {
int type_; int type_;
int mapToMode_; int mapToMode_;
bool useOriginalG2cofactor_; bool useOriginalG2cofactor_;
MapToG2_WB19 maptog2_wb19_;
MapTo() MapTo()
: type_(0) : type_(0)
, mapToMode_(MCL_MAP_TO_MODE_ORIGINAL) , mapToMode_(MCL_MAP_TO_MODE_ORIGINAL)
@ -537,6 +540,11 @@ struct MapTo {
mapToMode_ = mode; mapToMode_ = mode;
return true; return true;
break; break;
case MCL_MAP_TO_MODE_WB19:
mapToMode_ = mode;
maptog2_wb19_.init();
return true;
break;
default: default:
return false; return false;
} }

@ -39,5 +39,6 @@ enum {
enum { enum {
MCL_MAP_TO_MODE_ORIGINAL, // see MapTo::calcBN MCL_MAP_TO_MODE_ORIGINAL, // see MapTo::calcBN
MCL_MAP_TO_MODE_TRY_AND_INC, // try-and-incremental-x MCL_MAP_TO_MODE_TRY_AND_INC, // try-and-incremental-x
MCL_MAP_TO_MODE_ETH2 // eth2.0 spec MCL_MAP_TO_MODE_ETH2, // eth2.0 spec
MCL_MAP_TO_MODE_WB19
}; };

@ -0,0 +1,608 @@
#pragma once
/**
@file
@brief map to G2 on BLS12-381 (must be included from mcl/bn.hpp)
@author MITSUNARI Shigeo(@herumi)
@license modified new BSD license
http://opensource.org/licenses/BSD-3-Clause
ref. https://eprint.iacr.org/2019/403 , https://github.com/algorand/bls_sigs_ref
*/
struct MapToG2_WB19 {
Fp2 xi;
Fp2 Ell2p_a;
Fp2 Ell2p_b;
Fp half;
mpz_class sqrtConst; // (p^2 - 9) / 16
Fp2 root4[4];
Fp2 etas[4];
Fp2 xnum[4];
Fp2 xden[3];
Fp2 ynum[4];
Fp2 yden[4];
struct Point {
Fp2 x, y, z;
bool isZero() const
{
return z.isZero();
}
};
// should be merged into ec.hpp
template<class G>
void neg(G& Q, const G& P) const
{
Q.x = P.x;
Fp2::neg(Q.y, P.y);
Q.z = P.z;
}
template<class G>
void add(G& R, const G& P, const G& Q) const
{
if (P.isZero()) {
R = Q;
return;
}
if (Q.isZero()) {
R = Q;
return;
}
Fp2 Z1Z1, Z2Z2, U1, U2, S1, S2;
Fp2::sqr(Z1Z1, P.z);
Fp2::sqr(Z2Z2, Q.z);
Fp2::mul(U1, P.x, Z2Z2);
Fp2::mul(U2, Q.x, Z1Z1);
Fp2::mul(S1, P.y, Q.z);
S1 *= Z2Z2;
Fp2::mul(S2, Q.y, P.z);
S2 *= Z1Z1;
if (U1 == U2 && S1 == S2) {
dbl(R, P);
return;
}
Fp2 H, I, J, rr, V;
Fp2::sub(H, U2, U1);
Fp2::add(I, H, H);
Fp2::sqr(I, I);
Fp2::mul(J, H, I);
Fp2::sub(rr, S2, S1);
rr += rr;
Fp2::mul(V, U1, I);
Fp2::mul(R.z, P.z, Q.z);
R.z *= H;
if (R.z.isZero()) {
R.x.clear();
R.y.clear();
return;
}
R.z += R.z;
Fp2::sqr(R.x, rr);
R.x -= J;
R.x -= V;
R.x -= V;
Fp2::sub(R.y, V, R.x);
R.y *= rr;
S1 *= J;
R.y -= S1;
R.y -= S1;
}
template<class G>
void dbl(G& Q, const G& P) const
{
Fp2 A, B, C, D, E, F;
Fp2::sqr(A, P.x);
Fp2::sqr(B, P.y);
Fp2::sqr(C, B);
Fp2::add(D, P.x, B);
Fp2::sqr(D, D);
D -= A;
D -= C;
D += D;
Fp2::add(E, A, A);
E += A;
Fp2::sqr(F, E);
Fp2::sub(Q.x, F, D);
Q.x -= D;
Fp2::mul(Q.z, P.y, P.z);
if (Q.z.isZero()) {
Q.x.clear();
Q.y.clear();
return;
}
Q.z += Q.z;
Fp2::sub(Q.y, D, Q.x);
Q.y *= E;
C += C;
C += C;
C += C;
Q.y -= C;
}
// P is on y^2 = x^3 + Ell2p_a x + Ell2p_b
bool isValidPoint(const Point& P) const
{
Fp2 y2, x2, z2, z4, t;
Fp2::sqr(x2, P.x);
Fp2::sqr(y2, P.y);
Fp2::sqr(z2, P.z);
Fp2::sqr(z4, z2);
Fp2::mul(t, z4, Ell2p_a);
t += x2;
t *= P.x;
z4 *= z2;
z4 *= Ell2p_b;
t += z4;
return y2 == t;
}
void init()
{
bool b;
xi.a = -2;
xi.b = -1;
Ell2p_a.a = 0;
Ell2p_a.b = 240;
Ell2p_b.a = 1012;
Ell2p_b.b = 1012;
half = -1;
half /= 2;
sqrtConst = Fp::getOp().mp;
sqrtConst *= sqrtConst;
sqrtConst -= 9;
sqrtConst /= 16;
const char *rv1Str = "0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09";
root4[0].a = 1;
root4[0].b.clear();
root4[1].a.clear();
root4[1].b = 1;
root4[2].a.setStr(&b, rv1Str);
assert(b); (void)b;
root4[2].b = root4[2].a;
root4[3].a = root4[2].a;
Fp::neg(root4[3].b, root4[3].a);
const char *ev1Str = "0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90";
const char *ev2Str = "0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5";
const char *ev3Str = "0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17";
const char *ev4Str = "0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1";
Fp& ev1 = etas[0].a;
Fp& ev2 = etas[0].b;
Fp& ev3 = etas[2].a;
Fp& ev4 = etas[2].b;
ev1.setStr(&b, ev1Str);
assert(b); (void)b;
ev2.setStr(&b, ev2Str);
assert(b); (void)b;
Fp::neg(etas[1].a, ev2);
etas[1].b = ev1;
ev3.setStr(&b, ev3Str);
assert(b); (void)b;
ev4.setStr(&b, ev4Str);
assert(b); (void)b;
Fp::neg(etas[3].a, ev4);
etas[3].b = ev3;
init_iso();
}
void init_iso()
{
const char *tbl[] = {
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6",
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a",
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e",
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d",
"0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f",
"0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706",
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be",
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c",
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f",
"0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99",
};
bool b;
xnum[0].a.setStr(&b, tbl[0]); assert(b); (void)b;
xnum[0].b = xnum[0].a;
xnum[1].a.clear();
xnum[1].b.setStr(&b, tbl[1]); assert(b); (void)b;
xnum[2].a.setStr(&b, tbl[2]); assert(b); (void)b;
xnum[2].b.setStr(&b, tbl[3]); assert(b); (void)b;
xnum[3].a.setStr(&b, tbl[4]); assert(b); (void)b;
xnum[3].b.clear();
xden[0].a.clear();
xden[0].b.setStr(&b, tbl[5]); assert(b); (void)b;
xden[1].a = 0xc;
xden[1].b.setStr(&b, tbl[6]); assert(b); (void)b;
xden[2].a = 1;
xden[2].b = 0;
ynum[0].a.setStr(&b, tbl[7]); assert(b); (void)b;
ynum[0].b = ynum[0].a;
ynum[1].a.clear();
ynum[1].b.setStr(&b, tbl[8]); assert(b); (void)b;
ynum[2].a.setStr(&b, tbl[9]); assert(b); (void)b;
ynum[2].b.setStr(&b, tbl[10]); assert(b); (void)b;
ynum[3].a.setStr(&b, tbl[11]); assert(b); (void)b;
ynum[3].b.clear();
yden[0].a.setStr(&b, tbl[12]); assert(b); (void)b;
yden[0].b = yden[0].a;
yden[1].a.clear();
yden[1].b.setStr(&b, tbl[13]); assert(b); (void)b;
yden[2].a = 0x12;
yden[2].b.setStr(&b, tbl[14]); assert(b); (void)b;
yden[3].a = 1;
yden[3].b.clear();
}
template<size_t N>
void evalPoly(Fp2& y, const Fp2& x, const Fp2 *zpows, const Fp2 (&cof)[N]) const
{
Fp2::mul(y, zpows[0], cof[N - 1]);
for (size_t i = 1; i < N; i++) {
y *= x;
Fp2 t;
Fp2::mul(t, zpows[i], cof[N - 1 - i]);
y += t;
}
}
// refer (xnum, xden, ynum, yden)
void iso3(G2& Q, const Point& P) const
{
Fp2 zpows[4];
zpows[0] = 1;
Fp2::sqr(zpows[1], P.z);
Fp2::sqr(zpows[2], zpows[1]);
Fp2::mul(zpows[3], zpows[2], zpows[1]);
Fp2 mapvals[4];
evalPoly(mapvals[0], P.x, zpows, xnum);
evalPoly(mapvals[1], P.x, zpows, xden);
evalPoly(mapvals[2], P.x, zpows, ynum);
evalPoly(mapvals[3], P.x, zpows, yden);
mapvals[1] *= zpows[1];
mapvals[2] *= P.y;
mapvals[3] *= zpows[1];
mapvals[3] *= P.z;
Fp2::mul(Q.z, mapvals[1], mapvals[3]);
Fp2::mul(Q.x, mapvals[0], mapvals[3]);
Q.x *= Q.z;
Fp2 t;
Fp2::sqr(t, Q.z);
Fp2::mul(Q.y, mapvals[2], mapvals[1]);
Q.y *= t;
}
/*
(a+bi)*(-2-i) = (b-2a)-(a+2b)i
*/
void mul_xi(Fp2& y, const Fp2& x) const
{
Fp t;
Fp::sub(t, x.b, x.a);
t -= x.a;
Fp::add(y.b, x.b, x.b);
y.b += x.a;
Fp::neg(y.b, y.b);
y.a = t;
}
bool isNegSign(const Fp2& x) const
{
if (x.b > half) return true;
if (!x.b.isZero()) return false;
if (x.a > half) return true;
if (!x.b.isZero()) return false;
return false;
}
void osswu2_help(Point& P, const Fp2& t) const
{
Fp2 t2, t2xi;
Fp2::sqr(t2, t);
Fp2 den, den2;
// Fp2::mul(t2xi, t2, xi);
mul_xi(t2xi, t2);
den = t2xi;
Fp2::sqr(den2, den);
// (t^2 * xi)^2 + (t^2 * xi)
den += den2;
Fp2 x0_num, x0_den;
Fp2::add(x0_num, den, 1);
x0_num *= Ell2p_b;
if (den.isZero()) {
Fp2::mul(x0_den, Ell2p_a, xi);
} else {
Fp2::mul(x0_den, -Ell2p_a, den);
}
Fp2 x0_den2, x0_den3, gx0_den, gx0_num;
Fp2::sqr(x0_den2, x0_den);
Fp2::mul(x0_den3, x0_den2, x0_den);
gx0_den = x0_den3;
Fp2::mul(gx0_num, Ell2p_b, gx0_den);
Fp2 tmp, tmp1, tmp2;
Fp2::mul(tmp, Ell2p_a, x0_num);
tmp *= x0_den2;
gx0_num += tmp;
Fp2::sqr(tmp, x0_num);
tmp *= x0_num;
gx0_num += tmp;
Fp2::sqr(tmp1, gx0_den); // x^2
Fp2::sqr(tmp2, tmp1); // x^4
tmp1 *= tmp2;
tmp1 *= gx0_den; // x^7
Fp2::mul(tmp2, gx0_num, tmp1);
tmp1 *= tmp2;
tmp1 *= gx0_den;
Fp2 candi;
Fp2::pow(candi, tmp1, sqrtConst);
candi *= tmp2;
bool isNegT = isNegSign(t);
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(root4); i++) {
Fp2::mul(P.y, candi, root4[i]);
Fp2::sqr(tmp, P.y);
tmp *= gx0_den;
if (tmp == gx0_num) {
if (isNegSign(P.y) != isNegT) {
Fp2::neg(P.y, P.y);
}
Fp2::mul(P.x, x0_num, x0_den);
P.y *= x0_den3;
P.z = x0_den;
return;
}
}
Fp2 x1_num, x1_den, gx1_num, gx1_den;
Fp2::mul(x1_num, t2xi, x0_num);
x1_den = x0_den;
Fp2::mul(gx1_num, den2, t2xi);
gx1_num *= gx0_num;
gx1_den = gx0_den;
candi *= t2;
candi *= t;
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(etas); i++) {
Fp2::mul(P.y, candi, etas[i]);
Fp2::sqr(tmp, P.y);
tmp *= gx1_den;
if (tmp == gx1_num) {
if (isNegSign(P.y) != isNegT) {
Fp2::neg(P.y, P.y);
}
Fp2::mul(P.x, x1_num, x1_den);
Fp2::sqr(tmp, x1_den);
P.y *= tmp;
P.y *= x1_den;
P.z = x1_den;
return;
}
}
assert(0);
}
void h2_chain(G2& t1, const G2& P) const
{
G2 t0, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15;
t0 = P;
dbl(t1, t0);
add(t4, t1, t0);
add(t2, t4, t1);
add(t3, t2, t1);
add(t11, t3, t1);
add(t9, t11, t1);
add(t10, t9, t1);
add(t5, t10, t1);
add(t7, t5, t1);
add(t15, t7, t1);
add(t13, t15, t1);
add(t6, t13, t1);
add(t14, t6, t1);
add(t12, t14, t1);
add(t8, t12, t1);
dbl(t1, t6);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t13);
for (size_t i = 0; i < 2; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 9; i++) dbl(t1, t1);
add(t1, t1, t8);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t11);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t13);
for (size_t i = 0; i < 8; i++) dbl(t1, t1);
add(t1, t1, t2);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 8; i++) dbl(t1, t1);
add(t1, t1, t11);
for (size_t i = 0; i < 8; i++) dbl(t1, t1);
add(t1, t1, t8);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t2);
for (size_t i = 0; i < 9; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t11);
for (size_t i = 0; i < 2; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 9; i++) dbl(t1, t1);
add(t1, t1, t8);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t13);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 11; i++) dbl(t1, t1);
add(t1, t1, t9);
for (size_t i = 0; i < 7; i++) dbl(t1, t1);
add(t1, t1, t12);
for (size_t i = 0; i < 7; i++) dbl(t1, t1);
add(t1, t1, t7);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t12);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t14);
for (size_t i = 0; i < 8; i++) dbl(t1, t1);
add(t1, t1, t13);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 8; i++) dbl(t1, t1);
add(t1, t1, t9);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t13);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t10);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t2);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t10);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t2);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 10; i++) dbl(t1, t1);
add(t1, t1, t9);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t14);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t9);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t15);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t8);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t12);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t15);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t2);
for (size_t i = 0; i < 7; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t9);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t15);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t14);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t8);
for (size_t i = 0; i < 10; i++) dbl(t1, t1);
add(t1, t1, t6);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 3; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 9; i++) dbl(t1, t1);
add(t1, t1, t13);
for (size_t i = 0; i < 7; i++) dbl(t1, t1);
add(t1, t1, t12);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t2);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t11);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t10);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t4);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t10);
for (size_t i = 0; i < 7; i++) dbl(t1, t1);
add(t1, t1, t7);
for (size_t i = 0; i < 3; i++) dbl(t1, t1);
add(t1, t1, t2);
for (size_t i = 0; i < 4; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 8; i++) dbl(t1, t1);
add(t1, t1, t9);
for (size_t i = 0; i < 8; i++) dbl(t1, t1);
add(t1, t1, t9);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t8);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t7);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t6);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t4);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t4);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t4);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t5);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 7; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t4);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 3; i++) dbl(t1, t1);
add(t1, t1, t0);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 6; i++) dbl(t1, t1);
add(t1, t1, t3);
for (size_t i = 0; i < 5; i++) dbl(t1, t1);
add(t1, t1, t2);
}
void mx_chain(G2& Q, const G2& P) const
{
G2 T;
dbl(T, P);
const size_t tbl[] = { 2, 3, 9, 32, 16 };
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
add(T, T, P);
for (size_t j = 0; j < tbl[i]; j++) {
dbl(T, T);
}
}
Q = T;
}
void clear_h2(G2& Q, const G2& P) const
{
#if 0
mcl::bn::BN::param.mapTo.mulByCofactorBLS12fast(Q, P);
#else
G2 work, work2;
h2_chain(work, P);
dbl(work2, work);
add(work2, work, work2);
mx_chain(work, work2);
mx_chain(work, work);
neg(work2, work2);
add(Q, work, work2);
#endif
}
void opt_swu2_map(G2& P, const Fp2& t, const Fp2 *t2 = 0) const
{
Point Pp;
osswu2_help(Pp, t);
if (t2) {
Point P2;
osswu2_help(P2, *t2);
add(Pp, Pp, P2);
}
iso3(P, Pp);
clear_h2(P, P);
}
};
Loading…
Cancel
Save