aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2016-09-18 16:35:51 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2016-09-18 16:35:51 +0800
commit9ad3a356288786f65fa239fd22923fc5986bb857 (patch)
tree7f4bbe37ddd710aab869fb6a92293e2be7da0c88
parent29ff10182a906b2dd9f4a1a0a32bc4c4dafb5f03 (diff)
downloadtangerine-mcl-9ad3a356288786f65fa239fd22923fc5986bb857.tar.gz
tangerine-mcl-9ad3a356288786f65fa239fd22923fc5986bb857.tar.zst
tangerine-mcl-9ad3a356288786f65fa239fd22923fc5986bb857.zip
rewrite fp_test
-rw-r--r--src/fp.cpp7
-rw-r--r--src/fp_generator.hpp19
-rw-r--r--src/fp_proto.hpp1
-rw-r--r--src/gen.cpp4
-rw-r--r--test/fp_test.cpp223
5 files changed, 179 insertions, 75 deletions
diff --git a/src/fp.cpp b/src/fp.cpp
index 5b99767..0d2af45 100644
--- a/src/fp.cpp
+++ b/src/fp.cpp
@@ -389,7 +389,6 @@ static void initInvTbl(Op& op)
static void initForMont(Op& op, const Unit *p, Mode mode)
{
const size_t N = op.N;
- assert(N >= 2);
{
mpz_class t = 1, R;
gmp::getArray(op.one, N, t);
@@ -451,9 +450,7 @@ void Op::init(const std::string& mstr, int base, size_t maxBitSize, Mode mode)
}
#endif
switch (roundBit) {
- case 32:
- case 64:
- case 96:
+ case 64: SET_OP(64); SET_OP_DBL_LLVM(64, 128); break;
case 128: SET_OP(128); SET_OP_DBL_LLVM(128, 256); break;
case 192: SET_OP(192); SET_OP_DBL_LLVM(192, 384); break;
case 256: SET_OP(256); SET_OP_DBL_LLVM(256, 512); break;
@@ -484,6 +481,8 @@ void Op::init(const std::string& mstr, int base, size_t maxBitSize, Mode mode)
break;
#endif
#else
+ case 32: SET_OP(32); SET_OP_DBL_LLVM(32, 64); break;
+ case 96: SET_OP(96); SET_OP_DBL_LLVM(96, 192); break;
case 160: SET_OP(160); SET_OP_DBL_LLVM(160, 320); break;
case 224: SET_OP(224); SET_OP_DBL_LLVM(224, 448); break;
case 288: SET_OP(288); break;
diff --git a/src/fp_generator.hpp b/src/fp_generator.hpp
index 5dbf90f..eb28c06 100644
--- a/src/fp_generator.hpp
+++ b/src/fp_generator.hpp
@@ -183,7 +183,7 @@ struct FpGenerator : Xbyak::CodeGenerator {
*/
void init(Op& op)
{
- if (op.N < 2) throw cybozu::Exception("mcl:FpGenerator:small pn") << op.N;
+// if (op.N < 2) throw cybozu::Exception("mcl:FpGenerator:small pn") << op.N;
op_ = &op;
p_ = op.p;
rp_ = fp::getMontgomeryCoeff(p_[0]);
@@ -347,7 +347,12 @@ struct FpGenerator : Xbyak::CodeGenerator {
*/
void gen_raw_mul_Unit(const RegExp& pz, const RegExp& px, const Reg64& y, const MixPack& wk, const Reg64& t, size_t n)
{
- assert(n >= 2);
+ if (n == 1) {
+ mov(rax, ptr [px]);
+ mul(y);
+ mov(ptr [pz], rax);
+ return;
+ }
if (n == 2) {
mov(rax, ptr [px]);
mul(y);
@@ -409,7 +414,7 @@ struct FpGenerator : Xbyak::CodeGenerator {
}
void gen_mul_Unit()
{
- assert(pn_ >= 2);
+// assert(pn_ >= 2);
const int regNum = useMulx_ ? 2 : (1 + std::min(pn_ - 1, 8));
const int stackSize = useMulx_ ? 0 : (pn_ - 1) * 8;
StackFrame sf(this, 3, regNum | UseRDX, stackSize);
@@ -944,7 +949,7 @@ struct FpGenerator : Xbyak::CodeGenerator {
*/
void gen_montMulN(const uint64_t *p, uint64_t pp, int n)
{
- assert(2 <= pn_ && pn_ <= 9);
+ assert(1 <= pn_ && pn_ <= 9);
const int regNum = useMulx_ ? 4 : 3 + std::min(n - 1, 7);
const int stackSize = (n * 3 + (isFullBit_ ? 2 : 1)) * 8;
StackFrame sf(this, 3, regNum | UseRDX, stackSize);
@@ -1791,7 +1796,7 @@ struct FpGenerator : Xbyak::CodeGenerator {
*/
void gen_preInv()
{
- assert(pn_ >= 2);
+ assert(pn_ >= 1);
const int freeRegNum = 13;
if (pn_ > 9) {
throw cybozu::Exception("mcl:FpGenerator:gen_preInv:large pn_") << pn_;
@@ -1943,9 +1948,9 @@ struct FpGenerator : Xbyak::CodeGenerator {
}
#endif
L(".exit");
- assert(ss.isReg(0) && ss.isReg(1));
+ assert(ss.isReg(0));
const Reg64& t2 = ss.getReg(0);
- const Reg64& t3 = ss.getReg(1);
+ const Reg64& t3 = rdx;
mov(t2, (size_t)p_);
if (isFullBit_) {
diff --git a/src/fp_proto.hpp b/src/fp_proto.hpp
index ea26927..f7ccaf9 100644
--- a/src/fp_proto.hpp
+++ b/src/fp_proto.hpp
@@ -25,6 +25,7 @@ void mcl_fp_montRed ## len(mcl::fp::Unit* z, const mcl::fp::Unit* xy, const mcl:
void mcl_fpDbl_add ## len(mcl::fp::Unit*, const mcl::fp::Unit*, const mcl::fp::Unit*, const mcl::fp::Unit*); \
void mcl_fpDbl_sub ## len(mcl::fp::Unit*, const mcl::fp::Unit*, const mcl::fp::Unit*, const mcl::fp::Unit*);
+MCL_FP_DEF_FUNC(64)
MCL_FP_DEF_FUNC(128)
MCL_FP_DEF_FUNC(192)
MCL_FP_DEF_FUNC(256)
diff --git a/src/gen.cpp b/src/gen.cpp
index cd11622..28ddc59 100644
--- a/src/gen.cpp
+++ b/src/gen.cpp
@@ -820,9 +820,7 @@ struct Code : public mcl::Generator {
setBit(i);
gen_all();
gen_addsub();
- if (i > 64) {
- gen_mul();
- }
+ gen_mul();
}
if (unit == 64 && maxBitSize == 768) {
for (uint32_t i = maxBitSize + unit * 2; i <= maxBitSize * 2; i += unit * 2) {
diff --git a/test/fp_test.cpp b/test/fp_test.cpp
index 19b6ea5..66087dc 100644
--- a/test/fp_test.cpp
+++ b/test/fp_test.cpp
@@ -1,9 +1,11 @@
#define PUT(x) std::cout << #x "=" << (x) << std::endl
+#define CYBOZU_TEST_DISABLE_AUTO_RUN
#include <cybozu/test.hpp>
#include <mcl/fp.hpp>
-#include <cybozu/benchmark.hpp>
#include "../src/fp_proto.hpp"
#include <time.h>
+#include <cybozu/benchmark.hpp>
+#include <cybozu/option.hpp>
#ifdef _MSC_VER
#pragma warning(disable: 4127) // const condition
@@ -11,20 +13,10 @@
typedef mcl::FpT<> Fp;
-const int m = 65537;
-struct Init {
- Init()
- {
- std::ostringstream ms;
- ms << m;
- Fp::init(ms.str());
- }
-};
-
-CYBOZU_TEST_SETUP_FIXTURE(Init);
-
-CYBOZU_TEST_AUTO(cstr)
+void cstrTest(mcl::fp::Mode mode)
{
+ const int m = 65537;
+ Fp::init(mpz_class(m), mode);
const struct {
const char *str;
int val;
@@ -34,7 +26,7 @@ CYBOZU_TEST_AUTO(cstr)
{ "123", 123 },
{ "0x123", 0x123 },
{ "0b10101", 21 },
- { "-123", m - 123 },
+ { "-123", m - 123 },
{ "-0x123", m - 0x123 },
{ "-0b10101", m - 21 },
};
@@ -71,7 +63,7 @@ CYBOZU_TEST_AUTO(cstr)
}
}
-CYBOZU_TEST_AUTO(setStr)
+void setStrTest()
{
const struct {
const char *in;
@@ -96,7 +88,7 @@ CYBOZU_TEST_AUTO(setStr)
}
}
-CYBOZU_TEST_AUTO(stream)
+void streamTest()
{
const struct {
const char *in;
@@ -142,7 +134,7 @@ CYBOZU_TEST_AUTO(stream)
}
}
-CYBOZU_TEST_AUTO(conv)
+void convTest()
{
const char *bin = "0b1001000110100";
const char *hex = "0x1234";
@@ -162,7 +154,7 @@ CYBOZU_TEST_AUTO(conv)
CYBOZU_TEST_EQUAL(str, hex);
}
-CYBOZU_TEST_AUTO(compare)
+void compareTest()
{
const struct {
int lhs;
@@ -201,18 +193,17 @@ CYBOZU_TEST_AUTO(compare)
}
}
-CYBOZU_TEST_AUTO(modulo)
+void moduloTest(const char *pStr)
{
- std::ostringstream ms;
- ms << m;
-
std::string str;
Fp::getModulo(str);
- CYBOZU_TEST_EQUAL(str, ms.str());
+ CYBOZU_TEST_EQUAL(str, mpz_class(pStr).get_str());
}
-CYBOZU_TEST_AUTO(ope)
+void opeTest(mcl::fp::Mode mode)
{
+ const int m = 65537;
+ Fp::init(mpz_class(m), mode);
const struct {
int x;
int y;
@@ -265,7 +256,7 @@ CYBOZU_TEST_AUTO(ope)
struct tag2;
-CYBOZU_TEST_AUTO(pow)
+void powTest()
{
Fp x, y, z;
x = 12345;
@@ -287,7 +278,7 @@ CYBOZU_TEST_AUTO(pow)
CYBOZU_TEST_EQUAL(x, 125);
}
-CYBOZU_TEST_AUTO(neg_pow)
+void powNegTest()
{
Fp x, y, z;
x = 12345;
@@ -300,7 +291,7 @@ CYBOZU_TEST_AUTO(neg_pow)
}
}
-CYBOZU_TEST_AUTO(pow_fp)
+void powFpTest()
{
Fp x, y, z;
x = 12345;
@@ -314,19 +305,18 @@ CYBOZU_TEST_AUTO(pow_fp)
struct TagAnother;
-CYBOZU_TEST_AUTO(another)
+void anotherFpTest(mcl::fp::Mode mode)
{
typedef mcl::FpT<TagAnother, 128> G;
- G::init("13");
+ G::init("13", mode);
G a = 3;
G b = 9;
a *= b;
CYBOZU_TEST_EQUAL(a, 1);
}
-CYBOZU_TEST_AUTO(setArray)
+void setArrayTest1()
{
- Fp::init("1000000000000000000117");
char b1[] = { 0x56, 0x34, 0x12 };
Fp x;
x.setArray(b1, 3);
@@ -334,8 +324,11 @@ CYBOZU_TEST_AUTO(setArray)
int b2[] = { 0x12, 0x34 };
x.setArray(b2, 2);
CYBOZU_TEST_EQUAL(x, Fp("0x3400000012"));
+}
- Fp::init("0x10000000000001234567a5");
+void setArrayTest2(mcl::fp::Mode mode)
+{
+ Fp::init("0x10000000000001234567a5", mode);
const struct {
uint32_t buf[3];
size_t bufN;
@@ -346,6 +339,7 @@ CYBOZU_TEST_AUTO(setArray)
{ { 0x234567a4, 0x00000001, 0x00080000}, 3, "0x08000000000001234567a4" },
{ { 0x234567a4, 0x00000001, 0x00100000}, 3, "0x10000000000001234567a4" },
};
+ Fp x;
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
x.setArray(tbl[i].buf, tbl[i].bufN);
CYBOZU_TEST_EQUAL(x, Fp(tbl[i].expected));
@@ -354,9 +348,8 @@ CYBOZU_TEST_AUTO(setArray)
CYBOZU_TEST_EXCEPTION(x.setArray(large, 3), cybozu::Exception);
}
-CYBOZU_TEST_AUTO(setArrayMask)
+void setArrayMaskTest1()
{
- Fp::init("1000000000000000000117");
char b1[] = { 0x56, 0x34, 0x12 };
Fp x;
x.setArrayMask(b1, 3);
@@ -364,8 +357,11 @@ CYBOZU_TEST_AUTO(setArrayMask)
int b2[] = { 0x12, 0x34 };
x.setArrayMask(b2, 2);
CYBOZU_TEST_EQUAL(x, Fp("0x3400000012"));
+}
- Fp::init("0x10000000000001234567a5");
+void setArrayMaskTest2(mcl::fp::Mode mode)
+{
+ Fp::init("0x10000000000001234567a5", mode);
const struct {
uint32_t buf[3];
size_t bufN;
@@ -376,6 +372,7 @@ CYBOZU_TEST_AUTO(setArrayMask)
{ { 0x234567a4, 0x00000001, 0x00100000}, 3, "0x00000000000001234567a4" },
{ { 0x234567a5, 0xfffffff1, 0xffffffff}, 3, "0x0ffffffffffff1234567a5" },
};
+ Fp x;
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
x.setArrayMask(tbl[i].buf, tbl[i].bufN);
CYBOZU_TEST_EQUAL(x, Fp(tbl[i].expected));
@@ -399,9 +396,8 @@ CYBOZU_TEST_AUTO(set64bit)
}
}
-CYBOZU_TEST_AUTO(getUint64)
+void getUint64Test()
{
- Fp::init("0x1000000000000000000f");
const uint64_t tbl[] = {
0, 1, 123, 0xffffffff, int64_t(0x7fffffffffffffffull)
};
@@ -430,9 +426,8 @@ CYBOZU_TEST_AUTO(getUint64)
}
}
-CYBOZU_TEST_AUTO(getInt64)
+void getInt64Test()
{
- Fp::init("0x1000000000000000000f");
const int64_t tbl[] = {
0, 1, 123, 0xffffffff, int64_t(0x7fffffffffffffffull),
-1, -2, -12345678, -int64_t(1) << 63,
@@ -456,6 +451,29 @@ CYBOZU_TEST_AUTO(getInt64)
}
}
+void getStrTest()
+{
+ const char *tbl[] = {
+ "0x0",
+ "0x5",
+ "0x123",
+ "0x123456789012345679adbc",
+ "0xffffffff26f2fc170f69466a74defd8d",
+ "0x100000000000000000000000000000033",
+ "0x11ee12312312940000000000000000000000000002342343"
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ const char *s = tbl[i];
+ mpz_class x(s);
+ if (x >= Fp::getOp().mp) continue;
+ Fp y(s);
+ std::string xs, ys;
+ mcl::gmp::getStr(xs, x, 16);
+ y.getStr(ys, 16);
+ CYBOZU_TEST_EQUAL(xs, ys);
+ }
+}
+
CYBOZU_TEST_AUTO(getArray)
{
const struct {
@@ -479,27 +497,6 @@ CYBOZU_TEST_AUTO(getArray)
}
}
-CYBOZU_TEST_AUTO(getStr)
-{
- const char *tbl[] = {
- "0x0",
- "0x5",
- "0x123",
- "0x123456789012345679adbc",
- "0xffffffff26f2fc170f69466a74defd8d",
- "0x100000000000000000000000000000033",
- "0x11ee12312312940000000000000000000000000002342343"
- };
- Fp::init("0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d");
- for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
- mpz_class x(tbl[i]);
- Fp y(tbl[i]);
- std::string xs, ys;
- mcl::gmp::getStr(xs, x, 16);
- y.getStr(ys, 16);
- CYBOZU_TEST_EQUAL(xs, ys);
- }
-}
#include <iostream>
#if defined(MCL_USE_LLVM) || defined(MCL_USE_XBYAK)
@@ -542,3 +539,107 @@ CYBOZU_TEST_AUTO(mod_NIST_P521)
}
}
#endif
+
+void sub(mcl::fp::Mode mode)
+{
+ printf("mode=%s\n", mcl::fp::ModeToStr(mode));
+ const char *tbl[] = {
+ // N = 2
+ "0x0000000000000001000000000000000d",
+ "0x7fffffffffffffffffffffffffffffff",
+ "0x8000000000000000000000000000001d",
+ "0xffffffffffffffffffffffffffffff61",
+
+ // N = 3
+ "0x000000000000000100000000000000000000000000000033", // min prime
+ "0x00000000fffffffffffffffffffffffffffffffeffffac73",
+ "0x0000000100000000000000000001b8fa16dfab9aca16b6b3",
+ "0x000000010000000000000000000000000000000000000007",
+ "0x30000000000000000000000000000000000000000000002b",
+ "0x70000000000000000000000000000000000000000000001f",
+ "0x800000000000000000000000000000000000000000000005",
+ "0xfffffffffffffffffffffffffffffffffffffffeffffee37",
+ "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d",
+ "0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime
+
+ // N = 4
+ "0x0000000000000001000000000000000000000000000000000000000000000085", // min prime
+ "0x2523648240000001ba344d80000000086121000000000013a700000000000013",
+ "0x7523648240000001ba344d80000000086121000000000013a700000000000017",
+ "0x800000000000000000000000000000000000000000000000000000000000005f",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime
+
+ // N = 6
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+
+ // N = 9
+ "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ const char *pStr = tbl[i];
+ printf("prime=%s\n", pStr);
+ Fp::init(pStr, mode);
+ setStrTest();
+ streamTest();
+ convTest();
+ compareTest();
+ moduloTest(pStr);
+ powTest();
+ powNegTest();
+ powFpTest();
+ setArrayTest1();
+ setArrayMaskTest1();
+ getUint64Test();
+ getInt64Test();
+ getStrTest();
+ }
+ cstrTest(mode);
+ opeTest(mode);
+ anotherFpTest(mode);
+ setArrayTest2(mode);
+ setArrayMaskTest2(mode);
+}
+
+std::string g_mode;
+
+CYBOZU_TEST_AUTO(main)
+{
+ if (g_mode.empty() || g_mode == "auto") {
+ sub(mcl::fp::FP_AUTO);
+ }
+ if (g_mode.empty() || g_mode == "gmp") {
+ sub(mcl::fp::FP_GMP);
+ }
+ if (g_mode.empty() || g_mode == "gmp_mont") {
+ sub(mcl::fp::FP_GMP_MONT);
+ }
+#ifdef MCL_USE_LLVM
+ if (g_mode.empty() || g_mode == "llvm") {
+ sub(mcl::fp::FP_LLVM);
+ }
+ if (g_mode.empty() || g_mode == "llvm_mont") {
+ sub(mcl::fp::FP_LLVM_MONT);
+ }
+#endif
+#ifdef MCL_USE_XBYAK
+ if (g_mode.empty() || g_mode == "xbyak") {
+ sub(mcl::fp::FP_XBYAK);
+ }
+#endif
+}
+
+int main(int argc, char *argv[])
+ try
+{
+ cybozu::Option opt;
+ opt.appendOpt(&g_mode, "", "m", ": mode(auto/gmp/gmp_mont/llvm/llvm_mont/xbyak)");
+ opt.appendHelp("h", ": show this message");
+ if (!opt.parse(argc, argv)) {
+ opt.usage();
+ return 1;
+ }
+ return cybozu::test::autoRun.run(argc, argv);
+} catch (std::exception& e) {
+ printf("ERR %s\n", e.what());
+ return 1;
+}