aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2019-07-25 13:56:45 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2019-07-25 13:56:45 +0800
commit53028c4a98817ad62ac916ad90c008d4a13cc567 (patch)
tree4161f6e48f9249e253cdfc359c642fbcd891a98b
parent2762669e4c7f11198bce7a86290b80982447320c (diff)
downloadtangerine-mcl-53028c4a98817ad62ac916ad90c008d4a13cc567.tar.gz
tangerine-mcl-53028c4a98817ad62ac916ad90c008d4a13cc567.tar.zst
tangerine-mcl-53028c4a98817ad62ac916ad90c008d4a13cc567.zip
GLV1 is template class
-rw-r--r--include/mcl/bn.hpp86
-rw-r--r--test/ecdsa_test.cpp12
-rw-r--r--test/glv_test.cpp20
3 files changed, 62 insertions, 56 deletions
diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp
index 02f58f2..3c5959b 100644
--- a/include/mcl/bn.hpp
+++ b/include/mcl/bn.hpp
@@ -577,14 +577,15 @@ void addTbl(G& Q, const G *tbl, const NafArray& naf, size_t i)
Software implementation of Attribute-Based Encryption: Appendixes
GLV for G1 on BN/BLS12
*/
-struct GLV1 {
- Fp rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2
- size_t rBitSize;
- mpz_class v0, v1;
- mpz_class B[2][2];
- mpz_class r;
+template<class F, class G>
+struct GLV1T {
+ static F rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2
+ static size_t rBitSize;
+ static mpz_class v0, v1;
+ static mpz_class B[2][2];
+ static mpz_class r;
private:
- bool usePrecomputedTable(int curveType)
+ static bool usePrecomputedTable(int curveType)
{
if (curveType < 0) return false;
const struct Tbl {
@@ -631,19 +632,12 @@ private:
return false;
}
public:
- bool operator==(const GLV1& rhs) const
- {
- return rw == rhs.rw && rBitSize == rhs.rBitSize && v0 == rhs.v0 && v1 == rhs.v1
- && B[0][0] == rhs.B[0][0] && B[0][1] == rhs.B[0][1] && B[1][0] == rhs.B[1][0]
- && B[1][1] == rhs.B[1][1] && r == rhs.r;
- }
- bool operator!=(const GLV1& rhs) const { return !operator==(rhs); }
#ifndef CYBOZU_DONT_USE_STRING
- void dump(const mpz_class& x) const
+ static void dump(const mpz_class& x)
{
printf("\"%s\",\n", mcl::gmp::getStr(x, 16).c_str());
}
- void dump() const
+ static void dump()
{
printf("\"%s\",\n", rw.getStr(16).c_str());
printf("%d,\n", (int)rBitSize);
@@ -653,14 +647,14 @@ public:
dump(r);
}
#endif
- void init(const mpz_class& r, const mpz_class& z, bool isBLS12 = false, int curveType = -1)
+ static void init(const mpz_class& _r, const mpz_class& z, bool isBLS12 = false, int curveType = -1)
{
if (usePrecomputedTable(curveType)) return;
- bool b = Fp::squareRoot(rw, -3);
+ bool b = F::squareRoot(rw, -3);
assert(b);
(void)b;
rw = -(rw + 1) / 2;
- this->r = r;
+ r = _r;
rBitSize = gmp::getBitSize(r);
rBitSize = (rBitSize + fp::UnitBitSize - 1) & ~(fp::UnitBitSize - 1);// a little better size
if (isBLS12) {
@@ -694,16 +688,16 @@ public:
L = lambda = p^4
L (x, y) = (rw x, y)
*/
- void mulLambda(G1& Q, const G1& P) const
+ static void mulLambda(G& Q, const G& P)
{
- Fp::mul(Q.x, P.x, rw);
+ F::mul(Q.x, P.x, rw);
Q.y = P.y;
Q.z = P.z;
}
/*
x = a + b * lambda mod r
*/
- void split(mpz_class& a, mpz_class& b, const mpz_class& x) const
+ static void split(mpz_class& a, mpz_class& b, const mpz_class& x)
{
mpz_class t;
t = (x * v0) >> rBitSize;
@@ -711,13 +705,13 @@ public:
a = x - (t * B[0][0] + b * B[1][0]);
b = - (t * B[0][1] + b * B[1][1]);
}
- void mul(G1& Q, const G1& P, mpz_class x, bool constTime = false) const
+ static void mul(G& Q, const G& P, mpz_class x, bool constTime = false)
{
const int w = 5;
const size_t tblSize = 1 << (w - 2);
NafArray naf[2];
mpz_class u[2];
- G1 tbl[2][tblSize];
+ G tbl[2][tblSize];
bool b;
x %= r;
@@ -737,22 +731,43 @@ public:
tbl[0][0] = P;
mulLambda(tbl[1][0], tbl[0][0]);
{
- G1 P2;
- G1::dbl(P2, P);
+ G P2;
+ G::dbl(P2, P);
for (size_t i = 1; i < tblSize; i++) {
- G1::add(tbl[0][i], tbl[0][i - 1], P2);
+ G::add(tbl[0][i], tbl[0][i - 1], P2);
mulLambda(tbl[1][i], tbl[0][i]);
}
}
const size_t maxBit = fp::max_(naf[0].size(), naf[1].size());
Q.clear();
for (size_t i = 0; i < maxBit; i++) {
- G1::dbl(Q, Q);
+ G::dbl(Q, Q);
addTbl(Q, tbl[0], naf[0], maxBit - 1 - i);
addTbl(Q, tbl[1], naf[1], maxBit - 1 - i);
}
}
+ static void mulArray(G& z, const G& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime)
+ {
+ mpz_class s;
+ bool b;
+ mcl::gmp::setArray(&b, s, y, yn);
+ assert(b);
+ if (isNegative) s = -s;
+ mul(z, x, s, constTime);
+ }
};
+template<class F, class G>
+F GLV1T<F, G>::rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2
+template<class F, class G>
+size_t GLV1T<F, G>::rBitSize;
+template<class F, class G>
+mpz_class GLV1T<F, G>::v0;
+template<class F, class G>
+mpz_class GLV1T<F, G>::v1;
+template<class F, class G>
+mpz_class GLV1T<F, G>::B[2][2];
+template<class F, class G>
+mpz_class GLV1T<F, G>::r;
/*
GLV method for G2 and GT on BN/BLS12
@@ -1035,7 +1050,7 @@ struct Param {
mpz_class p;
mpz_class r;
local::MapTo mapTo;
- local::GLV1 glv1;
+ typedef local::GLV1T<Fp, G1> GLV1;
local::GLV2 glv2;
// for G2 Frobenius
Fp2 g2;
@@ -1151,7 +1166,7 @@ struct Param {
} else {
mapTo.init(2 * p - r, z, cp.curveType);
}
- glv1.init(r, z, isBLS12, cp.curveType);
+ GLV1::init(r, z, isBLS12, cp.curveType);
glv2.init(r, z, isBLS12);
basePoint.clear();
*pb = true;
@@ -1200,15 +1215,6 @@ static const local::Param& param = local::StaticVar<>::param;
namespace local {
-inline void mulArrayGLV1(G1& z, const G1& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime)
-{
- mpz_class s;
- bool b;
- mcl::gmp::setArray(&b, s, y, yn);
- assert(b);
- if (isNegative) s = -s;
- BN::param.glv1.mul(z, x, s, constTime);
-}
inline void mulArrayGLV2(G2& z, const G2& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime)
{
mpz_class s;
@@ -2227,7 +2233,7 @@ inline void init(bool *pb, const mcl::CurveParam& cp = mcl::BN254, fp::Mode mode
{
local::StaticVar<>::param.init(pb, cp, mode);
if (!*pb) return;
- G1::setMulArrayGLV(local::mulArrayGLV1);
+ G1::setMulArrayGLV(bn::local::Param::GLV1::mulArray);
G2::setMulArrayGLV(local::mulArrayGLV2);
Fp12::setPowArrayGLV(local::powArrayGLV2);
G1::setCompressedExpression();
diff --git a/test/ecdsa_test.cpp b/test/ecdsa_test.cpp
index 8a766ea..28f689e 100644
--- a/test/ecdsa_test.cpp
+++ b/test/ecdsa_test.cpp
@@ -81,10 +81,10 @@ public:
void split(mpz_class& a, mpz_class& b, const mpz_class& x) const
{
mpz_class t;
-// t = (x * v0) >> rBitSize;
-// b = (x * v1) >> rBitSize;
-t = (B[1][1] * x) / r;
-b = (-B[0][1] * x) / r;
+ t = (x * v0) >> rBitSize;
+ b = (x * v1) >> rBitSize;
+//t = (B[1][1] * x) / r;
+//b = (-B[0][1] * x) / r;
a = x - (t * B[0][0] + b * B[1][0]);
b = - (t * B[0][1] + b * B[1][1]);
}
@@ -161,8 +161,8 @@ void initGLV()
gmp::setStr(glv1.B[0][1], "-0xe4437ed6010e88286f547fa90abfe4c3");
gmp::setStr(glv1.B[1][0], "0x114ca50f7a8e2f3f657c1108d9d44cfd8");
glv1.B[1][1] = glv1.B[0][0];
- glv1.v0 = ((-glv1.B[1][1]) << glv1.rBitSize) / glv1.r;
- glv1.v1 = ((glv1.B[1][0]) << glv1.rBitSize) / glv1.r;
+ glv1.v0 = ((glv1.B[1][1]) << glv1.rBitSize) / glv1.r;
+ glv1.v1 = ((-glv1.B[0][1]) << glv1.rBitSize) / glv1.r;
}
PUT(p.P);
Ec Q1, Q2;
diff --git a/test/glv_test.cpp b/test/glv_test.cpp
index 0e6fccd..79d378f 100644
--- a/test/glv_test.cpp
+++ b/test/glv_test.cpp
@@ -77,7 +77,7 @@ struct oldGLV {
};
template<class GLV1, class GLV2>
-void compareLength(const GLV1& rhs, const GLV2& lhs)
+void compareLength(const GLV2& lhs)
{
cybozu::XorShift rg;
int lt = 0;
@@ -88,7 +88,7 @@ void compareLength(const GLV1& rhs, const GLV2& lhs)
for (int i = 1; i < 1000; i++) {
r.setRand(rg);
x = r.getMpz();
- rhs.split(R0, R1, x);
+ GLV1::split(R0, R1, x);
lhs.split(L0, L1, x);
size_t R0n = mcl::gmp::getBitSize(R0);
@@ -121,10 +121,10 @@ void testGLV1()
oldGlv.init(BN::param.r, BN::param.z);
}
- mcl::bn::local::GLV1 glv;
- glv.init(BN::param.r, BN::param.z, BN::param.isBLS12);
+ typedef mcl::bn::local::Param::GLV1 GLV1;
+ GLV1::init(BN::param.r, BN::param.z, BN::param.isBLS12);
if (!BN::param.isBLS12) {
- compareLength(glv, oldGlv);
+ compareLength<GLV1>(oldGlv);
}
for (int i = 1; i < 100; i++) {
@@ -133,9 +133,9 @@ void testGLV1()
s.setRand(rg);
mpz_class ss = s.getMpz();
G1::mulGeneric(P1, P0, ss);
- glv.mul(P2, P0, ss);
+ GLV1::mul(P2, P0, ss);
CYBOZU_TEST_EQUAL(P1, P2);
- glv.mul(P2, P0, ss, true);
+ GLV1::mul(P2, P0, ss, true);
CYBOZU_TEST_EQUAL(P1, P2);
if (!BN::param.isBLS12) {
oldGlv.mul(P2, P0, ss);
@@ -145,15 +145,15 @@ void testGLV1()
for (int i = -100; i < 100; i++) {
mpz_class ss = i;
G1::mulGeneric(P1, P0, ss);
- glv.mul(P2, P0, ss);
+ GLV1::mul(P2, P0, ss);
CYBOZU_TEST_EQUAL(P1, P2);
- glv.mul(P2, P0, ss, true);
+ GLV1::mul(P2, P0, ss, true);
CYBOZU_TEST_EQUAL(P1, P2);
}
Fr s;
mapToG1(P0, 123);
CYBOZU_BENCH_C("Ec::mul", 100, P1 = P0; s.setRand(rg); G1::mulGeneric, P2, P1, s.getMpz());
- CYBOZU_BENCH_C("Ec::glv", 100, P1 = P0; s.setRand(rg); glv.mul, P2, P1, s.getMpz());
+ CYBOZU_BENCH_C("Ec::glv", 100, P1 = P0; s.setRand(rg); GLV1::mul, P2, P1, s.getMpz());
}
/*