aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2016-09-19 16:23:57 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2016-09-19 16:23:57 +0800
commit8730a3c7319db10ef75d19109f69d0b29ba52a5c (patch)
tree6d993c7ec6adf5e24c0b2fb952567ea8cd1f954c
parent9ad3a356288786f65fa239fd22923fc5986bb857 (diff)
downloadtangerine-mcl-8730a3c7319db10ef75d19109f69d0b29ba52a5c.tar.gz
tangerine-mcl-8730a3c7319db10ef75d19109f69d0b29ba52a5c.tar.zst
tangerine-mcl-8730a3c7319db10ef75d19109f69d0b29ba52a5c.zip
move mont_fp_test to fp_test
-rw-r--r--test/fp_test.cpp268
-rw-r--r--test/mont_fp_test.cpp500
2 files changed, 248 insertions, 520 deletions
diff --git a/test/fp_test.cpp b/test/fp_test.cpp
index 66087dc..d9d4fda 100644
--- a/test/fp_test.cpp
+++ b/test/fp_test.cpp
@@ -13,10 +13,8 @@
typedef mcl::FpT<> Fp;
-void cstrTest(mcl::fp::Mode mode)
+void cstrTest()
{
- const int m = 65537;
- Fp::init(mpz_class(m), mode);
const struct {
const char *str;
int val;
@@ -26,9 +24,6 @@ void cstrTest(mcl::fp::Mode mode)
{ "123", 123 },
{ "0x123", 0x123 },
{ "0b10101", 21 },
- { "-123", m - 123 },
- { "-0x123", m - 0x123 },
- { "-0b10101", m - 21 },
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
// string cstr
@@ -61,6 +56,19 @@ void cstrTest(mcl::fp::Mode mode)
x.getStr(str);
CYBOZU_TEST_EQUAL(str, os.str());
}
+ const struct {
+ const char *str;
+ int val;
+ } tbl2[] = {
+ { "-123", 123 },
+ { "-0x123", 0x123 },
+ { "-0b10101", 21 },
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl2); i++) {
+ Fp x(tbl2[i].str);
+ x = -x;
+ CYBOZU_TEST_EQUAL(x, tbl2[i].val);
+ }
}
void setStrTest()
@@ -134,11 +142,107 @@ void streamTest()
}
}
+void ioModeTest()
+{
+ Fp x(123);
+ const struct {
+ mcl::IoMode ioMode;
+ std::string expected;
+ } tbl[] = {
+ { mcl::IoBin, "1111011" },
+ { mcl::IoDec, "123" },
+ { mcl::IoHex, "7b" },
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ Fp::setIoMode(tbl[i].ioMode);
+ for (int j = 0; j < 2; j++) {
+ std::stringstream ss;
+ if (j == 1) {
+ ss << std::hex;
+ }
+ ss << x;
+ CYBOZU_TEST_EQUAL(ss.str(), tbl[i].expected);
+ Fp y;
+ y.clear();
+ ss >> y;
+ CYBOZU_TEST_EQUAL(x, y);
+ }
+ }
+ for (int i = 0; i < 2; i++) {
+ if (i == 0) {
+ Fp::setIoMode(mcl::IoArray);
+ } else {
+ Fp::setIoMode(mcl::IoArrayRaw);
+ }
+ std::stringstream ss;
+ ss << x;
+ CYBOZU_TEST_EQUAL(ss.str().size(), Fp::getBitSize() / 8);
+ Fp y;
+ ss >> y;
+ CYBOZU_TEST_EQUAL(x, y);
+ }
+ Fp::setIoMode(mcl::IoAuto);
+}
+
+void edgeTest()
+{
+ const mpz_class& m = Fp::getOp().mp;
+ /*
+ real mont
+ 0 0
+ 1 R^-1
+ R 1
+ -1 -R^-1
+ -R -1
+ */
+ mpz_class t = 1;
+ const size_t N = Fp::getUnitSize();
+ const mpz_class R = (t << (N * mcl::fp::UnitBitSize)) % m;
+ const mpz_class tbl[] = {
+ 0, 1, R, m - 1, m - R
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ const mpz_class& x = tbl[i];
+ for (size_t j = i; j < CYBOZU_NUM_OF_ARRAY(tbl); j++) {
+ const mpz_class& y = tbl[j];
+ mpz_class z = (x * y) % m;
+ Fp xx, yy;
+ xx.setMpz(x);
+ yy.setMpz(y);
+ Fp zz = xx * yy;
+ mpz_class t;
+ zz.getMpz(t);
+ CYBOZU_TEST_EQUAL(z, t);
+ }
+ }
+ t = m;
+ t /= 2;
+ Fp x;
+ x.setMpz(t);
+ CYBOZU_TEST_EQUAL(x * 2, -1);
+ t += 1;
+ x.setMpz(t);
+ CYBOZU_TEST_EQUAL(x * 2, 1);
+}
+
void convTest()
{
+#if 1
+ const char *bin, *hex, *dec;
+ if (Fp::getBitSize() <= 117) {
+ bin = "0b1000000000000000000000000000000000000000000000000000000000001110";
+ hex = "0x800000000000000e";
+ dec = "9223372036854775822";
+ } else {
+ bin = "0b100100011010001010110011110001001000000010010001101000101011001111000100100000001001000110100010101100111100010010000";
+ hex = "0x123456789012345678901234567890";
+ dec = "94522879687365475552814062743484560";
+ }
+#else
const char *bin = "0b1001000110100";
const char *hex = "0x1234";
const char *dec = "4660";
+#endif
Fp b(bin);
Fp h(hex);
Fp d(dec);
@@ -191,6 +295,37 @@ void compareTest()
CYBOZU_TEST_ASSERT(x == 5);
CYBOZU_TEST_ASSERT(x > 2);
}
+ {
+ 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;
+ 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 moduloTest(const char *pStr)
@@ -200,10 +335,8 @@ void moduloTest(const char *pStr)
CYBOZU_TEST_EQUAL(str, mpz_class(pStr).get_str());
}
-void opeTest(mcl::fp::Mode mode)
+void opeTest()
{
- const int m = 65537;
- Fp::init(mpz_class(m), mode);
const struct {
int x;
int y;
@@ -212,11 +345,11 @@ void opeTest(mcl::fp::Mode mode)
int mul; // x * y
int sqr; // x^2
} tbl[] = {
- { 0, 1, 1, m - 1, 0, 0 },
+ { 0, 1, 1, -1, 0, 0 },
{ 9, 5, 14, 4, 45, 81 },
- { 10, 13, 23, m - 3, 130, 100 },
- { 2000, 1000, 3000, 1000, (2000 * 1000) % m, (2000 * 2000) % m },
- { 12345, 9999, 12345 + 9999, 12345 - 9999, (12345 * 9999) % m, (12345 * 12345) % m },
+ { 10, 13, 23, -3, 130, 100 },
+ { 2000, 1000, 3000, 1000, 2000 * 1000, 2000 * 2000 },
+ { 12345, 9999, 12345 + 9999, 12345 - 9999, 12345 * 9999, 12345 * 12345 },
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
const Fp x(tbl[i].x);
@@ -247,11 +380,19 @@ void opeTest(mcl::fp::Mode mode)
z *= y;
CYBOZU_TEST_EQUAL(z, tbl[i].x);
}
- Fp x(5), y(3), z;
- Fp::addNC(z, x, y);
- CYBOZU_TEST_EQUAL(z, Fp(8));
- Fp::subNC(z, x, y);
- CYBOZU_TEST_EQUAL(z, Fp(2));
+ {
+ Fp x(5), y(3), z;
+ Fp::addNC(z, x, y);
+ if (Fp::compareRaw(z, Fp::getP()) >= 0) {
+ Fp::subNC(z, z, Fp::getP());
+ }
+ CYBOZU_TEST_EQUAL(z, Fp(8));
+ if (Fp::compareRaw(x, y) < 0) {
+ Fp::addNC(x, x, Fp::getP());
+ }
+ Fp::subNC(x, x, y);
+ CYBOZU_TEST_EQUAL(x, Fp(2));
+ }
}
struct tag2;
@@ -266,6 +407,11 @@ void powTest()
CYBOZU_TEST_EQUAL(y, z);
z *= x;
}
+ x = z;
+ Fp::pow(z, x, Fp::getOp().mp - 1);
+ CYBOZU_TEST_EQUAL(z, 1);
+ Fp::pow(z, x, Fp::getOp().mp);
+ CYBOZU_TEST_EQUAL(z, x);
typedef mcl::FpT<tag2, 128> Fp_other;
Fp_other::init("1009");
x = 5;
@@ -278,6 +424,16 @@ void powTest()
CYBOZU_TEST_EQUAL(x, 125);
}
+void mul_UnitTest()
+{
+ Fp x(-1), y, z;
+ for (unsigned int u = 0; u < 20; u++) {
+ Fp::mul(y, x, u);
+ Fp::mul_Unit(z, x, u);
+ CYBOZU_TEST_EQUAL(y, z);
+ }
+}
+
void powNegTest()
{
Fp x, y, z;
@@ -303,6 +459,18 @@ void powFpTest()
}
}
+void powGmp()
+{
+ Fp x, y, z;
+ x = 12345;
+ z = 1;
+ for (int i = 0; i < 100; i++) {
+ Fp::pow(y, x, mpz_class(i));
+ CYBOZU_TEST_EQUAL(y, z);
+ z *= x;
+ }
+}
+
struct TagAnother;
void anotherFpTest(mcl::fp::Mode mode)
@@ -451,8 +619,63 @@ void getInt64Test()
}
}
+void divBy2Test()
+{
+ const int tbl[] = { -4, -3, -2, -1, 0, 1, 2, 3 };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ Fp x(tbl[i]), y;
+ Fp::divBy2(y, x);
+ y *= 2;
+ CYBOZU_TEST_EQUAL(y, x);
+ y = x;
+ Fp::divBy2(y, y);
+ y *= 2;
+ CYBOZU_TEST_EQUAL(y, x);
+ }
+}
+
void getStrTest()
{
+ Fp x(0);
+ std::string str;
+ str = x.getStr();
+ CYBOZU_TEST_EQUAL(str, "0");
+ str = x.getStr(mcl::IoBinPrefix);
+ CYBOZU_TEST_EQUAL(str, "0b0");
+ str = x.getStr(mcl::IoBin);
+ CYBOZU_TEST_EQUAL(str, "0");
+ str = x.getStr(mcl::IoHexPrefix);
+ CYBOZU_TEST_EQUAL(str, "0x0");
+ str = x.getStr(mcl::IoHex);
+ CYBOZU_TEST_EQUAL(str, "0");
+
+ x = 123;
+ str = x.getStr();
+ CYBOZU_TEST_EQUAL(str, "123");
+ str = x.getStr(mcl::IoBinPrefix);
+ CYBOZU_TEST_EQUAL(str, "0b1111011");
+ str = x.getStr(mcl::IoBin);
+ CYBOZU_TEST_EQUAL(str, "1111011");
+ str = x.getStr(mcl::IoHexPrefix);
+ CYBOZU_TEST_EQUAL(str, "0x7b");
+ str = x.getStr(mcl::IoHex);
+ CYBOZU_TEST_EQUAL(str, "7b");
+
+ {
+ std::ostringstream os;
+ os << x;
+ CYBOZU_TEST_EQUAL(os.str(), "123");
+ }
+ {
+ std::ostringstream os;
+ os << std::hex << std::showbase << x;
+ CYBOZU_TEST_EQUAL(os.str(), "0x7b");
+ }
+ {
+ std::ostringstream os;
+ os << std::hex << x;
+ CYBOZU_TEST_EQUAL(os.str(), "7b");
+ }
const char *tbl[] = {
"0x0",
"0x5",
@@ -579,22 +802,27 @@ void sub(mcl::fp::Mode mode)
const char *pStr = tbl[i];
printf("prime=%s\n", pStr);
Fp::init(pStr, mode);
+ cstrTest();
setStrTest();
streamTest();
+ ioModeTest();
+ edgeTest();
convTest();
compareTest();
moduloTest(pStr);
+ opeTest();
+ mul_UnitTest();
powTest();
powNegTest();
powFpTest();
+ powGmp();
setArrayTest1();
setArrayMaskTest1();
getUint64Test();
getInt64Test();
+ divBy2Test();
getStrTest();
}
- cstrTest(mode);
- opeTest(mode);
anotherFpTest(mode);
setArrayTest2(mode);
setArrayMaskTest2(mode);
diff --git a/test/mont_fp_test.cpp b/test/mont_fp_test.cpp
index 7b14f01..b26f828 100644
--- a/test/mont_fp_test.cpp
+++ b/test/mont_fp_test.cpp
@@ -109,509 +109,9 @@ void put(const uint64_t (&x)[N])
struct Test {
typedef mcl::FpT<> Fp;
- mpz_class m;
void run(const char *p)
{
Fp::init(p);
- m = p;
- Zn::init(p);
- edge();
- cstr();
- getStr();
- setStr();
- stream();
- ioMode();
- conv();
- compare();
- modulo();
- ope();
- pow();
- mul_Unit();
- pow_Zn();
- setArray();
- set64bit();
- divBy2();
- bench();
- }
- void cstr()
- {
- const struct {
- const char *str;
- int val;
- } tbl[] = {
- { "0", 0 },
- { "1", 1 },
- { "123", 123 },
- { "0x123", 0x123 },
- { "0b10101", 21 },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- // string cstr
- Fp x(tbl[i].str);
- CYBOZU_TEST_EQUAL(x, tbl[i].val);
-
- // int cstr
- Fp y(tbl[i].val);
- CYBOZU_TEST_EQUAL(y, x);
-
- // copy cstr
- Fp z(x);
- CYBOZU_TEST_EQUAL(z, x);
-
- // assign int
- Fp w;
- w = tbl[i].val;
- CYBOZU_TEST_EQUAL(w, x);
-
- // assign self
- Fp u;
- u = w;
- CYBOZU_TEST_EQUAL(u, x);
-
- // conv
- std::ostringstream os;
- os << tbl[i].val;
-
- std::string str;
- x.getStr(str);
- CYBOZU_TEST_EQUAL(str, os.str());
- }
- const struct {
- const char *str;
- int val;
- } tbl2[] = {
- { "-123", 123 },
- { "-0x123", 0x123 },
- { "-0b10101", 21 },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl2); i++) {
- Fp x(tbl2[i].str);
- x = -x;
- CYBOZU_TEST_EQUAL(x, tbl2[i].val);
- }
- }
- void getStr()
- {
- Fp x(0);
- std::string str;
- str = x.getStr();
- CYBOZU_TEST_EQUAL(str, "0");
- str = x.getStr(mcl::IoBinPrefix);
- CYBOZU_TEST_EQUAL(str, "0b0");
- str = x.getStr(mcl::IoBin);
- CYBOZU_TEST_EQUAL(str, "0");
- str = x.getStr(mcl::IoHexPrefix);
- CYBOZU_TEST_EQUAL(str, "0x0");
- str = x.getStr(mcl::IoHex);
- CYBOZU_TEST_EQUAL(str, "0");
-
- x = 123;
- str = x.getStr();
- CYBOZU_TEST_EQUAL(str, "123");
- str = x.getStr(mcl::IoBinPrefix);
- CYBOZU_TEST_EQUAL(str, "0b1111011");
- str = x.getStr(mcl::IoBin);
- CYBOZU_TEST_EQUAL(str, "1111011");
- str = x.getStr(mcl::IoHexPrefix);
- CYBOZU_TEST_EQUAL(str, "0x7b");
- str = x.getStr(mcl::IoHex);
- CYBOZU_TEST_EQUAL(str, "7b");
-
- {
- std::ostringstream os;
- os << x;
- CYBOZU_TEST_EQUAL(os.str(), "123");
- }
- {
- std::ostringstream os;
- os << std::hex << std::showbase << x;
- CYBOZU_TEST_EQUAL(os.str(), "0x7b");
- }
- {
- std::ostringstream os;
- os << std::hex << x;
- CYBOZU_TEST_EQUAL(os.str(), "7b");
- }
- }
-
- void setStr()
- {
- const struct {
- const char *in;
- int out;
- int base;
- } tbl[] = {
- { "100", 100, 0 }, // set base = 10 if base = 0
- { "100", 4, 2 },
- { "100", 256, 16 },
- { "0b100", 4, 0 },
- { "0b100", 4, 2 },
- { "0x100", 256, 0 },
- { "0x100", 256, 16 },
- // use prefix if base conflicts with prefix
- { "0b100", 4, 16 },
- { "0x100", 256, 2 },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- Fp x;
- x.setStr(tbl[i].in, tbl[i].base);
- CYBOZU_TEST_EQUAL(x, tbl[i].out);
- }
- }
-
- void stream()
- {
- const struct {
- const char *in;
- int out10;
- int out16;
- } tbl[] = {
- { "100", 100, 256 }, // set base = 10 if base = 0
- { "0x100", 256, 256 },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- {
- std::istringstream is(tbl[i].in);
- Fp x;
- is >> x;
- CYBOZU_TEST_EQUAL(x, tbl[i].out10);
- }
- {
- std::istringstream is(tbl[i].in);
- Fp x;
- is >> std::hex >> x;
- CYBOZU_TEST_EQUAL(x, tbl[i].out16);
- }
- }
- std::istringstream is("0b100");
- Fp x;
- // use prefix if base conflicts with prefix
- is >> std::hex >> x;
- CYBOZU_TEST_EQUAL(x, 4);
- }
- void ioMode()
- {
- Fp x(123);
- const struct {
- mcl::IoMode ioMode;
- std::string expected;
- } tbl[] = {
- { mcl::IoBin, "1111011" },
- { mcl::IoDec, "123" },
- { mcl::IoHex, "7b" },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- Fp::setIoMode(tbl[i].ioMode);
- for (int j = 0; j < 2; j++) {
- std::stringstream ss;
- if (j == 1) {
- ss << std::hex;
- }
- ss << x;
- CYBOZU_TEST_EQUAL(ss.str(), tbl[i].expected);
- Fp y;
- y.clear();
- ss >> y;
- CYBOZU_TEST_EQUAL(x, y);
- }
- }
- for (int i = 0; i < 2; i++) {
- if (i == 0) {
- Fp::setIoMode(mcl::IoArray);
- } else {
- Fp::setIoMode(mcl::IoArrayRaw);
- }
- std::stringstream ss;
- ss << x;
- CYBOZU_TEST_EQUAL(ss.str().size(), Fp::getBitSize() / 8);
- Fp y;
- ss >> y;
- CYBOZU_TEST_EQUAL(x, y);
- }
- Fp::setIoMode(mcl::IoAuto);
- }
- void edge()
- {
- std::cout << std::hex;
- /*
- real mont
- 0 0
- 1 R^-1
- R 1
- -1 -R^-1
- -R -1
- */
- mpz_class t = 1;
- const size_t N = Fp::getUnitSize();
- const mpz_class R = (t << (N * mcl::fp::UnitBitSize)) % m;
- const mpz_class tbl[] = {
- 0, 1, R, m - 1, m - R
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- const mpz_class& x = tbl[i];
- for (size_t j = i; j < CYBOZU_NUM_OF_ARRAY(tbl); j++) {
- const mpz_class& y = tbl[j];
- mpz_class z = (x * y) % m;
- Fp xx, yy;
- xx.setMpz(x);
- yy.setMpz(y);
- Fp zz = xx * yy;
- mpz_class t;
- zz.getMpz(t);
- CYBOZU_TEST_EQUAL(z, t);
- }
- }
- t = Fp::getOp().mp;
- t /= 2;
- Fp x;
- x.setMpz(t);
- CYBOZU_TEST_EQUAL(x * 2, -1);
- t += 1;
- x.setMpz(t);
- CYBOZU_TEST_EQUAL(x * 2, 1);
- }
-
- void conv()
- {
- const char *bin, *hex, *dec;
- if (Fp::getBitSize() <= 117) {
- bin = "0b1000000000000000000000000000000000000000000000000000000000001110";
- hex = "0x800000000000000e";
- dec = "9223372036854775822";
- } else {
- bin = "0b100100011010001010110011110001001000000010010001101000101011001111000100100000001001000110100010101100111100010010000";
- hex = "0x123456789012345678901234567890";
- dec = "94522879687365475552814062743484560";
- }
- Fp b(bin);
- Fp h(hex);
- Fp d(dec);
- CYBOZU_TEST_EQUAL(b, h);
- CYBOZU_TEST_EQUAL(b, d);
-
- std::string str;
- b.getStr(str, mcl::IoBinPrefix);
- CYBOZU_TEST_EQUAL(str, bin);
- b.getStr(str);
- CYBOZU_TEST_EQUAL(str, dec);
- b.getStr(str, mcl::IoHexPrefix);
- CYBOZU_TEST_EQUAL(str, hex);
- }
-
- void compare()
- {
- const struct {
- int lhs;
- int rhs;
- int cmp;
- } tbl[] = {
- { 0, 0, 0 },
- { 1, 0, 1 },
- { 0, 1, -1 },
- { -1, 0, 1 }, // m-1, 0
- { 0, -1, -1 }, // 0, m-1
- { 123, 456, -1 },
- { 456, 123, 1 },
- { 5, 5, 0 },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- const Fp x(tbl[i].lhs);
- const Fp y(tbl[i].rhs);
- const int cmp = tbl[i].cmp;
- if (cmp == 0) {
- CYBOZU_TEST_EQUAL(x, y);
- } else {
- 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()
- {
- std::ostringstream ms;
- ms << m;
-
- std::string str;
- Fp::getModulo(str);
- CYBOZU_TEST_EQUAL(str, ms.str());
- }
-
- void ope()
- {
- const struct {
- Zn x;
- Zn y;
- Zn add; // x + y
- Zn sub; // x - y
- Zn mul; // x * y
- Zn sqr; // x * x
- } tbl[] = {
- { 0, 1, 1, -1, 0, 0 },
- { 9, 7, 16, 2, 63, 81 },
- { 10, 13, 23, -3, 130, 100 },
- { 2000, -1000, 1000, 3000, -2000000, 4000000 },
- { -12345, -9999, -(12345 + 9999), - 12345 + 9999, 12345 * 9999, 12345 * 12345 },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- const Fp x(castTo<Fp>(tbl[i].x));
- const Fp y(castTo<Fp>(tbl[i].y));
- Fp z;
- Fp::add(z, x, y);
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].add));
- Fp::sub(z, x, y);
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].sub));
- Fp::mul(z, x, y);
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].mul));
-
- Fp r;
- Fp::inv(r, y);
- Zn rr = 1 / tbl[i].y;
- CYBOZU_TEST_EQUAL(r, castTo<Fp>(rr));
- Fp::mul(z, z, r);
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].x));
-
- z = x + y;
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].add));
- z = x - y;
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].sub));
- z = x * y;
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].mul));
- Fp::sqr(z, x);
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].sqr));
-
- z = x / y;
- z *= y;
- CYBOZU_TEST_EQUAL(z, castTo<Fp>(tbl[i].x));
- }
- {
- Fp x(5), y(3), z;
- Fp::addNC(z, x, y);
- if (Fp::compareRaw(z, Fp::getP()) >= 0) {
- Fp::subNC(z, z, Fp::getP());
- }
- CYBOZU_TEST_EQUAL(z, Fp(8));
- if (Fp::compareRaw(x, y) < 0) {
- Fp::addNC(x, x, Fp::getP());
- }
- Fp::subNC(x, x, y);
- CYBOZU_TEST_EQUAL(x, Fp(2));
- }
- }
- void pow()
- {
- Fp x, y, z;
- x = 12345;
- z = 1;
- for (int i = 0; i < 100; i++) {
- Fp::pow(y, x, i);
- CYBOZU_TEST_EQUAL(y, z);
- z *= x;
- }
- x = z;
- Fp::pow(z, x, Fp::getOp().mp - 1);
- CYBOZU_TEST_EQUAL(z, 1);
- Fp::pow(z, x, Fp::getOp().mp);
- CYBOZU_TEST_EQUAL(z, x);
- }
- void mul_Unit()
- {
- Fp x(-1), y, z;
- for (unsigned int u = 0; u < 20; u++) {
- Fp::mul(y, x, u);
- Fp::mul_Unit(z, x, u);
- CYBOZU_TEST_EQUAL(y, z);
- }
- }
- void pow_Zn()
- {
- Fp x, y, z;
- x = 12345;
- z = 1;
- for (int i = 0; i < 100; i++) {
- Fp::pow(y, x, Zn(i));
- CYBOZU_TEST_EQUAL(y, z);
- z *= x;
- }
- }
-
- void setArray()
- {
- // QQQ
-#if 0
- char b1[] = { 0x56, 0x34, 0x12 };
- Fp x;
- x.setArray(b1, 3);
- CYBOZU_TEST_EQUAL(x, 0x123456);
- int b2[] = { 0x12, 0x34 };
- x.setArray(b2, 2);
- CYBOZU_TEST_EQUAL(x, Fp("0x3400000012"));
-#endif
- }
-
- void set64bit()
- {
- const struct {
- const char *p;
- int64_t i;
- } tbl[] = {
- { "0x1234567812345678", uint64_t(0x1234567812345678ull) },
- { "0x1234567812345678", int64_t(0x1234567812345678ll) },
- };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- Fp x(tbl[i].p);
- Fp y(tbl[i].i);
- if (tbl[i].i < 0) x = -x;
- CYBOZU_TEST_EQUAL(x, y);
- }
- }
- void divBy2()
- {
- const int tbl[] = { -4, -3, -2, -1, 0, 1, 2, 3 };
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- Fp x(tbl[i]), y;
- Fp::divBy2(y, x);
- y *= 2;
- CYBOZU_TEST_EQUAL(y, x);
- y = x;
- Fp::divBy2(y, y);
- y *= 2;
- CYBOZU_TEST_EQUAL(y, x);
- }
- }
- void bench()
- {
Fp x("-123456789");
Fp y("-0x7ffffffff");
CYBOZU_BENCH("add", operator+, x, x);