change mulVec interface

update-fork
MITSUNARI Shigeo 5 years ago
parent afb1c812f1
commit 3039bdb86f
  1. 2
      include/mcl/bn.hpp
  2. 31
      include/mcl/ec.hpp
  3. 3
      include/mcl/op.hpp
  4. 14
      include/mcl/operator.hpp
  5. 5
      test/bls12_test.cpp
  6. 5
      test/bn384_test.cpp
  7. 5
      test/bn512_test.cpp
  8. 5
      test/bn_test.cpp
  9. 13
      test/common_test.hpp
  10. 10
      test/ec_test.cpp

@ -814,7 +814,7 @@ struct GLV2 {
size_t mulVecNGLV(T& z, const T *xVec, const mpz_class *yVec, size_t n) const
{
const mpz_class& r = Fr::getOp().mp;
const size_t N = 16;
const size_t N = mcl::fp::maxMulVecNGLV;
if (n > N) n = N;
const int w = 5;
const size_t tblSize = 1 << (w - 2);

@ -30,9 +30,6 @@ enum Mode {
namespace local {
const size_t maxMulVecN = 32; // inner loop of mulVec
const size_t maxMulVecNGLV = 16; // inner loop of mulVec with GLV
// x is negative <=> x < half(:=(p+1)/2) <=> a = 1
template<class Fp>
bool get_a_flag(const Fp& x)
@ -1187,9 +1184,10 @@ public:
@note &z != xVec[i]
*/
private:
static inline size_t mulVecN(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t n)
template<class tag, size_t maxBitSize, template<class _tag, size_t _maxBitSize>class FpT>
static inline size_t mulVecN(EcT& z, const EcT *xVec, const FpT<tag, maxBitSize> *yVec, size_t n)
{
const size_t N = mcl::ec::local::maxMulVecN;
const size_t N = mcl::fp::maxMulVecN;
if (n > N) n = N;
const int w = 5;
const size_t tblSize = 1 << (w - 2);
@ -1197,9 +1195,12 @@ private:
NafArray naf[N];
EcT tbl[N][tblSize];
size_t maxBit = 0;
mpz_class y;
for (size_t i = 0; i < n; i++) {
bool b;
gmp::getNAFwidth(&b, naf[i], yVec[i], w);
yVec[i].getMpz(&b, y);
assert(b); (void)b;
gmp::getNAFwidth(&b, naf[i], y, w);
assert(b); (void)b;
if (naf[i].size() > maxBit) maxBit = naf[i].size();
EcT P2;
@ -1220,14 +1221,20 @@ private:
}
public:
static inline void mulVec(EcT& z, const EcT *xVec, const mpz_class *yVec, size_t n)
template<class tag, size_t maxBitSize, template<class _tag, size_t _maxBitSize>class FpT>
static inline void mulVec(EcT& z, const EcT *xVec, const FpT<tag, maxBitSize> *yVec, size_t n)
{
size_t (*f)(EcT&, const EcT *, const mpz_class *, size_t n) = mulVecN;
/*
mulVecNGLV is a little slow for large n
*/
if (mulVecNGLV && n < mcl::ec::local::maxMulVecNGLV) {
size_t done = mulVecNGLV(z, xVec, yVec, n);
if (mulVecNGLV && n < mcl::fp::maxMulVecNGLV) {
mpz_class myVec[mcl::fp::maxMulVecNGLV];
for (size_t i = 0; i < n; i++) {
bool b;
yVec[i].getMpz(&b, myVec[i]);
assert(b); (void)b;
}
size_t done = mulVecNGLV(z, xVec, myVec, n);
assert(done == n); (void)done;
return;
}
@ -1235,7 +1242,7 @@ public:
r.clear();
while (n > 0) {
EcT t;
size_t done = f(t, xVec, yVec, n);
size_t done = mulVecN(t, xVec, yVec, n);
r += t;
xVec += done;
yVec += done;
@ -1352,7 +1359,7 @@ public:
}
static inline size_t mulVecNGLV(Ec& z, const Ec *xVec, const mpz_class *yVec, size_t n)
{
const size_t N = mcl::ec::local::maxMulVecNGLV;
const size_t N = mcl::fp::maxMulVecNGLV;
if (n > N) n = N;
const int w = 5;
const mpz_class& r = Fr::getOp().mp;

@ -111,6 +111,9 @@ const size_t UnitBitSize = sizeof(Unit) * 8;
const size_t maxUnitSize = (MCL_MAX_BIT_SIZE + UnitBitSize - 1) / UnitBitSize;
#define MCL_MAX_UNIT_SIZE ((MCL_MAX_BIT_SIZE + MCL_UNIT_BIT_SIZE - 1) / MCL_UNIT_BIT_SIZE)
const size_t maxMulVecN = 32; // inner loop of mulVec
const size_t maxMulVecNGLV = 16; // inner loop of mulVec with GLV
struct FpGenerator;
struct Op;

@ -89,14 +89,24 @@ struct Operator : public E {
powArrayGLV = f;
powVecNGLV = g;
}
static void powVec(T& z, const T* xVec, const mpz_class *yVec, size_t n)
static const size_t powVecMaxN = 16;
template<class tag, size_t maxBitSize, template<class _tag, size_t _maxBitSize>class FpT>
static void powVec(T& z, const T* xVec, const FpT<tag, maxBitSize> *yVec, size_t n)
{
assert(powVecNGLV);
T r;
r.setOne();
const size_t N = mcl::fp::maxMulVecNGLV;
mpz_class myVec[N];
while (n > 0) {
T t;
size_t done = powVecNGLV(t, xVec, yVec, n);
size_t tn = fp::min_(n, N);
for (size_t i = 0; i < tn; i++) {
bool b;
yVec[i].getMpz(&b, myVec[i]);
assert(b); (void)b;
}
size_t done = powVecNGLV(t, xVec, myVec, tn);
r *= t;
xVec += done;
yVec += done;

@ -6,7 +6,6 @@ cybozu::CpuClock clk;
#include <mcl/bls12_381.hpp>
#include <cybozu/option.hpp>
#include <cybozu/xorshift.hpp>
#include "common_test.hpp"
#if defined(__EMSCRIPTEN__) && !defined(MCL_AVOID_EXCEPTION_TEST)
#define MCL_AVOID_EXCEPTION_TEST
@ -14,6 +13,8 @@ cybozu::CpuClock clk;
using namespace mcl::bls12;
#include "common_test.hpp"
mcl::fp::Mode g_mode;
const struct TestSet {
@ -384,7 +385,7 @@ CYBOZU_TEST_AUTO(naive)
testPairing(P, Q, ts.e);
testPrecomputed(P, Q);
testMillerLoop2(P, Q);
testCommon<G1, G2, GT>(P, Q);
testCommon(P, Q);
testBench(P, Q);
}
int count = (int)clk.getCount();

@ -5,7 +5,6 @@
#include <cybozu/xorshift.hpp>
#include <mcl/bn384.hpp>
#include <mcl/bn.hpp>
#include "common_test.hpp"
using namespace mcl::bn384;
@ -13,6 +12,8 @@ mcl::fp::Mode g_mode;
#include "bench.hpp"
#include "common_test.hpp"
void testCurve(const mcl::CurveParam& cp)
{
initPairing(cp, g_mode);
@ -40,7 +41,7 @@ void testCurve(const mcl::CurveParam& cp)
pairing(e2, aP, bQ);
GT::pow(e1, e1, a * b);
CYBOZU_TEST_EQUAL(e1, e2);
testCommon<G1, G2, GT>(P, Q);
testCommon(P, Q);
testBench(P, Q);
testSquareRoot();
testLagrange();

@ -5,10 +5,11 @@
#include <cybozu/xorshift.hpp>
#include <mcl/bn512.hpp>
#include <mcl/bn.hpp>
#include "common_test.hpp"
using namespace mcl::bn512;
#include "common_test.hpp"
mcl::fp::Mode g_mode;
#include "bench.hpp"
@ -34,7 +35,7 @@ void testCurve(const mcl::CurveParam& cp)
pairing(e2, aP, bQ);
GT::pow(e1, e1, a * b);
CYBOZU_TEST_EQUAL(e1, e2);
testCommon<G1, G2, GT>(P, Q);
testCommon(P, Q);
testBench(P, Q);
testSquareRoot();
testLagrange();

@ -6,7 +6,6 @@ cybozu::CpuClock clk;
#include <mcl/bn256.hpp>
#include <cybozu/option.hpp>
#include <cybozu/xorshift.hpp>
#include "common_test.hpp"
#if defined(__EMSCRIPTEN__) && !defined(MCL_AVOID_EXCEPTION_TEST)
#define MCL_AVOID_EXCEPTION_TEST
@ -15,6 +14,8 @@ cybozu::CpuClock clk;
typedef mcl::bn::local::Compress Compress;
using namespace mcl::bn;
#include "common_test.hpp"
mcl::fp::Mode g_mode;
const struct TestSet {
@ -402,7 +403,7 @@ CYBOZU_TEST_AUTO(naive)
testPrecomputed(P, Q);
testMillerLoop2(P, Q);
testMillerLoopVec();
testCommon<G1, G2, GT>(P, Q);
testCommon(P, Q);
testBench(P, Q);
benchAddDblG1();
benchAddDblG2();

@ -1,5 +1,5 @@
template<class G>
void naiveMulVec(G& out, const G *xVec, const mpz_class *yVec, size_t n)
void naiveMulVec(G& out, const G *xVec, const Fr *yVec, size_t n)
{
if (n == 1) {
G::mul(out, xVec[0], yVec[0]);
@ -20,11 +20,11 @@ void testMulVec(const G& P)
using namespace mcl::bn;
const int N = 33;
G xVec[N];
mpz_class yVec[N];
Fr yVec[N];
for (size_t i = 0; i < N; i++) {
G::mul(xVec[i], P, i + 3);
mcl::gmp::getRand(yVec[i], Fr::getOp().bitSize);
yVec[i].setByCSPRNG();
}
const size_t nTbl[] = { 1, 2, 3, 5, 7, 8, 9, 14, 15, 16, 30, 31, 32, 33 };
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(nTbl); i++) {
@ -44,7 +44,7 @@ void testMulVec(const G& P)
}
template<class G>
void naivePowVec(G& out, const G *xVec, const mpz_class *yVec, size_t n)
void naivePowVec(G& out, const G *xVec, const Fr *yVec, size_t n)
{
if (n == 1) {
G::pow(out, xVec[0], yVec[0]);
@ -65,12 +65,12 @@ inline void testPowVec(const G& e)
using namespace mcl::bn;
const int N = 33;
G xVec[N];
mpz_class yVec[N];
Fr yVec[N];
xVec[0] = e;
for (size_t i = 0; i < N; i++) {
if (i > 0) G::mul(xVec[i], xVec[i - 1], e);
mcl::gmp::getRand(yVec[i], Fr::getOp().bitSize);
yVec[i].setByCSPRNG();
}
const size_t nTbl[] = { 1, 2, 3, 5, 7, 8, 9, 14, 15, 16, 30, 31, 32, 33 };
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(nTbl); i++) {
@ -89,7 +89,6 @@ inline void testPowVec(const G& e)
}
}
template<class G1, class G2, class GT>
void testCommon(const G1& P, const G2& Q)
{
puts("G1");

@ -532,7 +532,7 @@ private:
void operator=(const Test&);
};
void naiveMulVec(Ec& out, const Ec *xVec, const mpz_class *yVec, size_t n)
void naiveMulVec(Ec& out, const Ec *xVec, const Zn *yVec, size_t n)
{
Ec r, t;
r.clear();
@ -552,25 +552,27 @@ void mulVec(const mcl::EcParam& para)
P += P;
const int N = 33;
Ec xVec[N];
mpz_class yVec[N];
Zn yVec[N];
Ec Q1, Q2;
Ec::dbl(P, P);
for (size_t i = 0; i < N; i++) {
Ec::mul(xVec[i], P, i + 3);
mcl::gmp::getRand(yVec[i], Zn::getOp().bitSize);
yVec[i].setByCSPRNG();
}
const size_t nTbl[] = { 1, 2, 3, 5, 30, 31, 32, 33 };
const int C = 400;
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(nTbl); i++) {
const size_t n = nTbl[i];
CYBOZU_TEST_ASSERT(n <= N);
naiveMulVec(Q1, xVec, yVec, n);
Ec::mulVec(Q2, xVec, yVec, n);
CYBOZU_TEST_EQUAL(Q1, Q2);
#ifndef NDEBUG
printf("n=%zd\n", n);
const int C = 400;
CYBOZU_BENCH_C("naive ", C, naiveMulVec, Q1, xVec, yVec, n);
CYBOZU_BENCH_C("mulVec", C, Ec::mulVec, Q1, xVec, yVec, n);
#endif
}
}

Loading…
Cancel
Save