aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2018-02-06 05:18:38 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2018-02-06 05:18:38 +0800
commiteab7d579e51e2f6dd40652ba28e140669a193d34 (patch)
tree590305283115715236530a9f0648a799732c368e
parent0a707a3d07dcdc01291834484692cc9318efa866 (diff)
downloadtangerine-mcl-eab7d579e51e2f6dd40652ba28e140669a193d34.tar.gz
tangerine-mcl-eab7d579e51e2f6dd40652ba28e140669a193d34.tar.zst
tangerine-mcl-eab7d579e51e2f6dd40652ba28e140669a193d34.zip
[she] add ZkpBin
-rw-r--r--include/mcl/randgen.hpp2
-rw-r--r--include/mcl/she.hpp174
-rw-r--r--test/she_test.cpp17
3 files changed, 160 insertions, 33 deletions
diff --git a/include/mcl/randgen.hpp b/include/mcl/randgen.hpp
index ed35a01..9e078d4 100644
--- a/include/mcl/randgen.hpp
+++ b/include/mcl/randgen.hpp
@@ -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;
}
diff --git a/include/mcl/she.hpp b/include/mcl/she.hpp
index ffb7d13..14e097c 100644
--- a/include/mcl/she.hpp
+++ b/include/mcl/she.hpp
@@ -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
diff --git a/test/she_test.cpp b/test/she_test.cpp
index b52f1fa..aa9f231 100644
--- a/test/she_test.cpp
+++ b/test/she_test.cpp
@@ -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;