aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2017-01-28 17:18:45 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2017-01-28 17:18:45 +0800
commit90d7bbe2b605d4f1179421541d590a93620c923a (patch)
treec00b8c25e6a2680071f17c22979892722f4dddde
parent74975e85c83c98f67b4a954764fe5d2de726a822 (diff)
downloaddexon-mcl-90d7bbe2b605d4f1179421541d590a93620c923a.tar.gz
dexon-mcl-90d7bbe2b605d4f1179421541d590a93620c923a.tar.zst
dexon-mcl-90d7bbe2b605d4f1179421541d590a93620c923a.zip
fix ; ensure that the elements by mapTo.calcG2 is in G2
-rw-r--r--include/mcl/bn.hpp22
-rw-r--r--include/mcl/ec.hpp15
-rw-r--r--java/bn256.i12
-rw-r--r--test/bn_test.cpp12
4 files changed, 46 insertions, 15 deletions
diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp
index e9097da..d417990 100644
--- a/include/mcl/bn.hpp
+++ b/include/mcl/bn.hpp
@@ -109,12 +109,13 @@ bool getGoodRepl(Vec& v, const mpz_class& x)
}
template<class Fp>
-struct MapTo {
+struct MapToT {
typedef mcl::Fp2T<Fp> Fp2;
typedef mcl::EcT<Fp> G1;
typedef mcl::EcT<Fp2> G2;
Fp c1; // sqrt(-3)
Fp c2; // (-1 + sqrt(-3)) / 2
+ mpz_class cofactor;
int legendre(const Fp& x) const
{
return gmp::legendre(x.getMpz(), Fp::getOp().mp);
@@ -160,12 +161,16 @@ struct MapTo {
}
}
ERR_POINT:
- throw cybozu::Exception("MapTo:calc:bad") << t;
+ throw cybozu::Exception("MapToT:calc:bad") << t;
}
- MapTo()
+ /*
+ cofactor is for G2
+ */
+ void init(const mpz_class& cofactor)
{
- if (!Fp::squareRoot(c1, -3)) throw cybozu::Exception("MapTo:c1");
+ if (!Fp::squareRoot(c1, -3)) throw cybozu::Exception("MapToT:init:c1");
c2 = (c1 - 1) / 2;
+ this->cofactor = cofactor;
}
/*
P.-A. Fouque and M. Tibouchi,
@@ -178,9 +183,15 @@ struct MapTo {
{
calc<G1, Fp>(P, t);
}
+ /*
+ get the element in G2 by multiplying the cofactor
+ */
void calcG2(G2& P, const Fp2& t) const
{
calc<G2, Fp2>(P, t);
+ assert(cofactor != 0);
+ G2::mul(P, P, cofactor);
+ assert(!P.isZero());
}
};
@@ -215,6 +226,7 @@ struct ParamT {
mpz_class exp_c0;
mpz_class exp_c1;
mpz_class exp_c2;
+ MapToT<Fp> mapTo;
// Loop parameter for the Miller loop part of opt. ate pairing.
typedef std::vector<int8_t> SignVec;
@@ -249,6 +261,8 @@ struct ParamT {
is_b_div_xi_1_m1i = b_div_xi == Fp2(1, -1);
G1::init(0, b, mcl::ec::Proj);
G2::init(0, b_div_xi, mcl::ec::Proj);
+ G2::setOrder(r);
+ mapTo.init(2 * p - r);
Fp2::pow(g[0], xi, (p - 1) / 6); // g = xi^((p-1)/6)
for (size_t i = 1; i < gN; i++) {
diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp
index 044cfd4..432ef63 100644
--- a/include/mcl/ec.hpp
+++ b/include/mcl/ec.hpp
@@ -55,6 +55,12 @@ public:
static Fp b_;
static int specialA_;
static bool compressedExpression_;
+ /*
+ order_ is the order of G2 which is the subgroup of EcT<Fp2>.
+ check the order of the elements if verifyOrder_ is true
+ */
+ static bool verifyOrder_;
+ static mpz_class order_;
#ifdef MCL_EC_USE_AFFINE
EcT() : inf_(true) {}
#else
@@ -152,6 +158,8 @@ public:
} else {
specialA_ = generic;
}
+ verifyOrder_ = false;
+ order_ = 0;
#ifdef MCL_EC_USE_AFFINE
cybozu::disable_warning_unused_variable(mode);
#else
@@ -165,6 +173,11 @@ public:
}
#endif
}
+ static inline void setOrder(const mpz_class& order)
+ {
+ verifyOrder_ = true;
+ order_ = order;
+ }
// backward compatilibity
static inline void setParam(const std::string& astr, const std::string& bstr, int mode = ec::Jacobi)
{
@@ -738,6 +751,8 @@ template<class Fp> Fp EcT<Fp>::a_;
template<class Fp> Fp EcT<Fp>::b_;
template<class Fp> int EcT<Fp>::specialA_;
template<class Fp> bool EcT<Fp>::compressedExpression_;
+template<class Fp> bool EcT<Fp>::verifyOrder_;
+template<class Fp> mpz_class EcT<Fp>::order_;
#ifndef MCL_EC_USE_AFFINE
template<class Fp> int EcT<Fp>::mode_;
#endif
diff --git a/java/bn256.i b/java/bn256.i
index 848d116..94a8edb 100644
--- a/java/bn256.i
+++ b/java/bn256.i
@@ -9,26 +9,20 @@
#include <cybozu/crypto.hpp>
#include <mcl/bn256.hpp>
struct Param {
- cybozu::RandomGenerator rg;
- mcl::bn::MapTo<mcl::bn256::Fp> mapTo;
- static inline Param& getParam()
+ cybozu::RandomGenerator rg;
+ static inline Param& getParam()
{
static Param p;
return p;
}
};
-static void mapToG1(mcl::bn256::G1& P, const mcl::bn256::Fp& t)
-{
- static mcl::bn::MapTo<mcl::bn256::Fp> mapTo;
- mapTo.calcG1(P, t);
-}
static void HashAndMapToG1(mcl::bn256::G1& P, const std::string& m)
{
std::string digest = cybozu::crypto::Hash::digest(cybozu::crypto::Hash::N_SHA256, m);
mcl::bn256::Fp t;
t.setArrayMask(digest.c_str(), digest.size());
- mapToG1(P, t);
+ mcl::bn256::BN::param.mapTo.calcG1(P, t);
}
#include "bn256_impl.hpp"
diff --git a/test/bn_test.cpp b/test/bn_test.cpp
index be99cf8..363217a 100644
--- a/test/bn_test.cpp
+++ b/test/bn_test.cpp
@@ -99,11 +99,15 @@ void testSetStr(const G2& Q0)
void testMapToG1()
{
- mcl::bn::MapTo<Fp> mapTo;
+ const mcl::bn::MapToT<Fp>& mapTo = BN::param.mapTo;
G1 g;
for (int i = 1; i < 10; i++) {
mapTo.calcG1(g, i);
+ CYBOZU_TEST_ASSERT(!g.isZero());
+ G1 gr;
+ G1::mul(gr, g, BN::param.r);
+ CYBOZU_TEST_ASSERT(gr.isZero());
}
if (BN::param.b == 2) {
CYBOZU_TEST_EXCEPTION(mapTo.calcG1(g, 0), cybozu::Exception);
@@ -114,11 +118,15 @@ void testMapToG1()
void testMapToG2()
{
- mcl::bn::MapTo<Fp> mapTo;
+ const mcl::bn::MapToT<Fp>& mapTo = BN::param.mapTo;
G2 g;
for (int i = 1; i < 10; i++) {
mapTo.calcG2(g, i);
+ CYBOZU_TEST_ASSERT(!g.isZero());
+ G2 gr;
+ G2::mul(gr, g, BN::param.r);
+ CYBOZU_TEST_ASSERT(gr.isZero());
}
if (BN::param.b == 2) {
CYBOZU_TEST_EXCEPTION(mapTo.calcG2(g, 0), cybozu::Exception);