dev
MITSUNARI Shigeo 10 years ago
parent 685d67fa0a
commit f519ccc1f8
  1. 62
      include/mcl/fp_base.hpp
  2. 150
      src/fp.cpp
  3. 4
      test/mont_fp_test.cpp

@ -129,24 +129,6 @@ inline void toArray(Unit *y, size_t yn, const mpz_srcptr x)
clearArray(y, xn, yn);
}
inline void set_mpz_t(mpz_t& z, const Unit* p, int n)
{
z->_mp_alloc = n;
int i = n;
while (i > 0 && p[i - 1] == 0) {
i--;
}
z->_mp_size = i;
z->_mp_d = (mp_limb_t*)const_cast<Unit*>(p);
}
inline void set_zero(mpz_t& z, Unit *p, size_t n)
{
z->_mp_alloc = (int)n;
z->_mp_size = 0;
z->_mp_d = (mp_limb_t*)p;
}
} // mcl::fp::local
struct TagDefault;
@ -200,37 +182,17 @@ struct MontFp {
static const size_t N = (bitN + sizeof(Unit) * 8 - 1) / (sizeof(Unit) * 8);
static const size_t invTblN = N * sizeof(Unit) * 8 * 2;
static mpz_class mp_;
// static mcl::SquareRoot sq_;
static Unit p_[N];
static Unit one_[N];
static Unit R_[N]; // (1 << (N * 64)) % p
static Unit RR_[N]; // (R * R) % p
static Unit invTbl_[invTblN][N];
static size_t modBitLen_;
static FpGenerator fg_;
static void3op add_;
static void3op mul_;
static inline void fromRawGmp(Unit *y, const mpz_class& x)
static inline void fromRawGmp(Unit *y, size_t n, const mpz_class& x)
{
local::toArray(y, N, x.get_mpz_t());
}
static inline void setModulo(const Unit *p)
{
copy(p_, p);
Gmp::setRaw(mp_, p, N);
// sq_.set(pOrg_);
mpz_class t = 1;
fromRawGmp(one_, t);
t = (t << (N * 64)) % mp_;
fromRawGmp(R_, t);
t = (t * t) % mp_;
fromRawGmp(RR_, t);
fg_.init(p_, N);
add_ = Xbyak::CastTo<void3op>(fg_.add_);
mul_ = Xbyak::CastTo<void3op>(fg_.mul_);
local::toArray(y, n, x.get_mpz_t());
}
static void initInvTbl(Unit invTbl[invTblN][N])
{
@ -281,8 +243,18 @@ struct MontFp {
}
static inline void init(Op& op, const Unit *p)
{
puts("use MontFp2");
setModulo(p);
copy(p_, p);
Gmp::setRaw(mp_, p, N);
mpz_class t = 1;
fromRawGmp(one_, N, t);
t = (t << (N * 64)) % mp_;
t = (t * t) % mp_;
fromRawGmp(RR_, N, t);
fg_.init(p_, N);
add_ = Xbyak::CastTo<void3op>(fg_.add_);
mul_ = Xbyak::CastTo<void3op>(fg_.mul_);
op.N = N;
op.isZero = &isZero;
op.clear = &clear;
@ -297,24 +269,18 @@ puts("use MontFp2");
op.sub = Xbyak::CastTo<void3op>(fg_.sub_);
op.mul = mul_;
op.mp = mp_;
// op.p = &p_[0];
copy(op.p, p_);
op.toMont = &toMont;
op.fromMont = &fromMont;
// shr1 = Xbyak::CastTo<void2op>(fg_.shr1_);
// addNc = Xbyak::CastTo<bool3op>(fg_.addNc_);
// subNc = Xbyak::CastTo<bool3op>(fg_.subNc_);
initInvTbl(invTbl_);
}
};
template<class tag, size_t bitN> mpz_class MontFp<tag, bitN>::mp_;
template<class tag, size_t bitN> fp::Unit MontFp<tag, bitN>::p_[MontFp<tag, bitN>::N];
template<class tag, size_t bitN> fp::Unit MontFp<tag, bitN>::one_[MontFp<tag, bitN>::N];
template<class tag, size_t bitN> fp::Unit MontFp<tag, bitN>::R_[MontFp<tag, bitN>::N];
template<class tag, size_t bitN> fp::Unit MontFp<tag, bitN>::RR_[MontFp<tag, bitN>::N];
template<class tag, size_t bitN> fp::Unit MontFp<tag, bitN>::invTbl_[MontFp<tag, bitN>::invTblN][MontFp<tag, bitN>::N];
template<class tag, size_t bitN> size_t MontFp<tag, bitN>::modBitLen_;
template<class tag, size_t bitN> FpGenerator MontFp<tag, bitN>::fg_;
template<class tag, size_t bitN> void3op MontFp<tag, bitN>::add_;
template<class tag, size_t bitN> void3op MontFp<tag, bitN>::mul_;

@ -145,152 +145,62 @@ struct OpeFunc {
}
};
#ifdef MCL_USE_LLVM
#define SET_OP_LLVM(n) \
op.addG = mcl_fp_add ## n ##S; \
op.subG = mcl_fp_sub ## n ##S; \
op.mulPreG = mcl_fp_mulPre ## n;
#else
#define SET_OP_LLVM(n)
#endif
#define SET_OP(n) \
op.N = n / UnitBitN; \
op.isZero = OpeFunc<n>::isZeroC; \
op.clear = OpeFunc<n>::clearC; \
op.copy = OpeFunc<n>::copyC; \
op.negG = OpeFunc<n>::negC; \
op.invG = OpeFunc<n>::invC; \
op.addG = OpeFunc<n>::addC; \
op.subG = OpeFunc<n>::subC; \
op.mulPreG = OpeFunc<n>::mulPreC; \
op.modG = OpeFunc<n>::modC; \
SET_OP_LLVM(n)
void initOpByLLVM(Op& op, const Unit* /*p*/, size_t bitLen)
{
assert(sizeof(mp_limb_t) == sizeof(Unit));
const size_t UnitBitN = sizeof(Unit) * 8;
if (bitLen <= 128) {
op.N = 128 / UnitBitN;
op.isZero = OpeFunc<128>::isZeroC;
op.clear = OpeFunc<128>::clearC;
op.copy = OpeFunc<128>::copyC;
op.negG = OpeFunc<128>::negC;
op.invG = OpeFunc<128>::invC;
op.addG = OpeFunc<128>::addC;
op.subG = OpeFunc<128>::subC;
op.mulPreG = OpeFunc<128>::mulPreC;
op.modG = OpeFunc<128>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add128S;
op.subG = mcl_fp_sub128S;
op.mulPreG = mcl_fp_mulPre128;
#endif
SET_OP(128)
} else
#if CYBOZU_OS_BIT == 32
if (bitLen <= 160) {
op.N = 160 / UnitBitN;
op.isZero = OpeFunc<160>::isZeroC;
op.clear = OpeFunc<160>::clearC;
op.copy = OpeFunc<160>::copyC;
op.negG = OpeFunc<160>::negC;
op.invG = OpeFunc<160>::invC;
op.addG = OpeFunc<160>::addC;
op.subG = OpeFunc<160>::subC;
op.mulPreG = OpeFunc<160>::mulPreC;
op.modG = OpeFunc<160>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add160S;
op.subG = mcl_fp_sub160S;
op.mulPreG = mcl_fp_mulPre160;
#endif
SET_OP(160)
} else
#endif
if (bitLen <= 192) {
op.N = 192 / UnitBitN;
op.isZero = OpeFunc<192>::isZeroC;
op.clear = OpeFunc<192>::clearC;
op.copy = OpeFunc<192>::copyC;
op.negG = OpeFunc<192>::negC;
op.invG = OpeFunc<192>::invC;
op.addG = OpeFunc<192>::addC;
op.subG = OpeFunc<192>::subC;
op.mulPreG = OpeFunc<192>::mulPreC;
op.modG = OpeFunc<192>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add192S;
op.subG = mcl_fp_sub192S;
op.mulPreG = mcl_fp_mulPre192;
#endif
SET_OP(192)
} else
#if CYBOZU_OS_BIT == 32
if (bitLen <= 224) {
op.N = 224 / UnitBitN;
op.isZero = OpeFunc<224>::isZeroC;
op.clear = OpeFunc<224>::clearC;
op.copy = OpeFunc<224>::copyC;
op.negG = OpeFunc<224>::negC;
op.invG = OpeFunc<224>::invC;
op.addG = OpeFunc<224>::addC;
op.subG = OpeFunc<224>::subC;
op.mulPreG = OpeFunc<224>::mulPreC;
op.modG = OpeFunc<224>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add224S;
op.subG = mcl_fp_sub224S;
op.mulPreG = mcl_fp_mulPre224;
#endif
SET_OP(224)
} else
#endif
if (bitLen <= 256) {
op.N = 256 / UnitBitN;
op.isZero = OpeFunc<256>::isZeroC;
op.clear = OpeFunc<256>::clearC;
op.copy = OpeFunc<256>::copyC;
op.negG = OpeFunc<256>::negC;
op.invG = OpeFunc<256>::invC;
op.addG = OpeFunc<256>::addC;
op.subG = OpeFunc<256>::subC;
op.mulPreG = OpeFunc<256>::mulPreC;
op.modG = OpeFunc<256>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add256S;
op.subG = mcl_fp_sub256S;
op.mulPreG = mcl_fp_mulPre256;
#endif
SET_OP(256)
} else
if (bitLen <= 384) {
op.N = 384 / UnitBitN;
op.isZero = OpeFunc<384>::isZeroC;
op.clear = OpeFunc<384>::clearC;
op.copy = OpeFunc<384>::copyC;
op.negG = OpeFunc<384>::negC;
op.invG = OpeFunc<384>::invC;
op.addG = OpeFunc<384>::addC;
op.subG = OpeFunc<384>::subC;
op.mulPreG = OpeFunc<384>::mulPreC;
op.modG = OpeFunc<384>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add384S;
op.subG = mcl_fp_sub384S;
op.mulPreG = mcl_fp_mulPre384;
#endif
SET_OP(384)
} else
#if CYBOZU_OS_BIT == 64
if (bitLen <= 576) {
op.N = 576 / UnitBitN;
op.isZero = OpeFunc<576>::isZeroC;
op.clear = OpeFunc<576>::clearC;
op.copy = OpeFunc<576>::copyC;
op.negG = OpeFunc<576>::negC;
op.invG = OpeFunc<576>::invC;
op.addG = OpeFunc<576>::addC;
op.subG = OpeFunc<576>::subC;
op.mulPreG = OpeFunc<576>::mulPreC;
op.modG = OpeFunc<576>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add576S;
op.subG = mcl_fp_sub576S;
op.mulPreG = mcl_fp_mulPre576;
#endif
SET_OP(576)
}
#else
if (bitLen <= 544) {
op.N = 544 / UnitBitN;
op.isZero = OpeFunc<544>::isZeroC;
op.clear = OpeFunc<544>::clearC;
op.copy = OpeFunc<544>::copyC;
op.negG = OpeFunc<544>::negC;
op.invG = OpeFunc<544>::invC;
op.addG = OpeFunc<544>::addC;
op.subG = OpeFunc<544>::subC;
op.mulPreG = OpeFunc<544>::mulPreC;
op.modG = OpeFunc<544>::modC;
#ifdef MCL_USE_LLVM
op.addG = mcl_fp_add544S;
op.subG = mcl_fp_sub544S;
op.mulPreG = mcl_fp_mulPre544;
#endif
SET_OP(544)
}
#endif

@ -3,7 +3,9 @@
#include <cybozu/benchmark.hpp>
#include <time.h>
#define USE_MONT_FP
#ifndef USE_MONT_FP
#define USE_MONT_FP
#endif
#include <mcl/fp.hpp>
typedef mcl::FpT<> Zn;
typedef mcl::FpT<> MontFp3;

Loading…
Cancel
Save