refactor mulCT

update-fork
MITSUNARI Shigeo 5 years ago
parent d51fd79c86
commit 2ede71f70c
  1. 26
      include/mcl/bn.hpp
  2. 87
      include/mcl/ec.hpp
  3. 10
      include/mcl/operator.hpp
  4. 15
      test/common_test.hpp

@ -802,18 +802,26 @@ struct GLV2 {
}
}
template<class T>
void mul(T& Q, const T& P, mpz_class x, bool constTime = false) const
void mul(T& Q, const T& P, const mpz_class& x, bool constTime = false) const
{
(void)constTime;
mulVecNGLV(Q, &P, &x, 1);
mulVecNGLV(Q, &P, &x, 1, constTime);
}
template<class T>
size_t mulVecNGLV(T& z, const T *xVec, const mpz_class *yVec, size_t n) const
static void mulLambda(T& Q, const T& P)
{
Frobenius(Q, P);
}
template<class T>
size_t mulVecNGLV(T& z, const T *xVec, const mpz_class *yVec, size_t n, bool constTime) const
{
if (n == 1 && constTime) {
ec::local::mul1CT<GLV2<_Fr>, T, Fr, 4, 4>(*this, z, *xVec, *yVec);
return 1;
}
const mpz_class& r = Fr::getOp().mp;
const size_t N = mcl::fp::maxMulVecNGLV;
if (n > N) n = N;
const int w = 5;
const int w = 4;
const size_t tblSize = 1 << (w - 2);
const int splitN = 4;
NafArray naf[N][splitN];
@ -1060,17 +1068,17 @@ inline void powArrayGLV2(Fp12& z, const Fp12& x, const mcl::fp::Unit *y, size_t
BN::param.glv2.pow(z, x, s, constTime);
}
inline size_t mulVecNGLV2(G2& z, const G2 *xVec, const mpz_class *yVec, size_t n)
inline size_t mulVecNGLV2(G2& z, const G2 *xVec, const mpz_class *yVec, size_t n, bool constTime)
{
return BN::param.glv2.mulVecNGLV(z, xVec, yVec, n);
return BN::param.glv2.mulVecNGLV(z, xVec, yVec, n, constTime);
}
inline size_t powVecNGLV2(Fp12& z, const Fp12 *xVec, const mpz_class *yVec, size_t n)
inline size_t powVecNGLV2(Fp12& z, const Fp12 *xVec, const mpz_class *yVec, size_t n, bool constTime)
{
typedef GroupMtoA<Fp12> AG; // as additive group
AG& _z = static_cast<AG&>(z);
const AG *_xVec = static_cast<const AG*>(xVec);
return BN::param.glv2.mulVecNGLV(_z, _xVec, yVec, n);
return BN::param.glv2.mulVecNGLV(_z, _xVec, yVec, n, constTime);
}
/*

@ -9,6 +9,7 @@
#include <stdlib.h>
#include <mcl/fp.hpp>
#include <mcl/ecparam.hpp>
#include <mcl/window_method.hpp>
#ifdef _MSC_VER
#pragma warning(push)
@ -71,6 +72,76 @@ bool get_a_flag(const mcl::Fp2T<F>& x)
return get_a_flag(x.b); // x = a + bi
}
template<class GLV, class G, class F, int splitN, size_t w>
void mul1CT(const GLV& glv, G& Q, const G& P, const mpz_class& x)
{
const mpz_class& r = F::getOp().mp;
const size_t tblSize = 1 << w;
G tbl[splitN][tblSize];
bool negTbl[splitN];
mpz_class u[splitN];
mpz_class y = x % r;
if (y < 0) {
y += r;
}
glv.split(u, y);
for (int i = 0; i < splitN; i++) {
if (u[i] < 0) {
gmp::neg(u[i], u[i]);
negTbl[i] = true;
} else {
negTbl[i] = false;
}
tbl[i][0].clear();
}
tbl[0][1] = P;
for (size_t j = 2; j < tblSize; j++) {
G::add(tbl[0][j], tbl[0][j - 1], P);
}
for (int i = 1; i < splitN; i++) {
for (size_t j = 1; j < tblSize; j++) {
GLV::mulLambda(tbl[i][j], tbl[i - 1][j]);
}
}
for (int i = 0; i < splitN; i++) {
if (negTbl[i]) {
for (size_t j = 0; j < tblSize; j++) {
G::neg(tbl[i][j], tbl[i][j]);
}
}
}
mcl::FixedArray<int8_t, sizeof(F) * 8 / w + 1> vTbl[splitN];
size_t bitSizeTbl[splitN];
size_t maxBitSize = 0;
for (size_t i = 0; i < splitN; i++) {
size_t bitSize = gmp::getBitSize(u[i]);
bitSizeTbl[i] = bitSize;
if (bitSize > maxBitSize) {
maxBitSize = bitSize;
}
}
int loopN = (maxBitSize + w - 1) / w;
for (int i = 0; i < splitN; i++) {
fp::ArrayIterator<fp::Unit> itr(gmp::getUnit(u[i]), bitSizeTbl[i], w);
bool b = vTbl[i].resize(loopN);
assert(b);
(void)b;
for (int j = 0; j < loopN; j++) {
vTbl[i][loopN - 1 - j] = itr.getNext();
}
}
Q.clear();
for (int k = 0; k < loopN; k++) {
for (size_t i = 0; i < w; i++) {
G::dbl(Q, Q);
}
for (size_t i = 0; i < splitN; i++) {
uint8_t v = vTbl[i][k];
G::add(Q, Q, tbl[i][v]);
}
}
}
} // mcl::ec::local
template<class E>
@ -567,7 +638,7 @@ public:
static bool verifyOrder_;
static mpz_class order_;
static void (*mulArrayGLV)(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime);
static size_t (*mulVecNGLV)(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t yn);
static size_t (*mulVecNGLV)(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t yn, bool constTime);
/* default constructor is undefined value */
EcT() {}
EcT(const Fp& _x, const Fp& _y)
@ -633,7 +704,7 @@ public:
// don't clear order_ because it is used for isValidOrder()
}
}
static void setMulArrayGLV(void f(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime), size_t g(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t yn) = 0)
static void setMulArrayGLV(void f(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime), size_t g(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t yn, bool constTime) = 0)
{
mulArrayGLV = f;
mulVecNGLV = g;
@ -1342,7 +1413,7 @@ private:
public:
template<class tag, size_t maxBitSize, template<class _tag, size_t _maxBitSize>class FpT>
static inline void mulVec(EcT& z, const EcT *xVec, const FpT<tag, maxBitSize> *yVec, size_t n)
static inline void mulVec(EcT& z, const EcT *xVec, const FpT<tag, maxBitSize> *yVec, size_t n, bool constTime = false)
{
/*
mulVecNGLV is a little slow for large n
@ -1354,7 +1425,7 @@ public:
yVec[i].getMpz(&b, myVec[i]);
assert(b); (void)b;
}
size_t done = mulVecNGLV(z, xVec, myVec, n);
size_t done = mulVecNGLV(z, xVec, myVec, n, constTime);
assert(done == n); (void)done;
return;
}
@ -1424,7 +1495,7 @@ template<class Fp> int EcT<Fp>::ioMode_;
template<class Fp> bool EcT<Fp>::verifyOrder_;
template<class Fp> mpz_class EcT<Fp>::order_;
template<class Fp> void (*EcT<Fp>::mulArrayGLV)(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime);
template<class Fp> size_t (*EcT<Fp>::mulVecNGLV)(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t yn);
template<class Fp> size_t (*EcT<Fp>::mulVecNGLV)(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t yn, bool constTime);
template<class Fp> int EcT<Fp>::mode_;
// r = the order of Ec
@ -1471,11 +1542,11 @@ public:
a = x - (t * B[0][0] + b * B[1][0]);
b = - (t * B[0][1] + b * B[1][1]);
}
static void mul(Ec& Q, const Ec& P, const mpz_class& x, bool /*constTime*/ = false)
static void mul(Ec& Q, const Ec& P, const mpz_class& x, bool constTime = false)
{
mulVecNGLV(Q, &P, &x, 1);
mulVecNGLV(Q, &P, &x, 1, constTime);
}
static inline size_t mulVecNGLV(Ec& z, const Ec *xVec, const mpz_class *yVec, size_t n)
static inline size_t mulVecNGLV(Ec& z, const Ec *xVec, const mpz_class *yVec, size_t n, bool /*constTime*/ = false)
{
const size_t N = mcl::fp::maxMulVecNGLV;
if (n > N) n = N;

@ -84,14 +84,14 @@ struct Operator : public E {
{
powArray(z, x, gmp::getUnit(y), gmp::getUnitSize(y), y < 0, true);
}
static void setPowArrayGLV(void f(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime), size_t g(T& z, const T *xVec, const mpz_class *yVec, size_t n) = 0)
static void setPowArrayGLV(void f(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime), size_t g(T& z, const T *xVec, const mpz_class *yVec, size_t n, bool constTime) = 0)
{
powArrayGLV = f;
powVecNGLV = g;
}
static const size_t powVecMaxN = 16;
template<class tag, size_t maxBitSize, template<class _tag, size_t _maxBitSize>class FpT>
static void powVec(T& z, const T* xVec, const FpT<tag, maxBitSize> *yVec, size_t n)
static void powVec(T& z, const T* xVec, const FpT<tag, maxBitSize> *yVec, size_t n, bool constTime = false)
{
assert(powVecNGLV);
T r;
@ -106,7 +106,7 @@ struct Operator : public E {
yVec[i].getMpz(&b, myVec[i]);
assert(b); (void)b;
}
size_t done = powVecNGLV(t, xVec, myVec, tn);
size_t done = powVecNGLV(t, xVec, myVec, tn, constTime);
r *= t;
xVec += done;
yVec += done;
@ -116,7 +116,7 @@ struct Operator : public E {
}
private:
static void (*powArrayGLV)(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime);
static size_t (*powVecNGLV)(T& z, const T* xVec, const mpz_class *yVec, size_t n);
static size_t (*powVecNGLV)(T& z, const T* xVec, const mpz_class *yVec, size_t n, bool constTime);
static void powArray(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime)
{
if (powArrayGLV && (constTime || yn > 1)) {
@ -145,7 +145,7 @@ template<class T, class E>
void (*Operator<T, E>::powArrayGLV)(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime);
template<class T, class E>
size_t (*Operator<T, E>::powVecNGLV)(T& z, const T* xVec, const mpz_class *yVec, size_t n);
size_t (*Operator<T, E>::powVecNGLV)(T& z, const T* xVec, const mpz_class *yVec, size_t n, bool constTime);
/*
T must have save and load

@ -89,12 +89,27 @@ inline void testPowVec(const G& e)
}
}
template<class G>
void testMulCT(const G& P)
{
cybozu::XorShift rg;
G Q1, Q2;
for (int i = 0; i < 100; i++) {
Fr x;
x.setByCSPRNG(rg);
G::mul(Q1, P, x);
G::mulCT(Q2, P, x);
CYBOZU_TEST_EQUAL(Q1, Q2);
}
}
void testCommon(const G1& P, const G2& Q)
{
puts("G1");
testMulVec(P);
puts("G2");
testMulVec(Q);
testMulCT(Q);
GT e;
mcl::bn::pairing(e, P, Q);
puts("GT");

Loading…
Cancel
Save