add isOne and isNegative

dev
MITSUNARI Shigeo 9 years ago
parent 22a875af96
commit 240a177986
  1. 18
      include/mcl/fp.hpp
  2. 2
      include/mcl/op.hpp
  3. 32
      test/mont_fp_test.cpp

@ -106,6 +106,12 @@ public:
"\n", mode, op_.useMont);
#endif
op_.init(mstr, base, maxBitSize, mode);
{
FpT x = 1;
op_.copy(op_.oneRep, x.v_);
mpz_class half = (op_.mp - 1) / 2;
Gmp::getArray(op_.half, op_.N, half);
}
}
static inline void getModulo(std::string& pstr)
{
@ -299,6 +305,18 @@ public:
powerArray(z, x, Gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
}
bool isZero() const { return op_.isZero(v_); }
bool isOne() const { return fp::isEqualArray(v_, op_.oneRep, op_.N); }
/*
return true if p/2 < x < p
return false if 0 <= x <= p/2
note p/2 == (p-1)/2 because of p is odd
*/
bool isNegative() const
{
fp::Block b;
getBlock(b);
return fp::compareArray(b.p, op_.half, op_.N) > 0;
}
bool isValid() const
{
return fp::compareArray(v_, op_.p, op_.N) < 0;

@ -54,6 +54,8 @@ struct Op {
mpz_class mp;
mcl::SquareRoot sq;
Unit p[maxOpUnitSize];
Unit half[maxOpUnitSize]; // (p - 1) / 2
Unit oneRep[maxOpUnitSize]; // 1(=inv R if Montgomery)
/*
for Montgomery
one = 1

@ -365,6 +365,38 @@ struct Test {
CYBOZU_TEST_ASSERT(x != y);
}
}
{
Fp x(1);
CYBOZU_TEST_ASSERT(x.isOne());
x = 2;
CYBOZU_TEST_ASSERT(!x.isOne());
}
{
const struct {
int v;
bool expected;
} tbl[] = {
{ 0, false },
{ 1, false },
{ -1, true },
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
Fp x = tbl[i].v;
PUT(x);
CYBOZU_TEST_EQUAL(x.isNegative(), tbl[i].expected);
}
std::string str;
Fp::getModulo(str);
mpz_class half(str);
half = (half - 1) / 2;
Fp x;
x.setMpz(half - 1);
CYBOZU_TEST_ASSERT(!x.isNegative());
x.setMpz(half);
CYBOZU_TEST_ASSERT(!x.isNegative());
x.setMpz(half + 1);
CYBOZU_TEST_ASSERT(x.isNegative());
}
}
void modulo()

Loading…
Cancel
Save