add ZkpBinEq

dev
MITSUNARI Shigeo 7 years ago
parent 34c9142477
commit aedea90288
  1. 16
      include/mcl/she.h
  2. 290
      include/mcl/she.hpp
  3. 67
      src/she_c_impl.hpp
  4. 47
      test/she_c_test.hpp
  5. 56
      test/she_test.cpp

@ -64,6 +64,14 @@ typedef struct {
typedef struct {
mclBnFr d[4];
} sheZkpBin;
typedef struct {
mclBnFr d[4];
} sheZkpEq;
typedef struct {
mclBnFr d[7];
} sheZkpBinEq;
/*
initialize this library
call this once before using the other functions
@ -82,6 +90,8 @@ MCLSHE_DLL_API mclSize sheCipherTextG1Serialize(void *buf, mclSize maxBufSize, c
MCLSHE_DLL_API mclSize sheCipherTextG2Serialize(void *buf, mclSize maxBufSize, const sheCipherTextG2 *c);
MCLSHE_DLL_API mclSize sheCipherTextGTSerialize(void *buf, mclSize maxBufSize, const sheCipherTextGT *c);
MCLSHE_DLL_API mclSize sheZkpBinSerialize(void *buf, mclSize maxBufSize, const sheZkpBin *zkp);
MCLSHE_DLL_API mclSize sheZkpEqSerialize(void *buf, mclSize maxBufSize, const sheZkpEq *zkp);
MCLSHE_DLL_API mclSize sheZkpBinEqSerialize(void *buf, mclSize maxBufSize, const sheZkpBinEq *zkp);
// return read byte size if sucess else 0
MCLSHE_DLL_API mclSize sheSecretKeyDeserialize(sheSecretKey* sec, const void *buf, mclSize bufSize);
@ -90,6 +100,8 @@ MCLSHE_DLL_API mclSize sheCipherTextG1Deserialize(sheCipherTextG1* c, const void
MCLSHE_DLL_API mclSize sheCipherTextG2Deserialize(sheCipherTextG2* c, const void *buf, mclSize bufSize);
MCLSHE_DLL_API mclSize sheCipherTextGTDeserialize(sheCipherTextGT* c, const void *buf, mclSize bufSize);
MCLSHE_DLL_API mclSize sheZkpBinDeserialize(sheZkpBin* zkp, const void *buf, mclSize bufSize);
MCLSHE_DLL_API mclSize sheZkpEqDeserialize(sheZkpEq* zkp, const void *buf, mclSize bufSize);
MCLSHE_DLL_API mclSize sheZkpBinEqDeserialize(sheZkpBinEq* zkp, const void *buf, mclSize bufSize);
/*
set secretKey if system has /dev/urandom or CryptGenRandom
@ -149,6 +161,7 @@ MCLSHE_DLL_API int sheEncGT(sheCipherTextGT *c, const shePublicKey *pub, mclInt
*/
MCLSHE_DLL_API int sheEncWithZkpBinG1(sheCipherTextG1 *c, sheZkpBin *zkp, const shePublicKey *pub, int m);
MCLSHE_DLL_API int sheEncWithZkpBinG2(sheCipherTextG2 *c, sheZkpBin *zkp, const shePublicKey *pub, int m);
MCLSHE_DLL_API int sheEncWithZkpBinEq(sheCipherTextG1 *c1, sheCipherTextG2 *c2, sheZkpBinEq *zkp, const shePublicKey *pub, int m);
/*
decode c and set m
@ -163,8 +176,10 @@ MCLSHE_DLL_API int sheDecGT(mclInt *m, const sheSecretKey *sec, const sheCipherT
*/
MCLSHE_DLL_API int sheVerifyZkpBinG1(const shePublicKey *pub, const sheCipherTextG1 *c, const sheZkpBin *zkp);
MCLSHE_DLL_API int sheVerifyZkpBinG2(const shePublicKey *pub, const sheCipherTextG2 *c, const sheZkpBin *zkp);
MCLSHE_DLL_API int sheVerifyZkpBinEq(const shePublicKey *pub, const sheCipherTextG1 *c1, const sheCipherTextG2 *c2, const sheZkpBinEq *zkp);
MCLSHE_DLL_API int shePrecomputedPublicKeyVerifyZkpBinG1(const shePrecomputedPublicKey *ppub, const sheCipherTextG1 *c, const sheZkpBin *zkp);
MCLSHE_DLL_API int shePrecomputedPublicKeyVerifyZkpBinG2(const shePrecomputedPublicKey *ppub, const sheCipherTextG2 *c, const sheZkpBin *zkp);
MCLSHE_DLL_API int shePrecomputedPublicKeyVerifyZkpBinEq(const shePrecomputedPublicKey *ppub, const sheCipherTextG1 *c1, const sheCipherTextG2 *c2, const sheZkpBinEq *zkp);
/*
decode c via GT and set m
return 0 if success
@ -232,6 +247,7 @@ MCLSHE_DLL_API int shePrecomputedPublicKeyEncGT(sheCipherTextGT *c, const shePre
*/
MCLSHE_DLL_API int shePrecomputedPublicKeyEncWithZkpBinG1(sheCipherTextG1 *c, sheZkpBin *zkp, const shePrecomputedPublicKey *ppub, int m);
MCLSHE_DLL_API int shePrecomputedPublicKeyEncWithZkpBinG2(sheCipherTextG2 *c, sheZkpBin *zkp, const shePrecomputedPublicKey *ppub, int m);
MCLSHE_DLL_API int shePrecomputedPublicKeyEncWithZkpBinEq(sheCipherTextG1 *c1, sheCipherTextG2 *c2, sheZkpBinEq *zkp, const shePrecomputedPublicKey *ppub, int m);
#ifdef __cplusplus
}

@ -471,13 +471,13 @@ private:
tensorProductML(g,S1, T1, S2,T2);
finalExp4(g, g);
}
public:
struct ZkpBin : public fp::Serializable<ZkpBin> {
Fr d_[4];
template<class Tag, size_t n>
struct ZkpT : public fp::Serializable<ZkpT<Tag, n> > {
Fr d_[n];
template<class InputStream>
void load(InputStream& is, int ioMode = IoSerialize)
{
for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(d_); i++) {
for (size_t i = 0; i < n; i++) {
d_[i].load(is, ioMode);
}
}
@ -486,22 +486,38 @@ public:
{
const char sep = *fp::getIoSeparator(ioMode);
d_[0].save(os, ioMode);
for (size_t i = 1; i < CYBOZU_NUM_OF_ARRAY(d_); i++) {
for (size_t i = 1; i < n; i++) {
if (sep) cybozu::writeChar(os, sep);
d_[i].save(os, ioMode);
}
}
friend std::istream& operator>>(std::istream& is, ZkpBin& self)
friend std::istream& operator>>(std::istream& is, ZkpT& self)
{
self.load(is, fp::detectIoMode(Fr::getIoMode(), is));
return is;
}
friend std::ostream& operator<<(std::ostream& os, const ZkpBin& self)
friend std::ostream& operator<<(std::ostream& os, const ZkpT& self)
{
self.save(os, fp::detectIoMode(Fr::getIoMode(), os));
return os;
}
};
struct ZkpBinTag;
struct ZkpEqTag; // d_[] = { c, sp, ss, sm }
struct ZkpBinEqTag; // d_[] = { d0, d1, sp0, sp1, ss, sp, sm }
public:
/*
Zkp for m = 0 or 1
*/
typedef ZkpT<ZkpBinTag, 4> ZkpBin;
/*
Zkp for decG1(c1) == decG2(c2)
*/
typedef ZkpT<ZkpEqTag, 4> ZkpEq;
/*
Zkp for (m = 0 or 1) and decG1(c1) == decG2(c2)
*/
typedef ZkpT<ZkpBinEqTag, 7> ZkpBinEq;
typedef CipherTextAT<G1> CipherTextG1;
typedef CipherTextAT<G2> CipherTextG2;
@ -735,14 +751,17 @@ private:
(S, T) = (m P + r xP, rP)
Pmul.mul(X, a) // X = a P
xPmul.mul(X, a) // X = a xP
encRand is used to compute Zkp
use *encRand if encRand is not null
*/
template<class G, class INT, class MulG, class I>
static void ElGamalEnc(G& S, G& T, const INT& m, const mcl::fp::WindowMethod<I>& Pmul, const MulG& xPmul, Fr *encRand = 0)
static void ElGamalEnc(G& S, G& T, const INT& m, const mcl::fp::WindowMethod<I>& Pmul, const MulG& xPmul, const Fr *encRand = 0)
{
Fr r;
r.setRand();
if (encRand) *encRand = r;
if (encRand) {
r = *encRand;
} else {
r.setRand();
}
Pmul.mul(static_cast<I&>(T), r);
xPmul.mul(S, r); // S = r xP
if (m == 0) return;
@ -839,6 +858,197 @@ private:
c.setHashOf(buf, os.getPos());
return c == d[0] + d[1];
}
/*
encRand1, encRand2 are random values use for ElGamalEnc()
*/
template<class G1, class G2, class INT, class I1, class I2, class MulG1, class MulG2>
static void makeZkpEq(ZkpEq& zkp, G1& S1, G1& T1, G2& S2, G2& T2, const INT& m, const mcl::fp::WindowMethod<I1>& Pmul, const MulG1& xPmul, const mcl::fp::WindowMethod<I2>& Qmul, const MulG2& yQmul)
{
Fr p, s;
p.setRand();
s.setRand();
ElGamalEnc(S1, T1, m, Pmul, xPmul, &p);
ElGamalEnc(S2, T2, m, Qmul, yQmul, &s);
Fr rp, rs, rm;
rp.setRand();
rs.setRand();
rm.setRand();
G1 R1, R2;
G2 R3, R4;
ElGamalEnc(R1, R2, rm, Pmul, xPmul, &rp);
ElGamalEnc(R3, R4, rm, Qmul, yQmul, &rs);
char buf[sizeof(G1) * 4 + sizeof(G2) * 4];
cybozu::MemoryOutputStream os(buf, sizeof(buf));
S1.save(os);
T1.save(os);
S2.save(os);
T2.save(os);
R1.save(os);
R2.save(os);
R3.save(os);
R4.save(os);
Fr& c = zkp.d_[0];
Fr& sp = zkp.d_[1];
Fr& ss = zkp.d_[2];
Fr& sm = zkp.d_[3];
c.setHashOf(buf, os.getPos());
Fr::mul(sp, c, p);
sp += rp;
Fr::mul(ss, c, s);
ss += rs;
Fr::mul(sm, c, m);
sm += rm;
}
template<class G1, class G2, class I1, class I2, class MulG1, class MulG2>
static bool verifyZkpEq(const ZkpEq& zkp, const G1& S1, const G1& T1, const G2& S2, const G2& T2, const mcl::fp::WindowMethod<I1>& Pmul, const MulG1& xPmul, const mcl::fp::WindowMethod<I2>& Qmul, const MulG2& yQmul)
{
const Fr& c = zkp.d_[0];
const Fr& sp = zkp.d_[1];
const Fr& ss = zkp.d_[2];
const Fr& sm = zkp.d_[3];
G1 R1, R2, X1;
G2 R3, R4, X2;
ElGamalEnc(R1, R2, sm, Pmul, xPmul, &sp);
G1::mul(X1, S1, c);
R1 -= X1;
G1::mul(X1, T1, c);
R2 -= X1;
ElGamalEnc(R3, R4, sm, Qmul, yQmul, &ss);
G2::mul(X2, S2, c);
R3 -= X2;
G2::mul(X2, T2, c);
R4 -= X2;
char buf[sizeof(G1) * 4 + sizeof(G2) * 4];
cybozu::MemoryOutputStream os(buf, sizeof(buf));
S1.save(os);
T1.save(os);
S2.save(os);
T2.save(os);
R1.save(os);
R2.save(os);
R3.save(os);
R4.save(os);
Fr c2;
c2.setHashOf(buf, os.getPos());
return c == c2;
}
/*
encRand1, encRand2 are random values use for ElGamalEnc()
*/
template<class G1, class G2, class I1, class I2, class MulG1, class MulG2>
static void makeZkpBinEq(ZkpBinEq& zkp, G1& S1, G1& T1, G2& S2, G2& T2, int m, const mcl::fp::WindowMethod<I1>& Pmul, const MulG1& xPmul, const mcl::fp::WindowMethod<I2>& Qmul, const MulG2& yQmul)
{
if (m != 0 && m != 1) throw cybozu::Exception("makeZkpBinEq:bad m") << m;
Fr *d = &zkp.d_[0];
Fr *spm = &zkp.d_[2];
Fr& ss = zkp.d_[4];
Fr& sp = zkp.d_[5];
Fr& sm = zkp.d_[6];
Fr p, s;
p.setRand();
s.setRand();
ElGamalEnc(S1, T1, m, Pmul, xPmul, &p);
ElGamalEnc(S2, T2, m, Qmul, yQmul, &s);
d[1-m].setRand();
spm[1-m].setRand();
G1 R1[2], R2[2], X1;
Pmul.mul(static_cast<I1&>(R1[1-m]), spm[1-m]);
G1::mul(X1, T1, d[1-m]);
R1[1-m] -= X1;
if (m == 0) {
G1::sub(X1, S1, P_);
G1::mul(X1, X1, d[1-m]);
} else {
G1::mul(X1, S1, d[1-m]);
}
xPmul.mul(R2[1-m], spm[1-m]);
R2[1-m] -= X1;
Fr rpm, rp, rs, rm;
rpm.setRand();
rp.setRand();
rs.setRand();
rm.setRand();
ElGamalEnc(R2[m], R1[m], 0, Pmul, xPmul, &rpm);
G1 R3, R4;
G2 R5, R6;
ElGamalEnc(R4, R3, rm, Pmul, xPmul, &rp);
ElGamalEnc(R6, R5, rm, Qmul, yQmul, &rs);
char buf[sizeof(Fr) * 12];
cybozu::MemoryOutputStream os(buf, sizeof(buf));
S1.save(os);
T1.save(os);
R1[0].save(os);
R1[1].save(os);
R2[0].save(os);
R2[1].save(os);
R3.save(os);
R4.save(os);
R5.save(os);
R6.save(os);
Fr c;
c.setHashOf(buf, os.getPos());
Fr::sub(d[m], c, d[1-m]);
Fr::mul(spm[m], d[m], p);
spm[m] += rpm;
Fr::mul(sp, c, p);
sp += rp;
Fr::mul(ss, c, s);
ss += rs;
Fr::mul(sm, c, m);
sm += rm;
}
template<class G1, class G2, class I1, class I2, class MulG1, class MulG2>
static bool verifyZkpBinEq(const ZkpBinEq& zkp, const G1& S1, const G1& T1, const G2& S2, const G2& T2, const mcl::fp::WindowMethod<I1>& Pmul, const MulG1& xPmul, const mcl::fp::WindowMethod<I2>& Qmul, const MulG2& yQmul)
{
const Fr *d = &zkp.d_[0];
const Fr *spm = &zkp.d_[2];
const Fr& ss = zkp.d_[4];
const Fr& sp = zkp.d_[5];
const Fr& sm = zkp.d_[6];
G1 R1[2], R2[2], X1;
for (int i = 0; i < 2; i++) {
Pmul.mul(static_cast<I1&>(R1[i]), spm[i]);
G1::mul(X1, T1, d[i]);
R1[i] -= X1;
}
xPmul.mul(R2[0], spm[0]);
G1::mul(X1, S1, d[0]);
R2[0] -= X1;
xPmul.mul(R2[1], spm[1]);
G1::sub(X1, S1, P_);
G1::mul(X1, X1, d[1]);
R2[1] -= X1;
Fr c;
Fr::add(c, d[0], d[1]);
G1 R3, R4;
G2 R5, R6;
ElGamalEnc(R4, R3, sm, Pmul, xPmul, &sp);
G1::mul(X1, T1, c);
R3 -= X1;
G1::mul(X1, S1, c);
R4 -= X1;
ElGamalEnc(R6, R5, sm, Qmul, yQmul, &ss);
G2 X2;
G2::mul(X2, T2, c);
R5 -= X2;
G2::mul(X2, S2, c);
R6 -= X2;
char buf[sizeof(Fr) * 12];
cybozu::MemoryOutputStream os(buf, sizeof(buf));
S1.save(os);
T1.save(os);
R1[0].save(os);
R1[1].save(os);
R2[0].save(os);
R2[1].save(os);
R3.save(os);
R4.save(os);
R5.save(os);
R6.save(os);
Fr c2;
c2.setHashOf(buf, os.getPos());
return c == c2;
}
/*
common method for PublicKey and PrecomputedPublicKey
*/
@ -858,16 +1068,6 @@ 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
{
@ -990,6 +1190,7 @@ public:
void encWithZkpBin(CipherTextG1& c, ZkpBin& zkp, int m) const
{
Fr encRand;
encRand.setRand();
const MulG<G1> xPmul(xP_);
ElGamalEnc(c.S_, c.T_, m, PhashTbl_.getWM(), xPmul, &encRand);
makeZkpBin(zkp, c.S_, c.T_, encRand, P_, m, PhashTbl_.getWM(), xPmul);
@ -997,6 +1198,7 @@ public:
void encWithZkpBin(CipherTextG2& c, ZkpBin& zkp, int m) const
{
Fr encRand;
encRand.setRand();
const MulG<G2> yQmul(yQ_);
ElGamalEnc(c.S_, c.T_, m, QhashTbl_.getWM(), yQmul, &encRand);
makeZkpBin(zkp, c.S_, c.T_, encRand, Q_, m, QhashTbl_.getWM(), yQmul);
@ -1012,6 +1214,31 @@ public:
return verifyZkpBin(c.S_, c.T_, Q_, zkp, QhashTbl_.getWM(), yQmul);
}
template<class INT>
void encWithZkpEq(CipherTextG1& c1, CipherTextG2& c2, ZkpEq& zkp, const INT& m) const
{
const MulG<G1> xPmul(xP_);
const MulG<G2> yQmul(yQ_);
makeZkpEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, m, PhashTbl_.getWM(), xPmul, QhashTbl_.getWM(), yQmul);
}
bool verify(const CipherTextG1& c1, const CipherTextG2& c2, const ZkpEq& zkp) const
{
const MulG<G1> xPmul(xP_);
const MulG<G2> yQmul(yQ_);
return verifyZkpEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, PhashTbl_.getWM(), xPmul, QhashTbl_.getWM(), yQmul);
}
void encWithZkpBinEq(CipherTextG1& c1, CipherTextG2& c2, ZkpBinEq& zkp, int m) const
{
const MulG<G1> xPmul(xP_);
const MulG<G2> yQmul(yQ_);
makeZkpBinEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, m, PhashTbl_.getWM(), xPmul, QhashTbl_.getWM(), yQmul);
}
bool verify(const CipherTextG1& c1, const CipherTextG2& c2, const ZkpBinEq& zkp) const
{
const MulG<G1> xPmul(xP_);
const MulG<G2> yQmul(yQ_);
return verifyZkpBinEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, PhashTbl_.getWM(), xPmul, QhashTbl_.getWM(), yQmul);
}
template<class INT>
void encGT(CipherTextGT& c, const INT& m) const
{
/*
@ -1147,12 +1374,14 @@ public:
void encWithZkpBin(CipherTextG1& c, ZkpBin& zkp, int m) const
{
Fr encRand;
encRand.setRand();
ElGamalEnc(c.S_, c.T_, m, PhashTbl_.getWM(), xPwm_, &encRand);
makeZkpBin(zkp, c.S_, c.T_, encRand, P_, m, PhashTbl_.getWM(), xPwm_);
}
void encWithZkpBin(CipherTextG2& c, ZkpBin& zkp, int m) const
{
Fr encRand;
encRand.setRand();
ElGamalEnc(c.S_, c.T_, m, QhashTbl_.getWM(), yQwm_, &encRand);
makeZkpBin(zkp, c.S_, c.T_, encRand, Q_, m, QhashTbl_.getWM(), yQwm_);
}
@ -1164,6 +1393,23 @@ public:
{
return verifyZkpBin(c.S_, c.T_, Q_, zkp, QhashTbl_.getWM(), yQwm_);
}
template<class INT>
void encWithZkpEq(CipherTextG1& c1, CipherTextG2& c2, ZkpEq& zkp, const INT& m) const
{
makeZkpEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, m, PhashTbl_.getWM(), xPwm_, QhashTbl_.getWM(), yQwm_);
}
bool verify(const CipherTextG1& c1, const CipherTextG2& c2, const ZkpEq& zkp) const
{
return verifyZkpEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, PhashTbl_.getWM(), xPwm_, QhashTbl_.getWM(), yQwm_);
}
void encWithZkpBinEq(CipherTextG1& c1, CipherTextG2& c2, ZkpBinEq& zkp, int m) const
{
makeZkpBinEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, m, PhashTbl_.getWM(), xPwm_, QhashTbl_.getWM(), yQwm_);
}
bool verify(const CipherTextG1& c1, const CipherTextG2& c2, const ZkpBinEq& zkp) const
{
return verifyZkpBinEq(zkp, c1.S_, c1.T_, c2.S_, c2.T_, PhashTbl_.getWM(), xPwm_, QhashTbl_.getWM(), yQwm_);
}
};
class CipherTextA {
CipherTextG1 c1_;
@ -1471,6 +1717,8 @@ typedef SHE::CipherTextA CipherTextA;
typedef CipherTextGT CipherTextGM; // old class
typedef SHE::CipherText CipherText;
typedef SHE::ZkpBin ZkpBin;
typedef SHE::ZkpEq ZkpEq;
typedef SHE::ZkpBinEq ZkpBinEq;
} } // mcl::she

@ -42,6 +42,12 @@ static const CipherTextGT *cast(const sheCipherTextGT *p) { return reinterpret_c
static ZkpBin *cast(sheZkpBin *p) { return reinterpret_cast<ZkpBin*>(p); }
static const ZkpBin *cast(const sheZkpBin *p) { return reinterpret_cast<const ZkpBin*>(p); }
static ZkpEq *cast(sheZkpEq *p) { return reinterpret_cast<ZkpEq*>(p); }
static const ZkpEq *cast(const sheZkpEq *p) { return reinterpret_cast<const ZkpEq*>(p); }
static ZkpBinEq *cast(sheZkpBinEq *p) { return reinterpret_cast<ZkpBinEq*>(p); }
static const ZkpBinEq *cast(const sheZkpBinEq *p) { return reinterpret_cast<const ZkpBinEq*>(p); }
int sheInit(int curve, int maxUnitSize)
try
{
@ -125,6 +131,16 @@ mclSize sheZkpBinSerialize(void *buf, mclSize maxBufSize, const sheZkpBin *zkp)
return serialize(buf, maxBufSize, zkp);
}
mclSize sheZkpEqSerialize(void *buf, mclSize maxBufSize, const sheZkpEq *zkp)
{
return serialize(buf, maxBufSize, zkp);
}
mclSize sheZkpBinEqSerialize(void *buf, mclSize maxBufSize, const sheZkpBinEq *zkp)
{
return serialize(buf, maxBufSize, zkp);
}
template<class T>
mclSize deserialize(T *x, const void *buf, mclSize bufSize)
try
@ -165,6 +181,16 @@ mclSize sheZkpBinDeserialize(sheZkpBin* zkp, const void *buf, mclSize bufSize)
return deserialize(zkp, buf, bufSize);
}
mclSize sheZkpEqDeserialize(sheZkpEq* zkp, const void *buf, mclSize bufSize)
{
return deserialize(zkp, buf, bufSize);
}
mclSize sheZkpBinEqDeserialize(sheZkpBinEq* zkp, const void *buf, mclSize bufSize)
{
return deserialize(zkp, buf, bufSize);
}
int sheSecretKeySetByCSPRNG(sheSecretKey *sec)
try
{
@ -322,6 +348,27 @@ int shePrecomputedPublicKeyEncWithZkpBinG2(sheCipherTextG2 *c, sheZkpBin *zkp, c
return encWithZkpBinT(c, zkp, pub, m);
}
template<class PK>
int encWithZkpBinEqT(sheCipherTextG1 *c1, sheCipherTextG2 *c2, sheZkpBinEq *zkp, const PK *pub, int m)
try
{
cast(pub)->encWithZkpBinEq(*cast(c1), *cast(c2), *cast(zkp), m);
return 0;
} catch (std::exception& e) {
fprintf(stderr, "err %s\n", e.what());
return -1;
}
int sheEncWithZkpBinEq(sheCipherTextG1 *c1, sheCipherTextG2 *c2, sheZkpBinEq *zkp, const shePublicKey *pub, int m)
{
return encWithZkpBinEqT(c1, c2, zkp, pub, m);
}
int shePrecomputedPublicKeyEncWithZkpBinEq(sheCipherTextG1 *c1, sheCipherTextG2 *c2, sheZkpBinEq *zkp, const shePrecomputedPublicKey *ppub, int m)
{
return encWithZkpBinEqT(c1, c2, zkp, ppub, m);
}
template<class CT>
int decT(mclInt *m, const sheSecretKey *sec, const CT *c)
try
@ -618,3 +665,23 @@ int shePrecomputedPublicKeyVerifyZkpBinG2(const shePrecomputedPublicKey *pub, co
{
return verifyT(*cast(pub), *cast(c), *cast(zkp));
}
template<class PK>
int verifyT(const PK& pub, const CipherTextG1& c1, const CipherTextG2& c2, const ZkpBinEq& zkp)
try
{
return pub.verify(c1, c2, zkp);
} catch (std::exception& e) {
fprintf(stderr, "err %s\n", e.what());
return 0;
}
int sheVerifyZkpBinEq(const shePublicKey *pub, const sheCipherTextG1 *c1, const sheCipherTextG2 *c2, const sheZkpBinEq *zkp)
{
return verifyT(*cast(pub), *cast(c1), *cast(c2), *cast(zkp));
}
int shePrecomputedPublicKeyVerifyZkpBinEq(const shePrecomputedPublicKey *ppub, const sheCipherTextG1 *c1, const sheCipherTextG2 *c2, const sheZkpBinEq *zkp)
{
return verifyT(*cast(ppub), *cast(c1), *cast(c2), *cast(zkp));
}

@ -317,6 +317,53 @@ CYBOZU_TEST_AUTO(ZkpBin)
shePrecomputedPublicKeyDestroy(ppub);
}
template<class PK, class encWithZkpFunc, class verifyFunc>
void ZkpBinEqTest(const sheSecretKey *sec, const PK *pub, encWithZkpFunc encWithZkp, verifyFunc verify)
{
sheCipherTextG1 c1;
sheCipherTextG2 c2;
sheZkpBinEq zkp;
for (int m = 0; m < 2; m++) {
CYBOZU_TEST_EQUAL(encWithZkp(&c1, &c2, &zkp, pub, m), 0);
mclInt mDec = -1;
CYBOZU_TEST_EQUAL(sheDecG1(&mDec, sec, &c1), 0);
CYBOZU_TEST_EQUAL(mDec, m);
mDec = -1;
CYBOZU_TEST_EQUAL(sheDecG2(&mDec, sec, &c2), 0);
CYBOZU_TEST_EQUAL(mDec, m);
CYBOZU_TEST_EQUAL(verify(pub, &c1, &c2, &zkp), 1);
{
char buf[2048];
size_t n = sheZkpBinEqSerialize(buf, sizeof(buf), &zkp);
CYBOZU_TEST_EQUAL(n, mclBn_getOpUnitSize() * 8 * 7);
sheZkpBinEq zkp2;
size_t r = sheZkpBinEqDeserialize(&zkp2, buf, n);
CYBOZU_TEST_EQUAL(r, n);
CYBOZU_TEST_ASSERT(memcmp(&zkp, &zkp2, n) == 0);
}
zkp.d[0].d[0]++;
CYBOZU_TEST_EQUAL(verify(pub, &c1, &c2, &zkp), 0);
}
CYBOZU_TEST_ASSERT(encWithZkp(&c1, &c2, &zkp, pub, 2) != 0);
}
CYBOZU_TEST_AUTO(ZkpBinEq)
{
sheSecretKey sec;
sheSecretKeySetByCSPRNG(&sec);
shePublicKey pub;
sheGetPublicKey(&pub, &sec);
ZkpBinEqTest(&sec, &pub, sheEncWithZkpBinEq, sheVerifyZkpBinEq);
shePrecomputedPublicKey *ppub = shePrecomputedPublicKeyCreate();
CYBOZU_TEST_EQUAL(shePrecomputedPublicKeyInit(ppub, &pub), 0);
ZkpBinEqTest(&sec, ppub, shePrecomputedPublicKeyEncWithZkpBinEq, shePrecomputedPublicKeyVerifyZkpBinEq);
shePrecomputedPublicKeyDestroy(ppub);
}
CYBOZU_TEST_AUTO(finalExp)
{
sheSecretKey sec;

@ -150,6 +150,62 @@ CYBOZU_TEST_AUTO(ZkpBin)
ZkpBinTest<CipherTextG2>(sec, ppub);
}
template<class PubT>
void ZkpEqTest(const SecretKey& sec, const PubT& pub)
{
CipherTextG1 c1;
CipherTextG2 c2;
ZkpEq zkp;
for (int m = -4; m < 4; m++) {
pub.encWithZkpEq(c1, c2, zkp, m);
CYBOZU_TEST_EQUAL(sec.dec(c1), m);
CYBOZU_TEST_EQUAL(sec.dec(c2), m);
CYBOZU_TEST_ASSERT(pub.verify(c1, c2, zkp));
zkp.d_[0] += 1;
CYBOZU_TEST_ASSERT(!pub.verify(c1, c2, zkp));
}
}
CYBOZU_TEST_AUTO(ZkpEq)
{
const SecretKey& sec = g_sec;
PublicKey pub;
sec.getPublicKey(pub);
PrecomputedPublicKey ppub;
ppub.init(pub);
ZkpEqTest(sec, pub);
ZkpEqTest(sec, ppub);
}
template<class PK>
void ZkpBinEqTest(const SecretKey& sec, const PK& pub)
{
CipherTextG1 c1;
CipherTextG2 c2;
ZkpBinEq zkp;
for (int m = 0; m < 2; m++) {
pub.encWithZkpBinEq(c1, c2, zkp, m);
CYBOZU_TEST_EQUAL(sec.dec(c1), m);
CYBOZU_TEST_EQUAL(sec.dec(c2), m);
CYBOZU_TEST_ASSERT(pub.verify(c1, c2, zkp));
zkp.d_[0] += 1;
CYBOZU_TEST_ASSERT(!pub.verify(c1, c2, zkp));
}
CYBOZU_TEST_EXCEPTION(pub.encWithZkpBinEq(c1, c2, zkp, 2), cybozu::Exception);
}
CYBOZU_TEST_AUTO(ZkpBinEq)
{
const SecretKey& sec = g_sec;
PublicKey pub;
sec.getPublicKey(pub);
ZkpBinEqTest(sec, pub);
PrecomputedPublicKey ppub;
ppub.init(pub);
ZkpBinEqTest(sec, ppub);
}
CYBOZU_TEST_AUTO(add_sub_mul)
{
const SecretKey& sec = g_sec;

Loading…
Cancel
Save