rename op functions to fp_*

dev
MITSUNARI Shigeo 9 years ago
parent e43dfffb99
commit 38a4796d3b
  1. 72
      include/mcl/fp.hpp
  2. 51
      include/mcl/op.hpp
  3. 100
      src/fp.cpp

@ -74,11 +74,11 @@ public:
assert(maxBitSize <= MCL_MAX_OP_BIT_SIZE);
assert(sizeof(mp_limb_t) == sizeof(Unit));
// set default wrapper function
op_.neg = negW;
op_.sqr = sqrW;
op_.add = addW;
op_.sub = subW;
op_.mul = mulW;
op_.fp_neg = fp_negW;
op_.fp_sqr = fp_sqrW;
op_.fp_add = fp_addW;
op_.fp_sub = fp_subW;
op_.fp_mul = fp_mulW;
/*
priority : MCL_USE_XBYAK > MCL_USE_LLVM > none
Xbyak > llvm_opt > llvm > gmp
@ -97,8 +97,8 @@ public:
op_.useMont = mode == fp::FP_LLVM_MONT || mode == fp::FP_XBYAK;
if (mode == fp::FP_LLVM_MONT) {
op_.mul = montW;
op_.sqr = montSqrW;
op_.fp_mul = fp_montW;
op_.fp_sqr = fp_montSqrW;
}
#if 0
fprintf(stderr, "mode=%d, useMont=%d"
@ -116,7 +116,7 @@ public:
x.clear();
x.v_[0] = 1;
op_.toMont(x.v_, x.v_);
op_.copy(op_.oneRep, x.v_);
op_.fp_copy(op_.oneRep, x.v_);
}
{ // set half
mpz_class half = (op_.mp - 1) / 2;
@ -145,16 +145,16 @@ public:
FpT() {}
FpT(const FpT& x)
{
op_.copy(v_, x.v_);
op_.fp_copy(v_, x.v_);
}
FpT& operator=(const FpT& x)
{
op_.copy(v_, x.v_);
op_.fp_copy(v_, x.v_);
return *this;
}
void clear()
{
op_.clear(v_);
op_.fp_clear(v_);
}
FpT(int64_t x) { operator=(x); }
explicit FpT(const std::string& str, int base = 0)
@ -165,7 +165,7 @@ public:
{
clear();
if (x == 1) {
op_.copy(v_, op_.oneRep);
op_.fp_copy(v_, op_.oneRep);
} else if (x) {
int64_t y = x < 0 ? -x : x;
if (sizeof(Unit) == 8) {
@ -274,12 +274,12 @@ public:
{
setArray(Gmp::getUnit(x), Gmp::getUnitSize(x));
}
static inline void add(FpT& z, const FpT& x, const FpT& y) { op_.add(z.v_, x.v_, y.v_); }
static inline void sub(FpT& z, const FpT& x, const FpT& y) { op_.sub(z.v_, x.v_, y.v_); }
static inline void mul(FpT& z, const FpT& x, const FpT& y) { op_.mul(z.v_, x.v_, y.v_); }
static inline void inv(FpT& y, const FpT& x) { op_.invOp(y.v_, x.v_, op_); }
static inline void neg(FpT& y, const FpT& x) { op_.neg(y.v_, x.v_); }
static inline void sqr(FpT& y, const FpT& x) { op_.sqr(y.v_, x.v_); }
static inline void add(FpT& z, const FpT& x, const FpT& y) { op_.fp_add(z.v_, x.v_, y.v_); }
static inline void sub(FpT& z, const FpT& x, const FpT& y) { op_.fp_sub(z.v_, x.v_, y.v_); }
static inline void mul(FpT& z, const FpT& x, const FpT& y) { op_.fp_mul(z.v_, x.v_, y.v_); }
static inline void inv(FpT& y, const FpT& x) { op_.fp_invOp(y.v_, x.v_, op_); }
static inline void neg(FpT& y, const FpT& x) { op_.fp_neg(y.v_, x.v_); }
static inline void sqr(FpT& y, const FpT& x) { op_.fp_sqr(y.v_, x.v_); }
static inline void div(FpT& z, const FpT& x, const FpT& y)
{
FpT rev;
@ -302,7 +302,7 @@ public:
{
powerArray(z, x, Gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
}
bool isZero() const { return op_.isZero(v_); }
bool isZero() const { return op_.fp_isZero(v_); }
bool isOne() const { return fp::isEqualArray(v_, op_.oneRep, op_.N); }
/*
return true if p/2 < x < p
@ -416,40 +416,40 @@ private:
/*
wrapper function for generic p
add(z, x, y)
case 1: op_.add(z.v_, x.v_, y.v_) written by Xbyak with fixed p
case 2: addW(z.v_, x.v_, y.v_)
op_.addP(z, x, y, p) written by GMP/LLVM with generic p
case 1: op_.fp_add(z.v_, x.v_, y.v_) written by Xbyak with fixed p
case 2: fp_addW(z.v_, x.v_, y.v_)
op_.fp_addP(z, x, y, p) written by GMP/LLVM with generic p
*/
static inline void addW(Unit *z, const Unit *x, const Unit *y)
static inline void fp_addW(Unit *z, const Unit *x, const Unit *y)
{
op_.addP(z, x, y, op_.p);
op_.fp_addP(z, x, y, op_.p);
}
static inline void subW(Unit *z, const Unit *x, const Unit *y)
static inline void fp_subW(Unit *z, const Unit *x, const Unit *y)
{
op_.subP(z, x, y, op_.p);
op_.fp_subP(z, x, y, op_.p);
}
static inline void mulW(Unit *z, const Unit *x, const Unit *y)
static inline void fp_mulW(Unit *z, const Unit *x, const Unit *y)
{
Unit xy[maxSize * 2];
op_.mulPreP(xy, x, y);
op_.modP(z, xy, op_.p);
op_.fp_mulPreP(xy, x, y);
op_.fp_modP(z, xy, op_.p);
}
static inline void sqrW(Unit *y, const Unit *x)
static inline void fp_sqrW(Unit *y, const Unit *x)
{
Unit xx[maxSize * 2];
op_.sqrPreP(xx, x);
op_.modP(y, xx, op_.p);
op_.fp_sqrPreP(xx, x);
op_.fp_modP(y, xx, op_.p);
}
static inline void negW(Unit *y, const Unit *x)
static inline void fp_negW(Unit *y, const Unit *x)
{
op_.negP(y, x, op_.p);
op_.fp_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)
static inline void fp_montW(Unit *z, const Unit *x, const Unit *y)
{
op_.mont(z, x, y, op_.p, op_.rp);
}
static inline void montSqrW(Unit *y, const Unit *x)
static inline void fp_montSqrW(Unit *y, const Unit *x)
{
op_.mont(y, x, x, op_.p, op_.rp);
}

@ -70,37 +70,37 @@ struct Op {
size_t N;
size_t bitSize;
// independent from p
bool (*isZero)(const Unit*);
void1u clear;
void2u copy;
bool (*fp_isZero)(const Unit*);
void1u fp_clear;
void2u fp_copy;
// not require p(function having p)
void2u neg;
void2u sqr;
void3u add;
void3u sub;
void3u mul;
void2u fp_neg;
void2u fp_sqr;
void3u fp_add;
void3u fp_sub;
void3u fp_mul;
// for Montgomery
bool useMont;
int2u preInv;
int2u fp_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;
void2u sqrPreP;
void2uOp invOp;
void4u addP;
void4u subP;
void3u mulPreP;
void3u modP;
void3u fp_negP;
void2u fp_sqrPreP;
void2uOp fp_invOp;
void4u fp_addP;
void4u fp_subP;
void3u fp_mulPreP;
void3u fp_modP;
FpGenerator *fg;
Op()
: N(0), bitSize(0)
, isZero(0), clear(0), copy(0)
, neg(0), sqr(0), add(0), sub(0), mul(0)
, useMont(false), preInv(0)
, fp_isZero(0), fp_clear(0), fp_copy(0)
, fp_neg(0), fp_sqr(0), fp_add(0), fp_sub(0), fp_mul(0)
, useMont(false), fp_preInv(0)
, rp(0), mont(0)
, negP(0), sqrPreP(0), invOp(0), addP(0), subP(0), mulPreP(0), modP(0)
, fp_negP(0), fp_sqrPreP(0), fp_invOp(0), fp_addP(0), fp_subP(0), fp_mulPreP(0), fp_modP(0)
, fg(createFpGenerator())
{
}
@ -114,14 +114,14 @@ struct Op {
M(x, y) = xyR^-1
y = M(x, 1) = xR^-1
*/
mul(y, x, one);
fp_mul(y, x, one);
}
void toMont(Unit* y, const Unit *x) const
{
/*
y = M(x, R2) = xR^2 R^-1 = xR
*/
mul(y, x, R2);
fp_mul(y, x, R2);
}
void init(const std::string& mstr, int base, size_t maxBitSize, Mode mode);
static FpGenerator* createFpGenerator();
@ -136,14 +136,19 @@ private:
x = a + bu
*/
struct Op2 {
Op *op;
int xi_c; // xi = u + xi_c
void3u add;
void3u sub;
void3u mul;
void2u inv;
void2u neg;
void2u sqr;
void2u mul_xi;
Op2()
: op(0), xi_c(0), add(0), sub(0), mul(0), neg(0), sqr(0), mul_xi(0)
{
}
void init(Op *op, int xi_c);
};
} } // mcl::fp

@ -85,15 +85,15 @@ struct OpeFunc {
z->_mp_size = 0;
z->_mp_d = (mp_limb_t*)p;
}
static inline void clearC(Unit *x)
static inline void fp_clearC(Unit *x)
{
clearArray(x, 0, N);
}
static inline void copyC(Unit *y, const Unit *x)
static inline void fp_copyC(Unit *y, const Unit *x)
{
copyArray(y, x, N);
}
static inline void addC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
static inline void fp_addC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
{
Unit ret[N + 2]; // not N + 1
mpz_t mz, mx, my, mp;
@ -107,7 +107,7 @@ struct OpeFunc {
}
Gmp::getArray(z, N, mz);
}
static inline void subC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
static inline void fp_subC(Unit *z, const Unit *x, const Unit *y, const Unit *p)
{
Unit ret[N + 1];
mpz_t mz, mx, my;
@ -123,7 +123,7 @@ struct OpeFunc {
Gmp::getArray(z, N, mz);
}
// z[N * 2] <- x[N] * y[N]
static inline void mulPreC(Unit *z, const Unit *x, const Unit *y)
static inline void fp_mulPreC(Unit *z, const Unit *x, const Unit *y)
{
mpz_t mx, my, mz;
set_zero(mz, z, N * 2);
@ -133,7 +133,7 @@ struct OpeFunc {
clearArray(z, mz->_mp_size, N * 2);
}
// y[N * 2] <- x[N]^2
static inline void sqrPreC(Unit *y, const Unit *x)
static inline void fp_sqrPreC(Unit *y, const Unit *x)
{
mpz_t mx, my;
set_zero(my, y, N * 2);
@ -142,7 +142,7 @@ struct OpeFunc {
clearArray(y, my->_mp_size, N * 2);
}
// y[N] <- x[N * 2] mod p[N]
static inline void modC(Unit *y, const Unit *x, const Unit *p)
static inline void fp_modC(Unit *y, const Unit *x, const Unit *p)
{
mpz_t mx, my, mp;
set_mpz_t(mx, x, N * 2);
@ -151,7 +151,7 @@ struct OpeFunc {
mpz_mod(my, mx, mp);
clearArray(y, my->_mp_size, N);
}
static inline void invOp(Unit *y, const Unit *x, const Op& op)
static inline void fp_invOpC(Unit *y, const Unit *x, const Op& op)
{
mpz_class my;
mpz_t mx, mp;
@ -163,39 +163,33 @@ struct OpeFunc {
/*
inv(xR) = (1/x)R^-1 -toMont-> 1/x -toMont-> (1/x)R
*/
static void invMontOp(Unit *y, const Unit *x, const Op& op)
static void fp_invMontOpC(Unit *y, const Unit *x, const Op& op)
{
invOp(y, x, op);
op.mul(y, y, op.R3);
// op.toMont(y, y);
// op.toMont(y, y);
fp_invOpC(y, x, op);
op.fp_mul(y, y, op.R3);
}
static inline bool isZeroC(const Unit *x)
static inline bool fp_isZeroC(const Unit *x)
{
return isZeroArray(x, N);
}
static inline void negC(Unit *y, const Unit *x, const Unit *p)
static inline void fp_negC(Unit *y, const Unit *x, const Unit *p)
{
if (isZeroC(x)) {
if (x != y) clearC(y);
if (fp_isZeroC(x)) {
if (x != y) fp_clearC(y);
return;
}
subC(y, p, x, p);
}
static inline void sqrC(Unit *y, const Unit *x, const Unit *p)
{
sqrC(y, p, x, p);
fp_subC(y, p, x, p);
}
};
#ifdef MCL_USE_LLVM
#define SET_OP_LLVM(n) \
if (mode == FP_LLVM || mode == FP_LLVM_MONT) { \
addP = mcl_fp_add ## n ##S; \
subP = mcl_fp_sub ## n ##S; \
mulPreP = mcl_fp_mulPre ## n; \
fp_addP = mcl_fp_add ## n ##S; \
fp_subP = mcl_fp_sub ## n ##S; \
fp_mulPreP = mcl_fp_mulPre ## n; \
if (n <= 256) { \
sqrPreP = mcl_fp_sqrPre ## n; \
fp_sqrPreP = mcl_fp_sqrPre ## n; \
} \
mont = mcl_fp_mont ## n; \
}
@ -205,33 +199,33 @@ struct OpeFunc {
#define SET_OP(n) \
N = n / UnitBitSize; \
isZero = OpeFunc<n>::isZeroC; \
clear = OpeFunc<n>::clearC; \
copy = OpeFunc<n>::copyC; \
negP = OpeFunc<n>::negC; \
fp_isZero = OpeFunc<n>::fp_isZeroC; \
fp_clear = OpeFunc<n>::fp_clearC; \
fp_copy = OpeFunc<n>::fp_copyC; \
fp_negP = OpeFunc<n>::fp_negC; \
if (useMont) { \
invOp = OpeFunc<n>::invMontOp; \
fp_invOp = OpeFunc<n>::fp_invMontOpC; \
} else { \
invOp = OpeFunc<n>::invOp; \
fp_invOp = OpeFunc<n>::fp_invOpC; \
} \
addP = OpeFunc<n>::addC; \
subP = OpeFunc<n>::subC; \
mulPreP = OpeFunc<n>::mulPreC; \
sqrPreP = OpeFunc<n>::sqrPreC; \
modP = OpeFunc<n>::modC; \
fp_addP = OpeFunc<n>::fp_addC; \
fp_subP = OpeFunc<n>::fp_subC; \
fp_mulPreP = OpeFunc<n>::fp_mulPreC; \
fp_sqrPreP = OpeFunc<n>::fp_sqrPreC; \
fp_modP = OpeFunc<n>::fp_modC; \
SET_OP_LLVM(n)
#ifdef MCL_USE_XBYAK
inline void invOpForMont(Unit *y, const Unit *x, const Op& op)
inline void invOpForMontC(Unit *y, const Unit *x, const Op& op)
{
Unit r[maxOpUnitSize];
int k = op.preInv(r, x);
int k = op.fp_preInv(r, x);
/*
xr = 2^k
R = 2^(N * 64)
get r2^(-k)R^2 = r 2^(N * 64 * 2 - k)
*/
op.mul(y, r, op.invTbl.data() + k * op.N);
op.fp_mul(y, r, op.invTbl.data() + k * op.N);
}
static void initInvTbl(Op& op)
@ -244,7 +238,7 @@ static void initInvTbl(Op& op)
t[0] = 2;
op.toMont(tbl, t);
for (size_t i = 0; i < invTblN - 1; i++) {
op.add(tbl - N, tbl, tbl);
op.fp_add(tbl - N, tbl, tbl);
tbl -= N;
}
}
@ -270,14 +264,14 @@ static void initForMont(Op& op, const Unit *p, Mode mode)
if (fg == 0) return;
fg->init(p, (int)N);
op.neg = Xbyak::CastTo<void2u>(fg->neg_);
op.add = Xbyak::CastTo<void3u>(fg->add_);
op.sub = Xbyak::CastTo<void3u>(fg->sub_);
op.mul = Xbyak::CastTo<void3u>(fg->mul_);
op.sqr = Xbyak::CastTo<void2u>(fg->sqr_);
op.fp_neg = Xbyak::CastTo<void2u>(fg->neg_);
op.fp_add = Xbyak::CastTo<void3u>(fg->add_);
op.fp_sub = Xbyak::CastTo<void3u>(fg->sub_);
op.fp_mul = Xbyak::CastTo<void3u>(fg->mul_);
op.fp_sqr = Xbyak::CastTo<void2u>(fg->sqr_);
if (N <= 4) {
op.preInv = Xbyak::CastTo<int2u>(op.fg->preInv_);
op.invOp = &invOpForMont;
op.fp_preInv = Xbyak::CastTo<int2u>(op.fg->preInv_);
op.fp_invOp = &invOpForMontC;
initInvTbl(op);
}
@ -319,7 +313,7 @@ void Op::init(const std::string& mstr, int base, size_t maxBitSize, Mode mode)
}
#ifdef MCL_USE_LLVM
if (mode == FP_AUTO && mp == mpz_class("0xfffffffffffffffffffffffffffffffeffffffffffffffff")) {
mul = &mcl_fp_mul_NIST_P192;
fp_mul = &mcl_fp_mul_NIST_P192;
useMont = false;
}
#endif
@ -329,6 +323,12 @@ void Op::init(const std::string& mstr, int base, size_t maxBitSize, Mode mode)
sq.set(mp);
}
void Op2::init(Op *op, int xi_c)
{
if (op->N * UnitBitSize != 256) throw cybozu::Exception("Op2:init:not support size") << op->N;
this->op = op;
}
void arrayToStr(std::string& str, const Unit *x, size_t n, int base, bool withPrefix)
{
switch (base) {
@ -402,7 +402,7 @@ int64_t getInt64(bool *pb, fp::Block& b, const fp::Op& op)
{
bool isNegative = false;
if (fp::isGreaterArray(b.p, op.half, op.N)) {
op.neg(b.v_, b.p);
op.fp_neg(b.v_, b.p);
b.p = b.v_;
isNegative = true;
}

Loading…
Cancel
Save