[she] add ZkpBin

dev
MITSUNARI Shigeo 7 years ago
parent 0a707a3d07
commit eab7d579e5
  1. 2
      include/mcl/randgen.hpp
  2. 174
      include/mcl/she.hpp
  3. 17
      test/she_test.cpp

@ -77,7 +77,7 @@ public:
rg must be thread safe
rg.read(void *buf, size_t bufSize);
*/
void setRandGen(RandGen& rg)
static void setRandGen(const RandGen& rg)
{
get() = rg;
}

@ -472,6 +472,36 @@ private:
finalExp4(g, g);
}
public:
struct ZkpBin : public fp::Serializable<ZkpBin> {
Fr d_[4];
template<class InputStream>
void load(InputStream& is, int ioMode = IoSerialize)
{
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(d_); i++) {
d_[i].load(is, ioMode);
}
}
template<class OutputStream>
void save(OutputStream& os, int ioMode = IoSerialize) const
{
const char sep = *fp::getIoSeparator(ioMode);
d_[0].save(os, ioMode);
for (size_t i = 1; i < CYBOZU_NUM_OF_ARRAY(d_); i++) {
if (sep) cybozu::writeChar(os, sep);
d_[i].save(os, ioMode);
}
}
friend std::istream& operator>>(std::istream& is, ZkpBin& self)
{
self.load(is, fp::detectIoMode(Fr::getIoMode(), is));
return is;
}
friend std::ostream& operator<<(std::ostream& os, const ZkpBin& self)
{
self.save(os, fp::detectIoMode(Fr::getIoMode(), os));
return os;
}
};
typedef CipherTextAT<G1> CipherTextG1;
typedef CipherTextAT<G2> CipherTextG2;
@ -719,6 +749,16 @@ private:
{
static_cast<const T&>(*this).encG2(c, m);
}
#if 0
void encWithZkpBin(CipherTextG1& c, ZkpBin& zkp, bool m) const
{
static_cast<const T&>(*this).encWithZkpBinG1(c, zkp, m);
}
void encWithZkpBin(CipherTextG2& c, ZkpBin& zkp, bool m) const
{
static_cast<const T&>(*this).encWithZkpBinG2(c, zkp, m);
}
#endif
template<class INT>
void enc(CipherTextA& c, const INT& m) const
{
@ -814,10 +854,11 @@ public:
(S, T) = (m P + r xP, rP)
*/
template<class G, class INT, class I>
static void enc1(G& S, G& T, const G& /*P*/, const G& xP, const INT& m, const mcl::fp::WindowMethod<I>& wm)
static void enc1(G& S, G& T, const G& /*P*/, const G& xP, const INT& m, const mcl::fp::WindowMethod<I>& wm, Fr *encRand = 0)
{
Fr r;
r.setRand();
if (encRand) *encRand = r;
// G::mul(T, P, r);
wm.mul(static_cast<I&>(T), r);
G::mul(S, xP, r);
@ -827,6 +868,94 @@ public:
wm.mul(static_cast<I&>(C), m);
S += C;
}
/*
d[1-m] ; rand
s[1-m] ; rand
R[0][1-m] = s[1-m] P - d[1-m] T
R[1][1-m] = s[1-m] xP - d[1-m] (S - (1-m) P)
r ; rand
R[0][m] = r P
R[1][m] = r xP
c = H(S, T, R[0][0], R[0][1], R[1][0], R[1][1])
d[m] = c - d[1-m]
s[m] = r + d[m] encRand
*/
template<class G>
static void makeZkpBin1(ZkpBin& zkp, const G& S, const G& T, const Fr& encRand, const G& P, const G& xP, int m)
{
if (m != 0 && m != 1) throw cybozu::Exception("makeZkpBin1:bad m") << m;
Fr *s = &zkp.d_[0];
Fr *d = &zkp.d_[2];
G R[2][2];
d[1-m].setRand();
s[1-m].setRand();
G T1, T2;
G::mul(T1, P, s[1-m]);
G::mul(T2, T, d[1-m]);
G::sub(R[0][1-m], T1, T2); // s[1-m] P - d[1-m]T
G::mul(T1, xP, s[1-m]);
if (m == 0) {
G::sub(T2, S, P);
G::mul(T2, T2, d[1-m]);
} else {
G::mul(T2, S, d[1-m]);
}
G::sub(R[1][1-m], T1, T2); // s[1-m] xP - d[1-m](S - (1-m) P)
Fr r;
r.setRand();
G::mul(R[0][m], P, r);
G::mul(R[1][m], xP, r);
char buf[sizeof(G) * 2];
cybozu::MemoryOutputStream os(buf, sizeof(buf));
S.save(os);
T.save(os);
R[0][0].save(os);
R[0][1].save(os);
R[1][0].save(os);
R[1][1].save(os);
Fr c;
c.setHashOf(buf, os.getPos());
d[m] = c - d[1-m];
s[m] = r + d[m] * encRand;
}
/*
R[0][i] = s[i] P - d[i] T ; i = 0,1
R[1][0] = s[0] xP - d[0] S
R[1][1] = s[1] xP - d[1](S - P)
c = H(S, T, R[0][0], R[0][1], R[1][0], R[1][1])
c == d[0] + d[1]
*/
template<class G>
static bool verifyZkpBin(const G& S, const G& T, const G& P, const G& xP, const ZkpBin& zkp)
{
const Fr *s = &zkp.d_[0];
const Fr *d = &zkp.d_[2];
G R[2][2];
G T1, T2;
for (int i = 0; i < 2; i++) {
G::mul(T1, P, s[i]);
G::mul(T2, T, d[i]);
G::sub(R[0][i], T1, T2);
}
G::mul(T1, xP, s[0]);
G::mul(T2, S, d[0]);
G::sub(R[1][0], T1, T2);
G::mul(T1, xP, s[1]);
G::sub(T2, S, P);
G::mul(T2, T2, d[1]);
G::sub(R[1][1], T1, T2);
char buf[sizeof(G) * 2];
cybozu::MemoryOutputStream os(buf, sizeof(buf));
S.save(os);
T.save(os);
R[0][0].save(os);
R[0][1].save(os);
R[1][0].save(os);
R[1][1].save(os);
Fr c;
c.setHashOf(buf, os.getPos());
return c == d[0] + d[1];
}
void set(const Fr& x, const Fr& y)
{
G1::mul(xP_, P_, x);
@ -842,6 +971,17 @@ public:
{
enc1(c.S_, c.T_, Q_, yQ_, m, QhashTbl_.getWM());
}
public:
void encWithZkpBin(CipherTextG1& c, ZkpBin& zkp, int m) const
{
Fr encRand;
enc1(c.S_, c.T_, P_, xP_, m, PhashTbl_.getWM(), &encRand);
makeZkpBin1(zkp, c.S_, c.T_, encRand, P_, xP_, m);
}
bool verify(const CipherTextG1& c, const ZkpBin& zkp) const
{
return verifyZkpBin(c.S_, c.T_, P_, xP_, zkp);
}
template<class INT>
void encGT(CipherTextGT& c, const INT& m) const
{
@ -991,37 +1131,6 @@ public:
yQwm_.init(pub.yQ_, bitSize, local::winSize);
}
};
struct ZkpBin : public fp::Serializable<ZkpBin> {
Fr d_[4];
template<class InputStream>
void load(InputStream& is, int ioMode = IoSerialize)
{
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(d_); i++) {
d_[i].load(is, ioMode);
}
}
template<class OutputStream>
void save(OutputStream& os, int ioMode = IoSerialize) const
{
const char sep = *fp::getIoSeparator(ioMode);
d_[0].save(os, ioMode);
for (size_t i = 1; i < CYBOZU_NUM_OF_ARRAY(d_); i++) {
if (sep) cybozu::writeChar(os, sep);
d_[i].save(os, ioMode);
}
}
friend std::istream& operator>>(std::istream& is, ZkpBin& self)
{
self.load(is, fp::detectIoMode(Fr::getIoMode(), is));
return is;
}
friend std::ostream& operator<<(std::ostream& os, const ZkpBin& self)
{
self.save(os, fp::detectIoMode(Fr::getIoMode(), os));
return os;
}
};
class CipherTextA {
CipherTextG1 c1_;
CipherTextG2 c2_;
@ -1327,6 +1436,7 @@ typedef SHE::CipherTextGT CipherTextGT;
typedef SHE::CipherTextA CipherTextA;
typedef CipherTextGT CipherTextGM; // old class
typedef SHE::CipherText CipherText;
typedef SHE::ZkpBin ZkpBin;
} } // mcl::she

@ -122,6 +122,23 @@ CYBOZU_TEST_AUTO(enc_dec)
}
}
CYBOZU_TEST_AUTO(ZkpBin)
{
const SecretKey& sec = g_sec;
PublicKey pub;
sec.getPublicKey(pub);
CipherTextG1 c1;
ZkpBin zkp;
for (int m = 0; m < 2; m++) {
pub.encWithZkpBin(c1, zkp, m);
CYBOZU_TEST_EQUAL(sec.dec(c1), m);
CYBOZU_TEST_ASSERT(pub.verify(c1, zkp));
zkp.d_[0] += 1;
CYBOZU_TEST_ASSERT(!pub.verify(c1, zkp));
}
CYBOZU_TEST_EXCEPTION(pub.encWithZkpBin(c1, zkp, 2), cybozu::Exception);
}
CYBOZU_TEST_AUTO(add_sub_mul)
{
const SecretKey& sec = g_sec;

Loading…
Cancel
Save