add cahce of secretKey

dev
MITSUNARI Shigeo 8 years ago
parent 7531fabca4
commit ac1e0234a0
  1. 80
      include/mcl/bgn.hpp
  2. 28
      test/bgn_test.cpp

@ -25,6 +25,71 @@ namespace mcl { namespace bgn {
namespace local {
struct KeyCount {
uint32_t key;
int32_t count; // power
bool operator<(const KeyCount& rhs) const
{
return key < rhs.key;
}
};
template<class G>
class MulTbl {
typedef std::vector<KeyCount> KeyCountVec;
KeyCountVec kcv;
G P_;
public:
void init(const G& P, size_t maxSize)
{
if (maxSize == 0) throw cybozu::Exception("MulTbl:init:zero maxSize");
P_ = P;
kcv.resize(maxSize - 1);
G xP;
xP.clear();
for (int i = 1; i < (int)maxSize; i++) {
xP += P;
xP.normalize();
kcv[i - 1].key = uint32_t(*xP.x.getUnit());
kcv[i - 1].count = xP.y.isOdd() ? i : -i;
}
/*
ascending order of abs(count) for same key
*/
std::stable_sort(kcv.begin(), kcv.end());
}
int logG(G xP) const
{
if (xP.isZero()) return 0;
typedef KeyCountVec::const_iterator Iter;
KeyCount kc;
xP.normalize();
kc.key = uint32_t(*xP.x.getUnit());
kc.count = 0;
std::pair<Iter, Iter> p = std::equal_range(kcv.begin(), kcv.end(), kc);
G Q;
Q.clear();
int prev = 0;
while (p.first != p.second) {
int count = p.first->count;
int abs_c = std::abs(count);
assert(abs_c >= prev);
bool neg = count < 0;
G T;
G::mul(T, P_, abs_c - prev);
Q += T;
Q.normalize();
if (Q.x == xP.x) {
if (Q.y.isOdd() ^ xP.y.isOdd() ^ neg) return -count;
return count;
}
prev = abs_c;
++p.first;
}
throw cybozu::Exception("MuTbl:logG:not found");
}
};
template<class G>
int logG(const G& P, const G& xP)
{
@ -77,9 +142,10 @@ struct BGNT {
G2 B2; // (x2 y2 - z2) Q
Fr x1x2;
GT g; // e(B1, B2)
local::MulTbl<G1> mulTbl;
public:
template<class RG>
void setRand(RG& rg)
void init(size_t maxSize, RG& rg)
{
x1.setRand(rg);
y1.setRand(rg);
@ -91,6 +157,7 @@ struct BGNT {
G2::mul(B2, Q, x2 * y2 - z2);
x1x2 = x1 * x2;
BN::pairing(g, B1, B2);
mulTbl.init(B1, maxSize);
}
/*
set (xP, yP, zP) and (xQ, yQ, zQ)
@ -132,8 +199,9 @@ struct BGNT {
G1 R1;
G1::mul(R1, c.S1, x1);
R1 -= c.T1;
int m1 = local::logG(B1, R1);
#if 1 // for debug
// int m1 = local::logG(B1, R1);
int m1 = mulTbl.logG(R1);
#if 0 // for debug
G2 R2;
G2::mul(R2, c.S2, x2);
R2 -= c.T2;
@ -195,6 +263,10 @@ struct BGNT {
void rerandomize(CipherText& c, RG& rg) const
{
if (c.isMultiplied()) {
/*
add Enc(0) * Enc(0)
(S1, T1) * (S2, T2) = (rP, rxP) * (r'Q, r'xQ)
*/
G1 S1, T1;
G2 S2, T2;
Fr r;
@ -260,7 +332,7 @@ struct BGNT {
throw cybozu::Exception("bgn:CipherText:mul:already mul");
}
/*
(S, T) * (S', T') = (e(S, S'), e(S, T'), e(T, S'), e(T, T'))
(S1, T1) * (S2, T2) = (e(S1, S2), e(S1, T2), e(T1, S2), e(T1, T2))
*/
z.g.resize(4);
BN::pairing(z.g[0], x.S1, y.S2);

@ -13,11 +13,13 @@ typedef BGN::PublicKey PublicKey;
typedef BGN::CipherText CipherText;
using namespace mcl::bgn;
using namespace mcl::bn256;
SecretKey g_sec;
CYBOZU_TEST_AUTO(logG)
{
BGN::init();
using namespace mcl::bn256;
G1 P;
BN::hashAndMapToG1(P, "abc");
for (int i = -5; i < 5; i++) {
@ -27,10 +29,24 @@ CYBOZU_TEST_AUTO(logG)
}
}
CYBOZU_TEST_AUTO(MulTbl)
{
mcl::bgn::local::MulTbl<G1> mulTbl;
G1 P;
BN::hashAndMapToG1(P, "abc");
const int maxSize = 100;
mulTbl.init(P, maxSize);
for (int i = -maxSize + 1; i < maxSize; i++) {
G1 xP;
G1::mul(xP, P, i);
CYBOZU_TEST_EQUAL(mulTbl.logG(xP), i);
}
}
CYBOZU_TEST_AUTO(enc_dec)
{
SecretKey sec;
sec.setRand(rg);
SecretKey& sec = g_sec;
sec.init(100, rg);
PublicKey pub;
sec.getPublicKey(pub);
CipherText c;
@ -44,8 +60,7 @@ CYBOZU_TEST_AUTO(enc_dec)
CYBOZU_TEST_AUTO(add_mul)
{
SecretKey sec;
sec.setRand(rg);
const SecretKey& sec = g_sec;
PublicKey pub;
sec.getPublicKey(pub);
for (int m1 = -5; m1 < 5; m1++) {
@ -67,8 +82,7 @@ CYBOZU_TEST_AUTO(add_mul)
CYBOZU_TEST_AUTO(add_mul_add)
{
SecretKey sec;
sec.setRand(rg);
const SecretKey& sec = g_sec;
PublicKey pub;
sec.getPublicKey(pub);
int m[8] = { 1, -2, 3, 4, -5, 6, -7, 8 };

Loading…
Cancel
Save