under refactoring

dev
MITSUNARI Shigeo 10 years ago
parent eb4d0b8dac
commit 3dac8a2663
  1. 39
      include/mcl/fp.hpp
  2. 104
      include/mcl/fp_util.hpp
  3. 2
      include/mcl/gmp_util.hpp
  4. 15
      include/mcl/op.hpp
  5. 59
      include/mcl/unit.hpp
  6. 60
      src/fp.cpp
  7. 2
      test/fp_generator_test.cpp

@ -23,7 +23,7 @@
#include <cybozu/itoa.hpp> #include <cybozu/itoa.hpp>
#include <cybozu/atoi.hpp> #include <cybozu/atoi.hpp>
#include <mcl/op.hpp> #include <mcl/op.hpp>
#include <mcl/fp_util.hpp> #include <mcl/unit.hpp>
#include <mcl/power.hpp> #include <mcl/power.hpp>
namespace mcl { namespace mcl {
@ -32,6 +32,10 @@ namespace fp {
struct TagDefault; struct TagDefault;
void arrayToStr(std::string& str, const Unit *x, size_t n, int base, bool withPrefix);
void strToGmp(mpz_class& x, bool *isMinus, const std::string& str, int base);
} // mcl::fp } // mcl::fp
template<class tag = fp::TagDefault, size_t maxBitN = MCL_MAX_OP_BIT_N> template<class tag = fp::TagDefault, size_t maxBitN = MCL_MAX_OP_BIT_N>
@ -58,7 +62,7 @@ public:
{ {
assert(maxBitN <= MCL_MAX_OP_BIT_N); assert(maxBitN <= MCL_MAX_OP_BIT_N);
bool isMinus; bool isMinus;
inFromStr(op_.mp, &isMinus, mstr, base); fp::strToGmp(op_.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;
const size_t bitLen = Gmp::getBitLen(op_.mp); const size_t bitLen = Gmp::getBitLen(op_.mp);
if (bitLen > maxBitN) throw cybozu::Exception("mcl:FpT:setModulo:too large bitLen") << bitLen << maxBitN; if (bitLen > maxBitN) throw cybozu::Exception("mcl:FpT:setModulo:too large bitLen") << bitLen << maxBitN;
@ -140,7 +144,7 @@ public:
{ {
bool isMinus; bool isMinus;
mpz_class x; mpz_class x;
inFromStr(x, &isMinus, str, base); fp::strToGmp(x, &isMinus, str, base);
if (x >= op_.mp) throw cybozu::Exception("fp:FpT:fromStr:large str") << str << op_.mp; if (x >= op_.mp) throw cybozu::Exception("fp:FpT:fromStr:large str") << str << op_.mp;
fp::toArray(v_, op_.N, x.get_mpz_t()); fp::toArray(v_, op_.N, x.get_mpz_t());
if (isMinus) { if (isMinus) {
@ -192,31 +196,11 @@ public:
fp::getRandVal(v_, rg, op_.p, op_.bitLen); 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)
{
switch (base) {
case 10:
{
mpz_class t;
Gmp::setRaw(t, x, n);
Gmp::toStr(str, t, 10);
}
return;
case 16:
mcl::fp::toStr16(str, x, n, withPrefix);
return;
case 2:
mcl::fp::toStr2(str, x, n, withPrefix);
return;
default:
throw cybozu::Exception("fp:FpT:toStr:bad base") << base;
}
}
void toStr(std::string& str, int base = 10, bool withPrefix = false) const void toStr(std::string& str, int base = 10, bool withPrefix = false) const
{ {
fp::Block b; fp::Block b;
getBlock(b); getBlock(b);
toStr(str, b.p, b.n, base, withPrefix); fp::arrayToStr(str, b.p, b.n, base, withPrefix);
} }
std::string toStr(int base = 10, bool withPrefix = false) const std::string toStr(int base = 10, bool withPrefix = false) const
{ {
@ -369,13 +353,6 @@ public:
op_.negP(y, x, op_.p); op_.negP(y, x, op_.p);
} }
private: private:
static inline void inFromStr(mpz_class& x, bool *isMinus, const std::string& str, int base)
{
const char *p = fp::verifyStr(isMinus, &base, str);
if (!Gmp::fromStr(x, p, base)) {
throw cybozu::Exception("fp:FpT:inFromStr") << str;
}
}
}; };
template<class tag, size_t maxBitN> fp::Op FpT<tag, maxBitN>::op_; template<class tag, size_t maxBitN> fp::Op FpT<tag, maxBitN>::op_;

@ -2,6 +2,7 @@
#include <vector> #include <vector>
#include <cybozu/itoa.hpp> #include <cybozu/itoa.hpp>
#include <cybozu/atoi.hpp> #include <cybozu/atoi.hpp>
#include <mcl/unit.hpp>
/** /**
@file @file
@brief utility of Fp @brief utility of Fp
@ -12,32 +13,6 @@
namespace mcl { namespace fp { namespace mcl { namespace fp {
#if defined(CYBOZU_OS_BIT) && (CYBOZU_OS_BIT == 32)
typedef uint32_t BlockType;
#else
typedef uint64_t BlockType;
#endif
template<class S>
void setBlockBit(S *buf, size_t bitLen, bool b)
{
const size_t unitSize = sizeof(S) * 8;
const size_t q = bitLen / unitSize;
const size_t r = bitLen % unitSize;
if (b) {
buf[q] |= S(1) << r;
} else {
buf[q] &= ~(S(1) << r);
}
}
template<class S>
bool getBlockBit(const S *buf, size_t bitLen)
{
const size_t unitSize = sizeof(S) * 8;
const size_t q = bitLen / unitSize;
const size_t r = bitLen % unitSize;
return (buf[q] & (S(1) << r)) != 0;
}
/* /*
convert x[0..n) to hex string convert x[0..n) to hex string
start "0x" if withPrefix start "0x" if withPrefix
@ -126,80 +101,5 @@ void fromStr16(T *x, size_t xn, const char *str, size_t strLen)
for (size_t i = requireSize; i < xn; i++) x[i] = 0; for (size_t i = requireSize; i < xn; i++) x[i] = 0;
} }
/*
@param base [inout]
*/
inline const char *verifyStr(bool *isMinus, int *base, const std::string& str)
{
const char *p = str.c_str();
if (*p == '-') {
*isMinus = true;
p++;
} else {
*isMinus = false;
}
if (p[0] == '0') {
if (p[1] == 'x') {
if (*base != 0 && *base != 16) {
throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
}
*base = 16;
p += 2;
} else if (p[1] == 'b') {
if (*base != 0 && *base != 2) {
throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
}
*base = 2;
p += 2;
}
}
if (*base == 0) *base = 10;
if (*p == '\0') throw cybozu::Exception("fp:verifyStr:str is empty");
return p;
}
template<class S>
size_t getRoundNum(size_t x)
{
const size_t size = sizeof(S) * 8;
return (x + size - 1) / size;
}
/*
compare x[0, n) with y[0, n)
*/
template<class S>
int compareArray(const S* x, const S* y, size_t n)
{
for (size_t i = 0; i < n; i++) {
const S a = x[n - 1 - i];
const S b = y[n - 1 - i];
if (a > b) return 1;
if (a < b) return -1;
}
return 0;
}
/*
get random value less than in[]
n = (bitLen + sizeof(S) * 8) / (sizeof(S) * 8)
input in[0..n)
output out[n..n)
0 <= out < in
*/
template<class RG, class S>
inline void getRandVal(S *out, RG& rg, const S *in, size_t bitLen)
{
const size_t unitBitSize = sizeof(S) * 8;
const size_t n = getRoundNum<S>(bitLen);
const size_t rem = bitLen & (unitBitSize - 1);
for (;;) {
rg.read(out, n);
if (rem > 0) out[n - 1] &= (S(1) << rem) - 1;
if (compareArray(out, in, n) < 0) return;
}
}
} // mcl::fp
} // fp } } // mcl::fp

@ -10,6 +10,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <vector> #include <vector>
#include <assert.h> #include <assert.h>
#include <cybozu/exception.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4616) #pragma warning(disable : 4616)
@ -51,7 +52,6 @@
#endif #endif
#endif #endif
#endif #endif
#include <mcl/operator.hpp>
namespace mcl { namespace mcl {

@ -7,21 +7,24 @@
http://opensource.org/licenses/BSD-3-Clause http://opensource.org/licenses/BSD-3-Clause
*/ */
#include <assert.h> #include <assert.h>
#include <cybozu/inttype.hpp> #include <mcl/gmp_util.hpp>
#include <mcl/unit.hpp>
#ifndef MCL_MAX_OP_BIT_N #ifndef MCL_MAX_OP_BIT_N
#define MCL_MAX_OP_BIT_N 521 #define MCL_MAX_OP_BIT_N 521
#endif #endif
namespace mcl { namespace mcl { namespace fp {
namespace fp { #if defined(CYBOZU_OS_BIT) && (CYBOZU_OS_BIT == 32)
typedef uint32_t Unit;
struct FpGenerator; #else
typedef uint64_t Unit;
#endif
const size_t UnitBitN = sizeof(Unit) * 8;
const size_t maxOpUnitN = (MCL_MAX_OP_BIT_N + UnitBitN - 1) / UnitBitN; const size_t maxOpUnitN = (MCL_MAX_OP_BIT_N + UnitBitN - 1) / UnitBitN;
struct FpGenerator;
struct Op; struct Op;
typedef void (*void1u)(Unit*); typedef void (*void1u)(Unit*);

@ -6,29 +6,22 @@
@license modified new BSD license @license modified new BSD license
http://opensource.org/licenses/BSD-3-Clause http://opensource.org/licenses/BSD-3-Clause
*/ */
#include <cybozu/inttype.hpp>
#include <mcl/gmp_util.hpp> #include <mcl/gmp_util.hpp>
namespace mcl { namespace fp { namespace mcl { namespace fp {
#if defined(CYBOZU_OS_BIT) && (CYBOZU_OS_BIT == 32)
typedef uint32_t Unit;
#else
typedef uint64_t Unit;
#endif
const size_t UnitBitN = sizeof(Unit) * 8;
/* /*
get pp such that p * pp = -1 mod M, get pp such that p * pp = -1 mod M,
where p is prime and M = 1 << 64(or 32). where p is prime and M = 1 << 64(or 32).
@param pLow [in] p mod M @param pLow [in] p mod M
*/ */
inline Unit getMontgomeryCoeff(Unit pLow) template<class T>
T getMontgomeryCoeff(T pLow)
{ {
Unit ret = 0; T ret = 0;
Unit t = 0; T t = 0;
Unit x = 1; T x = 1;
for (size_t i = 0; i < UnitBitN; i++) { for (size_t i = 0; i < sizeof(T) * 8; i++) {
if ((t & 1) == 0) { if ((t & 1) == 0) {
t += pLow; t += pLow;
ret += x; ret += x;
@ -39,7 +32,8 @@ inline Unit getMontgomeryCoeff(Unit pLow)
return ret; return ret;
} }
inline int compareArray(const Unit* x, const Unit* y, size_t n) template<class T>
int compareArray(const T* x, const T* y, size_t n)
{ {
for (size_t i = n - 1; i != size_t(-1); i--) { for (size_t i = n - 1; i != size_t(-1); i--) {
if (x[i] < y[i]) return -1; if (x[i] < y[i]) return -1;
@ -48,7 +42,8 @@ inline int compareArray(const Unit* x, const Unit* y, size_t n)
return 0; return 0;
} }
inline bool isEqualArray(const Unit* x, const Unit* y, size_t n) template<class T>
bool isEqualArray(const T* x, const T* y, size_t n)
{ {
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
if (x[i] != y[i]) return false; if (x[i] != y[i]) return false;
@ -56,7 +51,8 @@ inline bool isEqualArray(const Unit* x, const Unit* y, size_t n)
return true; return true;
} }
inline bool isZeroArray(const Unit *x, size_t n) template<class T>
bool isZeroArray(const T *x, size_t n)
{ {
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
if (x[i]) return false; if (x[i]) return false;
@ -64,25 +60,48 @@ inline bool isZeroArray(const Unit *x, size_t n)
return true; return true;
} }
inline void clearArray(Unit *x, size_t begin, size_t end) template<class T>
void clearArray(T *x, size_t begin, size_t end)
{ {
for (size_t i = begin; i < end; i++) x[i] = 0; for (size_t i = begin; i < end; i++) x[i] = 0;
} }
inline void copyArray(Unit *y, const Unit *x, size_t n) template<class T>
void copyArray(T *y, const T *x, size_t n)
{ {
for (size_t i = 0; i < n; i++) y[i] = x[i]; for (size_t i = 0; i < n; i++) y[i] = x[i];
} }
inline void toArray(Unit *y, size_t yn, const mpz_srcptr x) template<class T>
void toArray(T *y, size_t yn, const mpz_srcptr x)
{ {
const int xn = x->_mp_size; const int xn = x->_mp_size;
assert(xn >= 0); assert(xn >= 0);
const Unit* xp = (const Unit*)x->_mp_d; const T* xp = (const T*)x->_mp_d;
assert(xn <= (int)yn); assert(xn <= (int)yn);
copyArray(y, xp, xn); copyArray(y, xp, xn);
clearArray(y, xn, yn); clearArray(y, xn, yn);
} }
/*
get random value less than in[]
n = (bitLen + sizeof(T) * 8) / (sizeof(T) * 8)
input in[0..n)
output out[n..n)
0 <= out < in
*/
template<class RG, class T>
void getRandVal(T *out, RG& rg, const T *in, size_t bitLen)
{
const size_t TBitN = sizeof(T) * 8;
const size_t n = (bitLen + TBitN - 1) / TBitN;
const size_t rem = bitLen & (TBitN - 1);
for (;;) {
rg.read(out, n);
if (rem > 0) out[n - 1] &= (T(1) << rem) - 1;
if (compareArray(out, in, n) < 0) return;
}
}
} } // mcl::fp } } // mcl::fp

@ -1,4 +1,6 @@
#include <mcl/op.hpp> #include <mcl/op.hpp>
#include <mcl/unit.hpp>
#include <mcl/fp_util.hpp>
#ifdef USE_MONT_FP #ifdef USE_MONT_FP
#include <mcl/fp_generator.hpp> #include <mcl/fp_generator.hpp>
#endif #endif
@ -249,5 +251,63 @@ void Op::init(const Unit* p, size_t bitLen)
#endif #endif
} }
void arrayToStr(std::string& str, const Unit *x, size_t n, int base, bool withPrefix)
{
switch (base) {
case 10:
{
mpz_class t;
Gmp::setRaw(t, x, n);
Gmp::toStr(str, t, 10);
}
return;
case 16:
mcl::fp::toStr16(str, x, n, withPrefix);
return;
case 2:
mcl::fp::toStr2(str, x, n, withPrefix);
return;
default:
throw cybozu::Exception("fp:arrayToStr:bad base") << base;
}
}
inline const char *verifyStr(bool *isMinus, int *base, const std::string& str)
{
const char *p = str.c_str();
if (*p == '-') {
*isMinus = true;
p++;
} else {
*isMinus = false;
}
if (p[0] == '0') {
if (p[1] == 'x') {
if (*base != 0 && *base != 16) {
throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
}
*base = 16;
p += 2;
} else if (p[1] == 'b') {
if (*base != 0 && *base != 2) {
throw cybozu::Exception("fp:verifyStr:bad base") << *base << str;
}
*base = 2;
p += 2;
}
}
if (*base == 0) *base = 10;
if (*p == '\0') throw cybozu::Exception("fp:verifyStr:str is empty");
return p;
}
void strToGmp(mpz_class& x, bool *isMinus, const std::string& str, int base)
{
const char *p = fp::verifyStr(isMinus, &base, str);
if (!Gmp::fromStr(x, p, base)) {
throw cybozu::Exception("fp:FpT:inFromStr") << str;
}
}
} } // mcl::fp } } // mcl::fp

@ -6,8 +6,8 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <cybozu/itoa.hpp> #include <cybozu/itoa.hpp>
#include <mcl/fp_generator.hpp>
#include <mcl/fp.hpp> #include <mcl/fp.hpp>
#include <mcl/fp_generator.hpp>
#include <iostream> #include <iostream>
#include <cybozu/xorshift.hpp> #include <cybozu/xorshift.hpp>
#include <cybozu/benchmark.hpp> #include <cybozu/benchmark.hpp>

Loading…
Cancel
Save