add wrapper for mcl_fp_mont

dev
MITSUNARI Shigeo 10 years ago
parent 218c039e61
commit 372119e1b1
  1. 20
      include/mcl/fp.hpp
  2. 13
      include/mcl/op.hpp
  3. 64
      src/fp.cpp

@ -37,12 +37,6 @@ bool strToMpzArray(size_t *pBitSize, Unit *y, size_t maxBitSize, mpz_class& x, c
void copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, bool doMask);
enum Mode {
FP_AUTO,
FP_LLVM,
FP_XBYAK
};
} // mcl::fp
template<class tag = fp::TagDefault, size_t maxBitSize = MCL_MAX_OP_BIT_SIZE>
@ -67,7 +61,6 @@ public:
}
static inline void setModulo(const std::string& mstr, int base = 0, fp::Mode mode = fp::FP_AUTO)
{
cybozu::disable_warning_unused_variable(mode);
assert(maxBitSize <= MCL_MAX_OP_BIT_SIZE);
assert(sizeof(mp_limb_t) == sizeof(Unit));
// set default wrapper function
@ -75,7 +68,13 @@ public:
op_.add = addW;
op_.sub = subW;
op_.mul = mulW;
op_.init(mstr, base, maxBitSize);
#ifdef MCL_USE_LLVM
// op_.useMont = !(mode == fp::FP_LLVM);
if (op_.useMont) {
op_.mul = montW;
}
#endif
op_.init(mstr, base, maxBitSize, mode);
}
static inline void getModulo(std::string& pstr)
{
@ -344,6 +343,11 @@ public:
{
op_.negP(y, x, op_.p);
}
// wrapper function for mcl_fp_mont by LLVM
static inline void montW(Unit *z, const Unit *x, const Unit *y)
{
op_.mont(z, x, y, op_.p, op_.rp);
}
};
template<class tag, size_t maxBitSize> fp::Op FpT<tag, maxBitSize>::op_;

@ -39,6 +39,13 @@ struct Block {
Unit v_[maxOpUnitSize];
};
enum Mode {
FP_AUTO,
FP_LLVM,
FP_LLVM_MONT,
FP_XBYAK
};
struct Op {
mpz_class mp;
mcl::SquareRoot sq;
@ -66,6 +73,9 @@ struct Op {
// for Montgomery
bool useMont;
int2u preInv;
// these two members are for mcl_fp_mont
Unit rp;
void (*mont)(Unit *z, const Unit *x, const Unit *y, const Unit *p, Unit rp);
// require p
void3u negP;
void2uOp invOp;
@ -79,6 +89,7 @@ struct Op {
, isZero(0), clear(0), copy(0)
, neg(0), add(0), sub(0), mul(0)
, useMont(false), preInv(0)
, rp(0), mont(0)
, negP(0), invOp(0), addP(0), subP(0), mulPreP(0), modP(0)
, fg(createFpGenerator())
{
@ -95,7 +106,7 @@ struct Op {
{
mul(y, x, RR);
}
void init(const std::string& mstr, int base, size_t maxBitSize);
void init(const std::string& mstr, int base, size_t maxBitSize, Mode mode);
static FpGenerator* createFpGenerator();
static void destroyFpGenerator(FpGenerator *fg);
private:

@ -168,7 +168,8 @@ struct OpeFunc {
#define SET_OP_LLVM(n) \
addP = mcl_fp_add ## n ##S; \
subP = mcl_fp_sub ## n ##S; \
mulPreP = mcl_fp_mulPre ## n;
mulPreP = mcl_fp_mulPre ## n; \
mont = mcl_fp_mont ## n;
#else
#define SET_OP_LLVM(n)
#endif
@ -184,7 +185,7 @@ struct OpeFunc {
subP = OpeFunc<n>::subC; \
mulPreP = OpeFunc<n>::mulPreC; \
modP = OpeFunc<n>::modC; \
SET_OP_LLVM(n)
SET_OP_LLVM(n)
#ifdef USE_MONT_FP
inline void invOpForMont(Unit *y, const Unit *x, const Op& op)
@ -239,52 +240,51 @@ static void initForMont(Op& op, const Unit *p)
}
#endif
void Op::init(const std::string& mstr, int base, size_t maxBitSize)
void Op::init(const std::string& mstr, int base, size_t maxBitSize, Mode mode)
{
bool isMinus = fp::strToMpzArray(&bitSize, p, maxBitSize, mp, mstr, base);
if (isMinus) throw cybozu::Exception("Op:init:mstr is minus") << mstr;
if (mp == 0) throw cybozu::Exception("Op:init:mstr is zero") << mstr;
if (bitSize <= 128) {
SET_OP(128)
} else
#if CYBOZU_OS_BIT == 32
if (bitSize <= 160) {
SET_OP(160)
} else
#endif
if (bitSize <= 192) {
SET_OP(192)
} else
#if CYBOZU_OS_BIT == 32
if (bitSize <= 224) {
SET_OP(224)
} else
const size_t roundBit = (bitSize + UnitBitSize - 1) & ~(UnitBitSize - 1);
#ifdef MCL_USE_LLVM
rp = getMontgomeryCoeff(p[0]);
#endif
if (bitSize <= 256) {
SET_OP(256)
} else
if (bitSize <= 384) {
SET_OP(384)
} else
switch (roundBit) {
case 32:
case 64:
case 96:
case 128: SET_OP(128); break;
case 192: SET_OP(192); break;
case 256: SET_OP(256); break;
case 320: SET_OP(320); break;
case 384: SET_OP(384); break;
case 448: SET_OP(448); break;
case 512: SET_OP(512); break;
#if CYBOZU_OS_BIT == 64
if (bitSize <= 576) {
SET_OP(576)
}
case 576: SET_OP(576); break;
#else
if (bitSize <= 544) {
SET_OP(544)
}
case 160: SET_OP(160); break;
case 224: SET_OP(224); break;
case 288: SET_OP(288); break;
case 352: SET_OP(352); break;
case 416: SET_OP(416); break;
case 480: SET_OP(480); break;
case 544: SET_OP(544); break;
#endif
default:
throw cybozu::Exception("Op::init:not:support") << mstr;
}
#ifdef MCL_USE_LLVM
if (mp == mpz_class("0xfffffffffffffffffffffffffffffffeffffffffffffffff")) {
mul = &mcl_fp_mul_NIST_P192; // slower than MontFp192
}
#endif
if (mode == FP_XBYAK) {
#ifdef USE_MONT_FP
fp::initForMont(*this, p);
fp::initForMont(*this, p);
#endif
}
sq.set(mp);
}

Loading…
Cancel
Save