|
|
@ -35,7 +35,7 @@ namespace mcl { |
|
|
|
|
|
|
|
|
|
|
|
namespace fp { |
|
|
|
namespace fp { |
|
|
|
|
|
|
|
|
|
|
|
void setOp(mcl::fp::Op& op, const Unit* p, size_t pBitLen); |
|
|
|
void setOp(mcl::fp::Op& op, const Unit* p, size_t bitLen); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Block { |
|
|
|
struct Block { |
|
|
@ -55,8 +55,6 @@ class FpT { |
|
|
|
static const size_t UnitByteN = sizeof(Unit); |
|
|
|
static const size_t UnitByteN = sizeof(Unit); |
|
|
|
static const size_t maxUnitN = (maxBitN + UnitByteN * 8 - 1) / (UnitByteN * 8); |
|
|
|
static const size_t maxUnitN = (maxBitN + UnitByteN * 8 - 1) / (UnitByteN * 8); |
|
|
|
static fp::Op op_; |
|
|
|
static fp::Op op_; |
|
|
|
static mcl::SquareRoot sq_; |
|
|
|
|
|
|
|
static size_t pBitLen_; |
|
|
|
|
|
|
|
template<class tag2, size_t maxBitN2> friend class FpT; |
|
|
|
template<class tag2, size_t maxBitN2> friend class FpT; |
|
|
|
Unit v_[maxUnitN]; |
|
|
|
Unit v_[maxUnitN]; |
|
|
|
public: |
|
|
|
public: |
|
|
@ -78,53 +76,54 @@ public: |
|
|
|
mpz_class mp; |
|
|
|
mpz_class mp; |
|
|
|
inFromStr(mp, &isMinus, mstr, base); |
|
|
|
inFromStr(mp, &isMinus, mstr, base); |
|
|
|
if (isMinus) throw cybozu::Exception("mcl:FpT:setModulo:mstr is not minus") << mstr; |
|
|
|
if (isMinus) throw cybozu::Exception("mcl:FpT:setModulo:mstr is not minus") << mstr; |
|
|
|
pBitLen_ = Gmp::getBitLen(mp); |
|
|
|
const size_t bitLen = Gmp::getBitLen(mp); |
|
|
|
if (pBitLen_ > maxBitN) throw cybozu::Exception("mcl:FpT:setModulo:too large bitLen") << pBitLen_ << maxBitN; |
|
|
|
if (bitLen > maxBitN) throw cybozu::Exception("mcl:FpT:setModulo:too large bitLen") << bitLen << maxBitN; |
|
|
|
Unit p[maxUnitN] = {}; |
|
|
|
Unit p[maxUnitN] = {}; |
|
|
|
const size_t n = Gmp::getRaw(p, maxUnitN, mp); |
|
|
|
const size_t n = Gmp::getRaw(p, maxUnitN, mp); |
|
|
|
if (n == 0) throw cybozu::Exception("mcl:FpT:setModulo:bad mstr") << mstr; |
|
|
|
if (n == 0) throw cybozu::Exception("mcl:FpT:setModulo:bad mstr") << mstr; |
|
|
|
mcl::fp::setOp(op_, p, pBitLen_); |
|
|
|
mcl::fp::setOp(op_, p, bitLen); |
|
|
|
#if 1 |
|
|
|
#if 1 |
|
|
|
#ifdef USE_MONT_FP |
|
|
|
#ifdef USE_MONT_FP |
|
|
|
if (pBitLen_ <= 128) { op_ = fp::MontFp<tag, 128>::init(p); } |
|
|
|
if (bitLen <= 128) { op_ = fp::MontFp<tag, 128>::init(p); } |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
else if (pBitLen_ <= 160) { static fp::MontFp<tag, 160> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 160) { static fp::MontFp<tag, 160> f; op_ = f.init(p); } |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
else if (pBitLen_ <= 192) { static fp::MontFp<tag, 192> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 192) { static fp::MontFp<tag, 192> f; op_ = f.init(p); } |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
else if (pBitLen_ <= 224) { static fp::MontFp<tag, 224> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 224) { static fp::MontFp<tag, 224> f; op_ = f.init(p); } |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
else if (pBitLen_ <= 256) { static fp::MontFp<tag, 256> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 256) { static fp::MontFp<tag, 256> f; op_ = f.init(p); } |
|
|
|
else if (pBitLen_ <= 384) { static fp::MontFp<tag, 384> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 384) { static fp::MontFp<tag, 384> f; op_ = f.init(p); } |
|
|
|
else if (pBitLen_ <= 448) { static fp::MontFp<tag, 448> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 448) { static fp::MontFp<tag, 448> f; op_ = f.init(p); } |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
else if (pBitLen_ <= 544) { static fp::MontFp<tag, 544> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 544) { static fp::MontFp<tag, 544> f; op_ = f.init(p); } |
|
|
|
#else |
|
|
|
#else |
|
|
|
else if (pBitLen_ <= 576) { static fp::MontFp<tag, 576> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 576) { static fp::MontFp<tag, 576> f; op_ = f.init(p); } |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
else { static fp::MontFp<tag, maxBitN> f; op_ = f.init(p); } |
|
|
|
else { static fp::MontFp<tag, maxBitN> f; op_ = f.init(p); } |
|
|
|
#else |
|
|
|
#else |
|
|
|
if (pBitLen_ <= 128) { op_ = fp::FixedFp<tag, 128>::init(p); } |
|
|
|
if (bitLen <= 128) { op_ = fp::FixedFp<tag, 128>::init(p); } |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
else if (pBitLen_ <= 160) { static fp::FixedFp<tag, 160> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 160) { static fp::FixedFp<tag, 160> f; op_ = f.init(p); } |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
else if (pBitLen_ <= 192) { static fp::FixedFp<tag, 192> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 192) { static fp::FixedFp<tag, 192> f; op_ = f.init(p); } |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
else if (pBitLen_ <= 224) { static fp::FixedFp<tag, 224> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 224) { static fp::FixedFp<tag, 224> f; op_ = f.init(p); } |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
else if (pBitLen_ <= 256) { static fp::FixedFp<tag, 256> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 256) { static fp::FixedFp<tag, 256> f; op_ = f.init(p); } |
|
|
|
else if (pBitLen_ <= 384) { static fp::FixedFp<tag, 384> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 384) { static fp::FixedFp<tag, 384> f; op_ = f.init(p); } |
|
|
|
else if (pBitLen_ <= 448) { static fp::FixedFp<tag, 448> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 448) { static fp::FixedFp<tag, 448> f; op_ = f.init(p); } |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
#if CYBOZU_OS_BIT == 32 |
|
|
|
else if (pBitLen_ <= 544) { static fp::FixedFp<tag, 544> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 544) { static fp::FixedFp<tag, 544> f; op_ = f.init(p); } |
|
|
|
#else |
|
|
|
#else |
|
|
|
else if (pBitLen_ <= 576) { static fp::FixedFp<tag, 576> f; op_ = f.init(p); } |
|
|
|
else if (bitLen <= 576) { static fp::FixedFp<tag, 576> f; op_ = f.init(p); } |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
else { static fp::FixedFp<tag, maxBitN> f; op_ = f.init(p); } |
|
|
|
else { static fp::FixedFp<tag, maxBitN> f; op_ = f.init(p); } |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
assert(op_.N <= maxUnitN); |
|
|
|
assert(op_.N <= maxUnitN); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
sq_.set(mp); |
|
|
|
op_.bitLen = bitLen; |
|
|
|
|
|
|
|
op_.sq.set(mp); |
|
|
|
} |
|
|
|
} |
|
|
|
static inline void getModulo(std::string& pstr) |
|
|
|
static inline void getModulo(std::string& pstr) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -140,7 +139,7 @@ public: |
|
|
|
{ |
|
|
|
{ |
|
|
|
mpz_class mx, my; |
|
|
|
mpz_class mx, my; |
|
|
|
x.toGmp(mx); |
|
|
|
x.toGmp(mx); |
|
|
|
bool b = sq_.get(my, mx); |
|
|
|
bool b = op_.sq.get(my, mx); |
|
|
|
if (!b) return false; |
|
|
|
if (!b) return false; |
|
|
|
y.fromGmp(my); |
|
|
|
y.fromGmp(my); |
|
|
|
return true; |
|
|
|
return true; |
|
|
@ -242,7 +241,7 @@ public: |
|
|
|
template<class RG> |
|
|
|
template<class RG> |
|
|
|
void setRand(RG& rg) |
|
|
|
void setRand(RG& rg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
fp::getRandVal(v_, rg, op_.p, pBitLen_); |
|
|
|
fp::getRandVal(v_, rg, op_.p, op_.bitLen); |
|
|
|
fromMont(*this, *this); |
|
|
|
fromMont(*this, *this); |
|
|
|
} |
|
|
|
} |
|
|
|
static inline void toStr(std::string& str, const Unit *x, size_t n, int base = 10, bool withPrefix = false) |
|
|
|
static inline void toStr(std::string& str, const Unit *x, size_t n, int base = 10, bool withPrefix = false) |
|
|
@ -352,7 +351,7 @@ public: |
|
|
|
{ |
|
|
|
{ |
|
|
|
fp::Block b; |
|
|
|
fp::Block b; |
|
|
|
getBlock(b); |
|
|
|
getBlock(b); |
|
|
|
bv.append(b.p, pBitLen_); |
|
|
|
bv.append(b.p, op_.bitLen); |
|
|
|
} |
|
|
|
} |
|
|
|
bool isValid() const |
|
|
|
bool isValid() const |
|
|
|
{ |
|
|
|
{ |
|
|
@ -360,11 +359,11 @@ public: |
|
|
|
} |
|
|
|
} |
|
|
|
void fromBitVec(const cybozu::BitVector& bv) |
|
|
|
void fromBitVec(const cybozu::BitVector& bv) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (bv.size() != pBitLen_) throw cybozu::Exception("FpT:fromBitVec:bad size") << bv.size() << pBitLen_; |
|
|
|
if (bv.size() != op_.bitLen) throw cybozu::Exception("FpT:fromBitVec:bad size") << bv.size() << op_.bitLen; |
|
|
|
setRaw(bv.getBlock(), bv.getBlockSize()); |
|
|
|
setRaw(bv.getBlock(), bv.getBlockSize()); |
|
|
|
} |
|
|
|
} |
|
|
|
static inline size_t getModBitLen() { return pBitLen_; } |
|
|
|
static inline size_t getModBitLen() { return op_.bitLen; } |
|
|
|
static inline size_t getBitVecSize() { return pBitLen_; } |
|
|
|
static inline size_t getBitVecSize() { return op_.bitLen; } |
|
|
|
bool operator==(const FpT& rhs) const { return fp::local::isEqualArray(v_, rhs.v_, op_.N); } |
|
|
|
bool operator==(const FpT& rhs) const { return fp::local::isEqualArray(v_, rhs.v_, op_.N); } |
|
|
|
bool operator!=(const FpT& rhs) const { return !operator==(rhs); } |
|
|
|
bool operator!=(const FpT& rhs) const { return !operator==(rhs); } |
|
|
|
inline friend FpT operator+(const FpT& x, const FpT& y) { FpT z; add(z, x, y); return z; } |
|
|
|
inline friend FpT operator+(const FpT& x, const FpT& y) { FpT z; add(z, x, y); return z; } |
|
|
@ -422,8 +421,6 @@ private: |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template<class tag, size_t maxBitN> fp::Op FpT<tag, maxBitN>::op_; |
|
|
|
template<class tag, size_t maxBitN> fp::Op FpT<tag, maxBitN>::op_; |
|
|
|
template<class tag, size_t maxBitN> mcl::SquareRoot FpT<tag, maxBitN>::sq_; |
|
|
|
|
|
|
|
template<class tag, size_t maxBitN> size_t FpT<tag, maxBitN>::pBitLen_; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace power_impl { |
|
|
|
namespace power_impl { |
|
|
|
|
|
|
|
|
|
|
|