add GTHashTable

dev
MITSUNARI Shigeo 8 years ago
parent 88cce16481
commit 1fa9768f3c
  1. 122
      include/mcl/bgn.hpp
  2. 28
      test/bgn_test.cpp

@ -142,7 +142,116 @@ public:
return negCenter + c;
}
}
throw cybozu::Exception("HashTable:log:not found");
throw cybozu::Exception("EcHashTable:log:not found");
}
};
template<class GT>
class GTHashTable {
typedef std::vector<KeyCount> KeyCountVec;
KeyCountVec kcv;
GT g;
GT nextg;
GT nextgInv;
int hashSize;
size_t tryNum;
public:
GTHashTable() : hashSize(0), tryNum(0) {}
/*
compute log_P(g^x) for |x| <= hashSize * (tryNum + 1)
*/
void init(const GT& g, int hashSize, size_t tryNum = 0)
{
if (hashSize == 0) throw cybozu::Exception("GTHashTable:init:zero hashSize");
this->g = g;
this->hashSize = hashSize;
this->tryNum = tryNum;
kcv.resize(hashSize);
GT gx = 1;
for (int i = 1; i <= hashSize; i++) {
gx *= g;
kcv[i - 1].key = uint32_t(*gx.getFp0()->getUnit());
kcv[i - 1].count = gx.b.a.a.isOdd() ? i : -i;
}
nextg = gx;
GT::sqr(nextg, nextg);
nextg *= g; // nextg = g^(hasSize * 2 + 1)
GT::unitaryInv(nextgInv, nextg);
/*
ascending order of abs(count) for same key
*/
std::stable_sort(kcv.begin(), kcv.end());
}
/*
log_P(g^x)
find range which has same hash of gx in kcv,
and detect it
*/
int basicLog(const GT& gx, bool *ok = 0) const
{
if (ok) *ok = true;
if (gx.isOne()) return 0;
typedef KeyCountVec::const_iterator Iter;
KeyCount kc;
kc.key = uint32_t(*gx.getFp0()->getUnit());
kc.count = 0;
std::pair<Iter, Iter> p = std::equal_range(kcv.begin(), kcv.end(), kc);
GT Q = 1;
int prev = 0;
/*
check range which has same hash
*/
while (p.first != p.second) {
int count = p.first->count;
int abs_c = std::abs(count);
assert(abs_c >= prev); // assume ascending order
bool neg = count < 0;
GT T;
GT::pow(T, g, abs_c - prev);
Q *= T;
if (Q.a == gx.a) {
if (Q.b.a.a.isOdd() ^ gx.b.a.a.isOdd() ^ neg) return -count;
return count;
}
prev = abs_c;
++p.first;
}
if (ok) {
*ok = false;
return 0;
}
throw cybozu::Exception("GTHashTable:basicLog:not found");
}
/*
compute log_P(g^x)
call basicLog at most 2 * tryNum + 1
*/
int64_t log(const GT& gx) const
{
bool ok;
int c = basicLog(gx, &ok);
if (ok) {
return c;
}
GT pos = gx, neg = gx;
int64_t posCenter = 0;
int64_t negCenter = 0;
int64_t next = hashSize * 2 + 1;
for (size_t i = 0; i < tryNum; i++) {
pos *= nextgInv;
posCenter += next;
c = basicLog(pos, &ok);
if (ok) {
return posCenter + c;
}
neg *= nextg;
negCenter -= next;
c = basicLog(neg, &ok);
if (ok) {
return negCenter + c;
}
}
throw cybozu::Exception("GTHashTable:log:not found");
}
};
@ -198,7 +307,8 @@ struct BGNT {
G2 B2; // (x2 y2 - z2) Q
Fr x1x2;
GT g; // e(B1, B2)
local::EcHashTable<G1> hashTbl;
local::EcHashTable<G1> ecHashTbl;
local::GTHashTable<GT> gtHashTbl;
public:
template<class RG>
void setByCSPRNG(RG& rg)
@ -216,7 +326,8 @@ struct BGNT {
}
void setDecodeRange(size_t hashSize)
{
hashTbl.init(B1, hashSize);
ecHashTbl.init(B1, hashSize);
gtHashTbl.init(g, hashSize);
}
/*
set (xP, yP, zP) and (xQ, yQ, zQ)
@ -259,7 +370,7 @@ struct BGNT {
G1::mul(R1, c.S1, x1);
R1 -= c.T1;
// int m1 = local::log(B1, R1);
int m1 = hashTbl.log(R1);
int m1 = ecHashTbl.log(R1);
#if 0 // for debug
G2 R2;
G2::mul(R2, c.S2, x2);
@ -288,7 +399,8 @@ struct BGNT {
GT::unitaryInv(t, t);
s *= t;
BN::finalExp(s, s);
return log(g, s);
return gtHashTbl.log(s);
// return log(g, s);
}
};

@ -34,7 +34,7 @@ CYBOZU_TEST_AUTO(EcHashTable)
mcl::bgn::local::EcHashTable<G1> hashTbl;
G1 P;
BN::hashAndMapToG1(P, "abc");
const int maxSize = 10;
const int maxSize = 100;
const int tryNum = 3;
hashTbl.init(P, maxSize, tryNum);
for (int i = -maxSize; i <= maxSize; i++) {
@ -49,6 +49,32 @@ CYBOZU_TEST_AUTO(EcHashTable)
}
}
CYBOZU_TEST_AUTO(GTHashTable)
{
mcl::bgn::local::GTHashTable<GT> hashTbl;
GT g;
{
G1 P;
BN::hashAndMapToG1(P, "abc");
G2 Q;
BN::hashAndMapToG2(Q, "abc");
BN::pairing(g, P, Q);
}
const int maxSize = 100;
const int tryNum = 3;
hashTbl.init(g, maxSize, tryNum);
for (int i = -maxSize; i <= maxSize; i++) {
GT gx;
GT::pow(gx, g, i);
CYBOZU_TEST_EQUAL(hashTbl.basicLog(gx), i);
}
for (int i = -maxSize * tryNum; i <= maxSize * tryNum; i++) {
GT gx;
GT::pow(gx, g, i);
CYBOZU_TEST_EQUAL(hashTbl.log(gx), i);
}
}
CYBOZU_TEST_AUTO(enc_dec)
{
SecretKey& sec = g_sec;

Loading…
Cancel
Save