reduce public key size of bgn

dev
MITSUNARI Shigeo 7 years ago
parent 53175e88e6
commit a3ed208bb6
  1. 172
      include/mcl/bgn.hpp

@ -391,7 +391,7 @@ private:
static inline void tensorProduct(GT g[4], const G1& S1, const G1& T1, const G2& S2, const G2& T2) static inline void tensorProduct(GT g[4], const G1& S1, const G1& T1, const G2& S2, const G2& T2)
{ {
/* /*
(S1, T1) x (S2, T2) (S1, T1) x (S2, T2) = (e(S1, S2), e(S1, T2), e(T1, S2), e(T1, T2))
*/ */
#if 1 #if 1
#ifdef MCL_USE_BN384 #ifdef MCL_USE_BN384
@ -430,31 +430,20 @@ public:
} }
class SecretKey { class SecretKey {
Fr x1, y1, z1; Fr x, y;
Fr x2, y2, z2; GT g; // e(P, Q)
G1 B1; // (x1 y1 - z1) P
G2 B2; // (x2 y2 - z2) Q
Fr x1x2;
GT g; // e(B1, B2)
local::EcHashTable<G1> g1HashTbl; local::EcHashTable<G1> g1HashTbl;
local::GTHashTable<GT> gtHashTbl; local::GTHashTable<GT> gtHashTbl;
void initInner() void initInner()
{ {
G1::mul(B1, P, x1 * y1 - z1); BN::pairing(g, P, Q);
G2::mul(B2, Q, x2 * y2 - z2);
x1x2 = x1 * x2;
BN::pairing(g, B1, B2);
} }
public: public:
template<class RG> template<class RG>
void setByCSPRNG(RG& rg) void setByCSPRNG(RG& rg)
{ {
x1.setRand(rg); x.setRand(rg);
y1.setRand(rg); y.setRand(rg);
z1.setRand(rg);
x2.setRand(rg);
y2.setRand(rg);
z2.setRand(rg);
initInner(); initInner();
} }
void setByCSPRNG() { setByCSPRNG(local::g_rg); } void setByCSPRNG() { setByCSPRNG(local::g_rg); }
@ -463,7 +452,7 @@ public:
*/ */
void setRangeForG1DLP(size_t hashSize, size_t tryNum = 0) void setRangeForG1DLP(size_t hashSize, size_t tryNum = 0)
{ {
g1HashTbl.init(B1, hashSize, tryNum); g1HashTbl.init(P, hashSize, tryNum);
} }
/* /*
set range for GT-DLP set range for GT-DLP
@ -484,16 +473,12 @@ public:
setRangeForGTDLP(hashSize, tryNum); setRangeForGTDLP(hashSize, tryNum);
} }
/* /*
set (xP, yP, zP) and (xQ, yQ, zQ) set xP and yQ
*/ */
void getPublicKey(PublicKey& pub) const void getPublicKey(PublicKey& pub) const
{ {
G1::mul(pub.xP, P, x1); G1::mul(pub.xP, P, x);
G1::mul(pub.yP, P, y1); G2::mul(pub.yQ, Q, y);
G1::mul(pub.zP, P, z1);
G2::mul(pub.xQ, Q, x2);
G2::mul(pub.yQ, Q, y2);
G2::mul(pub.zQ, Q, z2);
} }
#if 0 #if 0
// log_x(y) // log_x(y)
@ -517,13 +502,13 @@ public:
int dec(const CipherTextG1& c) const int dec(const CipherTextG1& c) const
{ {
/* /*
S = myP + rP S = mP + rxP
T = mzP + rxP T = rP
R = xS - T = m(xy - z)P = mB R = S - xT = mP
*/ */
G1 R; G1 R;
G1::mul(R, c.S, x1); G1::mul(R, c.T, x);
R -= c.T; G1::sub(R, c.S, R);
return g1HashTbl.log(R); return g1HashTbl.log(R);
} }
int dec(const CipherTextA& c) const int dec(const CipherTextA& c) const
@ -534,23 +519,21 @@ public:
{ {
/* /*
(s, t, u, v) := (e(S, S'), e(S, T'), e(T, S'), e(T, T')) (s, t, u, v) := (e(S, S'), e(S, T'), e(T, S'), e(T, T'))
s^(xx') v / (t^x u^x') s v^(xy) / (t^y u^x) = s (v^x / t) ^ y / u^x
= e(xS, x'S') e(xS, -T') e(-T, x'S') e(T, T') = e(P, Q)^(mm')
= e(xS - T, x'S' - T')
= e(m B1, m' B2)
= e(B1, B2)^(mm')
*/ */
GT s, t, u; GT t, u, v;
GT::pow(s, c.g[0], x1x2); GT::unitaryInv(t, c.g[1]);
s *= c.g[3]; GT::unitaryInv(u, c.g[2]);
GT::pow(t, c.g[1], x1); GT::pow(v, c.g[3], x);
GT::pow(u, c.g[2], x2); v *= t;
t *= u; GT::pow(v, v, y);
GT::unitaryInv(t, t); GT::pow(u, u, x);
s *= t; v *= u;
BN::finalExp(s, s); v *= c.g[0];
return gtHashTbl.log(s); BN::finalExp(v, v);
// return log(g, s); return gtHashTbl.log(v);
// return log(g, v);
} }
int dec(const CipherText& c) const int dec(const CipherText& c) const
{ {
@ -562,28 +545,16 @@ public:
} }
std::istream& readStream(std::istream& is, int ioMode) std::istream& readStream(std::istream& is, int ioMode)
{ {
x1.readStream(is, ioMode); x.readStream(is, ioMode);
y1.readStream(is, ioMode); y.readStream(is, ioMode);
z1.readStream(is, ioMode);
x2.readStream(is, ioMode);
y2.readStream(is, ioMode);
z2.readStream(is, ioMode);
return is; return is;
} }
void getStr(std::string& str, int ioMode = 0) const void getStr(std::string& str, int ioMode = 0) const
{ {
const char *sep = fp::getIoSeparator(ioMode); const char *sep = fp::getIoSeparator(ioMode);
str = x1.getStr(ioMode); str = x.getStr(ioMode);
str += sep; str += sep;
str += y1.getStr(ioMode); str += y.getStr(ioMode);
str += sep;
str += z1.getStr(ioMode);
str += sep;
str += x2.getStr(ioMode);
str += sep;
str += y2.getStr(ioMode);
str += sep;
str += z2.getStr(ioMode);
} }
void setStr(const std::string& str, int ioMode = 0) void setStr(const std::string& str, int ioMode = 0)
{ {
@ -606,42 +577,39 @@ public:
} }
bool operator==(const SecretKey& rhs) const bool operator==(const SecretKey& rhs) const
{ {
return x1 == rhs.x1 && y1 == rhs.y1 && z1 == rhs.z1 return x == rhs.x && y == rhs.y;
&& x2 == rhs.x2 && y2 == rhs.y2 && z2 == rhs.z2;
} }
bool operator!=(const SecretKey& rhs) const { return !operator==(rhs); } bool operator!=(const SecretKey& rhs) const { return !operator==(rhs); }
}; };
class PublicKey { class PublicKey {
G1 xP, yP, zP; G1 xP;
G2 xQ, yQ, zQ; G2 yQ;
friend class SecretKey; friend class SecretKey;
/* /*
(S, T) = (m yP + rP, m zP + r xP) (S, T) = (m P + r xP, rP)
*/ */
template<class G, class RG> template<class G, class RG>
static void enc1(G& S, G& T, const G& P, const G& xP, const G& yP, const G& zP, int m, RG& rg) static void enc1(G& S, G& T, const G& P, const G& xP, int m, RG& rg)
{ {
Fr r; Fr r;
r.setRand(rg); r.setRand(rg);
G C; G C;
G::mul(S, yP, m); G::mul(T, P, r);
G::mul(C, P, r); G::mul(S, P, m);
S += C;
G::mul(T, zP, m);
G::mul(C, xP, r); G::mul(C, xP, r);
T += C; S += C;
} }
public: public:
template<class RG> template<class RG>
void enc(CipherTextG1& c, int m, RG& rg) const void enc(CipherTextG1& c, int m, RG& rg) const
{ {
enc1(c.S, c.T, P, xP, yP, zP, m, rg); enc1(c.S, c.T, P, xP, m, rg);
} }
template<class RG> template<class RG>
void enc(CipherTextG2& c, int m, RG& rg) const void enc(CipherTextG2& c, int m, RG& rg) const
{ {
enc1(c.S, c.T, Q, xQ, yQ, zQ, m, rg); enc1(c.S, c.T, Q, yQ, m, rg);
} }
template<class RG> template<class RG>
void enc(CipherTextA& c, int m, RG& rg) const void enc(CipherTextA& c, int m, RG& rg) const
@ -665,10 +633,12 @@ public:
void convertToCipherTextM(CipherTextM& cm, const CipherTextG1& c1) const void convertToCipherTextM(CipherTextM& cm, const CipherTextG1& c1) const
{ {
/* /*
Enc(1) = (S, T) = (yQ + rQ, zQ + r xQ) = (yQ, zQ) if r = 0 Enc(1) = (S, T) = (Q + r yQ, rQ) = (Q, 0) if r = 0
cm = c1 * (yQ, zQ) cm = c1 * (Q, 0) = (S, T) * (Q, 0) = (e(S, Q), 1, e(T, Q), 1)
QQQ
*/ */
tensorProduct(cm.g, c1.S, c1.T, yQ, zQ); G2 zero; zero.clear();
tensorProduct(cm.g, c1.S, c1.T, Q, zero);
} }
/* /*
convert from CipherTextG2 to CipherTextM convert from CipherTextG2 to CipherTextM
@ -676,10 +646,11 @@ public:
void convertToCipherTextM(CipherTextM& cm, const CipherTextG2& c2) const void convertToCipherTextM(CipherTextM& cm, const CipherTextG2& c2) const
{ {
/* /*
Enc(1) = (S, T) = (yP + rP, zP + r xP) = (yP, zP) if r = 0 Enc(1) = (S, T) = (P + r xP, rP) = (P, 0) if r = 0
cm = (yP, zP) * c2 cm = (P, 0) * c2
*/ */
tensorProduct(cm.g, yP, zP, c2.S, c2.T); G1 zero; zero.clear();
tensorProduct(cm.g, P, zero, c2.S, c2.T);
} }
void convertToCipherTextM(CipherTextM& cm, const CipherTextA& ca) const void convertToCipherTextM(CipherTextM& cm, const CipherTextA& ca) const
{ {
@ -706,24 +677,20 @@ public:
{ {
/* /*
add Enc(0) * Enc(0) add Enc(0) * Enc(0)
(S1, T1) * (S2, T2) = (rP, rxP) * (r'Q, r'xQ) (S1, T1) * (S2, T2) = (rxP, rP) * (r'yQ, r'Q)
replace r <- rr' replace r <- rr', r' <- 1
= (r P, rxP) * (Q, xQ) = (r xP, rP) * (yQ, Q)
*/ */
G1 S1, T1; G1 S1, T1;
Fr r; Fr r;
r.setRand(rg); r.setRand(rg);
G1::mul(S1, P, r); G1::mul(S1, xP, r);
G1::mul(T1, xP, r); G1::mul(T1, P, r);
GT e; GT g[4];
BN::millerLoop(e, S1, Q); tensorProduct(g, S1, T1, yQ, Q);
c.g[0] *= e; for (int i = 0; i < 4; i++) {
BN::millerLoop(e, S1, xQ); c.g[i] *= g[i];
c.g[1] *= e; }
BN::millerLoop(e, T1, Q);
c.g[2] *= e;
BN::millerLoop(e, T1, xQ);
c.g[3] *= e;
} }
template<class RG> template<class RG>
void rerandomize(CipherText& c, RG& rg) const void rerandomize(CipherText& c, RG& rg) const
@ -741,11 +708,7 @@ public:
std::istream& readStream(std::istream& is, int ioMode) std::istream& readStream(std::istream& is, int ioMode)
{ {
xP.readStream(is, ioMode); xP.readStream(is, ioMode);
yP.readStream(is, ioMode);
zP.readStream(is, ioMode);
xQ.readStream(is, ioMode);
yQ.readStream(is, ioMode); yQ.readStream(is, ioMode);
zQ.readStream(is, ioMode);
return is; return is;
} }
void getStr(std::string& str, int ioMode = 0) const void getStr(std::string& str, int ioMode = 0) const
@ -753,15 +716,7 @@ public:
const char *sep = fp::getIoSeparator(ioMode); const char *sep = fp::getIoSeparator(ioMode);
str = xP.getStr(ioMode); str = xP.getStr(ioMode);
str += sep; str += sep;
str += yP.getStr(ioMode);
str += sep;
str += zP.getStr(ioMode);
str += sep;
str += xQ.getStr(ioMode);
str += sep;
str += yQ.getStr(ioMode); str += yQ.getStr(ioMode);
str += sep;
str += zQ.getStr(ioMode);
} }
void setStr(const std::string& str, int ioMode = 0) void setStr(const std::string& str, int ioMode = 0)
{ {
@ -784,8 +739,7 @@ public:
} }
bool operator==(const PublicKey& rhs) const bool operator==(const PublicKey& rhs) const
{ {
return xP == rhs.xP && yP == rhs.yP && zP == rhs.zP return xP == rhs.xP && yQ == rhs.yQ;
&& xQ == rhs.xQ && yQ == rhs.yQ && zQ == rhs.zQ;
} }
bool operator!=(const PublicKey& rhs) const { return !operator==(rhs); } bool operator!=(const PublicKey& rhs) const { return !operator==(rhs); }
}; };

Loading…
Cancel
Save