|
|
|
@ -8,7 +8,33 @@ |
|
|
|
|
typedef mcl::FpT<> Fp; |
|
|
|
|
|
|
|
|
|
typedef mcl::fp::Unit Unit; |
|
|
|
|
using namespace mcl::fp; |
|
|
|
|
|
|
|
|
|
#include "../src/low_gmp.hpp" |
|
|
|
|
const size_t N = 12; |
|
|
|
|
|
|
|
|
|
void mulPre768(Unit *pz, const Unit *px, const Unit *py) |
|
|
|
|
{ |
|
|
|
|
/*
|
|
|
|
|
W = 1 << H |
|
|
|
|
(aW + b)(cW + d) = acW^2 + (ad + bc)W + bd |
|
|
|
|
ad + bc = (a + b)(c + d) - ac - bd |
|
|
|
|
*/ |
|
|
|
|
const size_t H = N / 2; |
|
|
|
|
low_mul<H>(pz, px, py); // bd
|
|
|
|
|
low_mul<H>(pz + N, px + H, py + H); // ac
|
|
|
|
|
Unit a_b[H + 1]; |
|
|
|
|
Unit c_d[H + 1]; |
|
|
|
|
a_b[H] = low_add<H>(a_b, px, px + H); // a + b
|
|
|
|
|
c_d[H] = low_add<H>(c_d, py, py + H); // c + d
|
|
|
|
|
Unit work[N + H] = {}; |
|
|
|
|
low_mul<H>(work, a_b, c_d); |
|
|
|
|
if (c_d[H]) low_add<H + 1>(work + H, work + H, c_d); |
|
|
|
|
if (a_b[H]) low_add<H + 1>(work + H, work + H, a_b); |
|
|
|
|
work[N] -= low_sub<H>(work, work, pz); |
|
|
|
|
work[N] -= low_sub<H>(work, work, pz + N); |
|
|
|
|
low_add<H + N>(pz + H, pz + H, work); |
|
|
|
|
} |
|
|
|
|
void test(const std::string& pStr, mcl::fp::Mode mode) |
|
|
|
|
{ |
|
|
|
|
printf("test %s\n", mcl::fp::ModeToStr(mode)); |
|
|
|
@ -31,6 +57,24 @@ void test(const std::string& pStr, mcl::fp::Mode mode) |
|
|
|
|
CYBOZU_BENCH("mul", Fp::mul, x, x, x); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void testMul() |
|
|
|
|
{ |
|
|
|
|
mcl::fp::Unit ux[N], uy[N], a[N * 2], b[N * 2]; |
|
|
|
|
for (size_t i = 0; i < N; i++) { |
|
|
|
|
ux[i] = -i * i + 5; |
|
|
|
|
uy[i] = -i * i + 9; |
|
|
|
|
} |
|
|
|
|
low_mul<12>(a, ux, uy); |
|
|
|
|
mulPre768(b, ux, uy); |
|
|
|
|
for (size_t i = 0; i < N * 2; i++) { |
|
|
|
|
if (a[i] != b[i]) { |
|
|
|
|
printf("ERR %016llx %016llx\n", (long long)a[i], (long long)b[i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
puts("end testMul"); |
|
|
|
|
CYBOZU_BENCH("mulPre768", mulPre768, ux, ux, uy); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void testAll(const std::string& pStr) |
|
|
|
|
{ |
|
|
|
|
test(pStr, mcl::fp::FP_GMP); |
|
|
|
@ -49,6 +93,7 @@ int main() |
|
|
|
|
}; |
|
|
|
|
testAll(pTbl[0]); |
|
|
|
|
testAll(pTbl[1]); |
|
|
|
|
// testMul();
|
|
|
|
|
} catch (std::exception& e) { |
|
|
|
|
printf("err %s\n", e.what()); |
|
|
|
|
puts("make clean"); |
|
|
|
|