dev
MITSUNARI Shigeo 9 years ago
parent 6f66d1fb91
commit b67f40405c
  1. 37
      include/mcl/fp.hpp
  2. 9
      include/mcl/fp_ext.hpp
  3. 2
      test/Makefile
  4. 108
      test/fp_ext_test.cpp

@ -56,6 +56,7 @@ class FpT {
static fp::Op op_;
template<class tag2, size_t maxBitSize2> friend class FpT;
Unit v_[maxSize];
template<class Fp> friend class Fp2T;
public:
// return pointer to array v_[]
const Unit *getUnit() const { return v_; }
@ -466,23 +467,23 @@ private:
static inline void fp2_addW(Unit *z, const Unit *x, const Unit *y)
{
const fp::void3u fp_add = op_.fp_add;
const size_t N = op_.N;
const size_t n = maxSize;
fp_add(z, x, y);
fp_add(z + N, x + N, y + N);
fp_add(z + n, x + n, y + n);
}
static inline void fp2_subW(Unit *z, const Unit *x, const Unit *y)
{
const fp::void3u fp_sub = op_.fp_sub;
const size_t N = op_.N;
const size_t n = maxSize;
fp_sub(z, x, y);
fp_sub(z + N, x + N, y + N);
fp_sub(z + n, x + n, y + n);
}
static inline void fp2_negW(Unit *y, const Unit *x)
{
const fp::void2u fp_neg = op_.fp_neg;
const size_t N = op_.N;
const size_t n = maxSize;
fp_neg(y, x);
fp_neg(y + N, x + N);
fp_neg(y + n, x + n);
}
/*
x = a + bu, y = c + du, u^2 = -1
@ -494,11 +495,11 @@ private:
const fp::void3u fp_add = op_.fp_add;
const fp::void3u fp_sub = op_.fp_sub;
const fp::void3u fp_mul = op_.fp_mul;
const size_t N = op_.N;
const size_t n = maxSize;
const Unit *a = x;
const Unit *b = x + N;
const Unit *b = x + n;
const Unit *c = y;
const Unit *d = y + N;
const Unit *d = y + n;
Unit t1[maxSize];
Unit t2[maxSize];
Unit ac[maxSize];
@ -510,8 +511,8 @@ private:
fp_mul(bd, b, d);
fp_sub(z, ac, bd); // ac - bd
fp_sub(z, z, bd);
fp_sub(z + N, t1, ac);
fp_sub(z + N, z + N, bd);
fp_sub(z + n, t1, ac);
fp_sub(z + n, z + n, bd);
}
/*
x = a + bu, u^2 = -1
@ -523,9 +524,9 @@ private:
const fp::void3u fp_sub = op_.fp_sub;
const fp::void2u fp_sqr = op_.fp_sqr;
const fp::void3u fp_mul = op_.fp_mul;
const size_t N = op_.N;
const size_t n = maxSize;
const Unit *a = x;
const Unit *b = x + N;
const Unit *b = x + n;
Unit aa[maxSize];
Unit bb[maxSize];
Unit t[maxSize];
@ -533,7 +534,7 @@ private:
fp_sqr(bb, b);
fp_mul(t, a, b);
fp_sub(y, aa, bb); // a^2 - b^2
fp_add(y + N, t, t); // 2ab
fp_add(y + n, t, t); // 2ab
}
/*
x = a + bu
@ -546,9 +547,9 @@ private:
const fp::void3u fp_mul = op_.fp_mul;
const fp::void2uOp fp_invOp = op_.fp_invOp;
const fp::void2u fp_neg = op_.fp_neg;
const size_t N = op_.N;
const size_t n = maxSize;
const Unit *a = x;
const Unit *b = x + N;
const Unit *b = x + n;
Unit aa[maxSize];
Unit bb[maxSize];
fp_sqr(aa, a);
@ -556,8 +557,8 @@ private:
fp_add(aa, aa, bb);
fp_invOp(aa, aa, op_); // aa = 1 / (a^2 + b^2)
fp_mul(y, y, aa);
fp_mul(y + N, y + N, aa);
fp_neg(y + N, y + N);
fp_mul(y + n, y + n, aa);
fp_neg(y + n, y + n);
}
};

@ -24,10 +24,9 @@ public:
: a(x), b(0)
{
}
Fp2T(const Fp& a, const Fp& b)
: a(a), b(b)
{
}
Fp2T(const Fp& a, const Fp& b) : a(a), b(b) { }
Fp2T(int64_t a, int64_t b) : a(a), b(b) { }
Fp2T(const std::string& a, const std::string& b, int base = 0) : a(a, base), b(b, base) {}
Fp* get() { return &a; }
const Fp* get() const { return &a; }
void clear()
@ -72,7 +71,7 @@ public:
const size_t size = str.size();
const size_t pos = str.find(',');
if (size >= 5 && str[0] == '[' && pos != std::string::npos && str[size - 1] == ']') {
a.setStr(str.substr(1, pos), base);
a.setStr(str.substr(1, pos - 1), base);
b.setStr(str.substr(pos + 1, size - pos - 2), base);
return;
}

@ -2,7 +2,7 @@ include ../common.mk
TARGET=$(TEST_FILE)
SRC=fp_test.cpp ec_test.cpp fp_util_test.cpp window_method_test.cpp elgamal_test.cpp
SRC=fp_test.cpp ec_test.cpp fp_util_test.cpp window_method_test.cpp elgamal_test.cpp fp_ext_test.cpp
ifeq ($(CPU),x64)
SRC+=fp_generator_test.cpp mont_fp_test.cpp
endif

@ -0,0 +1,108 @@
#define PUT(x) std::cout << #x "=" << (x) << std::endl
#include <cybozu/test.hpp>
#include <cybozu/benchmark.hpp>
#include <time.h>
#include <mcl/fp.hpp>
#include <mcl/fp_ext.hpp>
struct FpTag;
typedef mcl::FpT<FpTag, 256> Fp;
typedef mcl::Fp2T<Fp> Fp2;
void testFp2()
{
puts(__FUNCTION__);
Fp2 x, y, z;
x.a = 1;
x.b = 2;
y.a = 3;
y.b = 4;
/*
x = 1 + 2u
y = 3 + 4u
*/
Fp2::add(z, x, y);
CYBOZU_TEST_EQUAL(z, Fp2(4, 6));
Fp2::sub(z, x, y);
CYBOZU_TEST_EQUAL(z, Fp2(-2, -2));
Fp2::mul(z, x, y);
/*
(1 + 2u)(3 + 4u) = (3 - 8) + (4 + 6)u = -5 + 10u
*/
CYBOZU_TEST_EQUAL(z, Fp2(-5, 10));
z = x * x;
Fp2::sqr(y, x);
CYBOZU_TEST_EQUAL(z, y);
x.a.setStr("-1234567894");
x.b.setStr("-464652165165");
y = x * x;
Fp2::sqr(x, x);
CYBOZU_TEST_EQUAL(x, y);
{
std::ostringstream oss;
oss << x;
std::istringstream iss(oss.str());
Fp2 w;
iss >> w;
CYBOZU_TEST_EQUAL(x, w);
}
y = x;
Fp2::inv(y, x);
y *= x;
CYBOZU_TEST_EQUAL(y, 1);
}
void test(const char *p)
{
printf("prime=%s\n", p);
Fp::setModulo(p);
testFp2();
}
#if 0
void benchFp2()
{
Fp2 x, y;
x.a.set("4");
x.b.set("464652165165");
y = x * x;
CYBOZU_BENCH("Fp2::add ", Fp2::add, x, x, y);
CYBOZU_BENCH("Fp2::addNC ", Fp2::addNC, x, x, y);
CYBOZU_BENCH("Fp2::sub ", Fp2::sub, x, x, y);
CYBOZU_BENCH("Fp2::neg ", Fp2::neg, x, x);
CYBOZU_BENCH("Fp2::mul ", Fp2::mul, x, x, y);
CYBOZU_BENCH("Fp2::inverse ", x.inverse);
CYBOZU_BENCH("Fp2::square ", Fp2::square, x, x);
CYBOZU_BENCH("Fp2::mul_xi ", Fp2::mul_xi, x, x);
CYBOZU_BENCH("Fp2::mul_Fp_0", Fp2::mul_Fp_0, x, x, Param::half);
CYBOZU_BENCH("Fp2::mul_Fp_1", Fp2::mul_Fp_1, x, Param::half);
CYBOZU_BENCH("Fp2::divBy2 ", Fp2::divBy2, x, x);
CYBOZU_BENCH("Fp2::divBy4 ", Fp2::divBy4, x, x);
}
#endif
CYBOZU_TEST_AUTO(test)
{
const char *tbl[] = {
// 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
};
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
test(tbl[i]);
}
}
Loading…
Cancel
Save