aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2015-06-11 13:10:28 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2015-06-11 13:10:28 +0800
commitf5de1f72c791caff02eba566cdc0ec6e27cc5157 (patch)
treecf6af156f9813856d01c3088021a7583ffe89486
parent96c6d37dc13c666f3f3bbd309549bc086ecc54c8 (diff)
downloaddexon-mcl-f5de1f72c791caff02eba566cdc0ec6e27cc5157.tar.gz
dexon-mcl-f5de1f72c791caff02eba566cdc0ec6e27cc5157.tar.zst
dexon-mcl-f5de1f72c791caff02eba566cdc0ec6e27cc5157.zip
add elgamal
-rw-r--r--include/mcl/elgamal.hpp264
-rw-r--r--include/mcl/fp.hpp27
-rw-r--r--src/fp.cpp21
-rw-r--r--test/elgamal_test.cpp189
-rw-r--r--test/window_method_test.cpp4
5 files changed, 167 insertions, 338 deletions
diff --git a/include/mcl/elgamal.hpp b/include/mcl/elgamal.hpp
index 2d33201..7e90293 100644
--- a/include/mcl/elgamal.hpp
+++ b/include/mcl/elgamal.hpp
@@ -9,31 +9,27 @@
#include <string>
#include <sstream>
#include <cybozu/unordered_map.hpp>
-#include <cybozu/bitvector.hpp>
#ifndef CYBOZU_UNORDERED_MAP_STD
#include <map>
#endif
#include <cybozu/exception.hpp>
-#include <mcl/tagmultigr.hpp>
-#include <mcl/power_window.hpp>
+#include <mcl/window_method.hpp>
namespace mcl {
-template<class _G, class Zn>
+template<class _Ec, class Zn>
struct ElgamalT {
- typedef _G G;
- typedef TagMultiGr<G> TagG;
+ typedef _Ec Ec;
struct CipherText {
- typedef _G G;
- G c1;
- G c2;
+ Ec c1;
+ Ec c2;
/*
(c1, c2) = (0, 0) is trivial valid ciphertext for m = 0
*/
void clear()
{
- TagG::init(c1);
- TagG::init(c2);
+ c1.clear();
+ c2.clear();
}
/*
add encoded message with encoded message
@@ -42,8 +38,8 @@ struct ElgamalT {
*/
void add(const CipherText& c)
{
- TagG::mul(c1, c1, c.c1);
- TagG::mul(c2, c2, c.c2);
+ Ec::add(c1, c1, c.c1);
+ Ec::add(c2, c2, c.c2);
}
/*
mul by x
@@ -53,8 +49,8 @@ struct ElgamalT {
template<class N>
void mul(const N& x)
{
- G::power(c1, c1, x);
- G::power(c2, c2, x);
+ Ec::mul(c1, c1, x);
+ Ec::mul(c2, c2, x);
}
/*
negative encoded message
@@ -63,8 +59,8 @@ struct ElgamalT {
*/
void neg()
{
- TagG::inv(c1, c1);
- TagG::inv(c2, c2);
+ Ec::neg(c1, c1);
+ Ec::neg(c2, c2);
}
std::string toStr() const
{
@@ -91,31 +87,12 @@ struct ElgamalT {
is.flags(flags);
return is;
}
- void appendToBitVec(cybozu::BitVector& bv) const
- {
- c1.appendToBitVec(bv);
- c2.appendToBitVec(bv);
- }
- void fromBitVec(const cybozu::BitVector& bv)
- {
- size_t bitSize = G::getBitVecSize();
- cybozu::BitVector t;
- bv.extract(t, 0, bitSize);
- c1.fromBitVec(t);
- bv.extract(t, bitSize, bitSize);
- c2.fromBitVec(t);
- }
- static inline size_t getBitVecSize()
- {
- return G::getBitVecSize() * 2;
- }
};
/*
Zero Knowledge Proof
cipher text with ZKP to ensure m = 0 or 1
*/
struct Zkp {
- typedef _G G;
Zn c0, c1, s0, s1;
std::string toStr() const
{
@@ -145,51 +122,50 @@ struct ElgamalT {
};
class PublicKey {
- typedef _G G;
size_t bitSize;
- G f;
- G g;
- G h;
- bool enablePowerWindow_;
- mcl::WindowMethod<G> powf;
- mcl::WindowMethod<G> powg;
- mcl::WindowMethod<G> powh;
+ Ec f;
+ Ec g;
+ Ec h;
+ bool enableWindowMethod_;
+ fp::WindowMethod<Ec> wm_f;
+ fp::WindowMethod<Ec> wm_g;
+ fp::WindowMethod<Ec> wm_h;
template<class N>
- void powerSub(G& z, const G& x, const N& n, const mcl::WindowMethod<G>& pw) const
+ void mulDispatch(Ec& z, const Ec& x, const N& n, const fp::WindowMethod<Ec>& pw) const
{
- if (enablePowerWindow_) {
- pw.power(z, n);
+ if (enableWindowMethod_) {
+ pw.mul(z, n);
} else {
- G::power(z, x, n);
+ Ec::mul(z, x, n);
}
}
template<class N>
- void powerF(G& z, const N& n) const { powerSub(z, f, n, powf); }
+ void mulF(Ec& z, const N& n) const { mulDispatch(z, f, n, wm_f); }
template<class N>
- void powerG(G& z, const N& n) const { powerSub(z, g, n, powg); }
+ void mulG(Ec& z, const N& n) const { mulDispatch(z, g, n, wm_g); }
template<class N>
- void powerH(G& z, const N& n) const { powerSub(z, h, n, powh); }
+ void mulH(Ec& z, const N& n) const { mulDispatch(z, h, n, wm_h); }
public:
PublicKey()
: bitSize(0)
- , enablePowerWindow_(false)
+ , enableWindowMethod_(false)
{
}
void enablePowerWindow(size_t winSize = 10)
{
- powf.init(f, bitSize, winSize);
- powg.init(g, bitSize, winSize);
- powh.init(h, bitSize, winSize);
- enablePowerWindow_ = true;
+ wm_f.init(f, bitSize, winSize);
+ wm_g.init(g, bitSize, winSize);
+ wm_h.init(h, bitSize, winSize);
+ enableWindowMethod_ = true;
}
- const G& getF() const { return f; }
- void init(size_t bitSize, const G& f, const G& g, const G& h)
+ const Ec& getF() const { return f; }
+ void init(size_t bitSize, const Ec& f, const Ec& g, const Ec& h)
{
this->bitSize = bitSize;
this->f = f;
this->g = g;
this->h = h;
- enablePowerWindow_ = false;
+ enableWindowMethod_ = false;
}
/*
encode message
@@ -201,11 +177,11 @@ struct ElgamalT {
{
Zn u;
u.setRand(rg);
- powerG(c.c1, u);
- powerH(c.c2, u);
- G t;
- powerF(t, m);
- TagG::mul(c.c2, c.c2, t);
+ mulG(c.c1, u);
+ mulH(c.c2, u);
+ Ec t;
+ mulF(t, m);
+ Ec::add(c.c2, c.c2, t);
}
/*
encode message
@@ -220,30 +196,30 @@ struct ElgamalT {
}
Zn u;
u.setRand(rg);
- powerG(c.c1, u);
- powerH(c.c2, u);
+ mulG(c.c1, u);
+ mulH(c.c2, u);
if (m) {
- TagG::mul(c.c2, c.c2, f);
+ Ec::add(c.c2, c.c2, f);
Zn r1;
r1.setRand(rg);
zkp.c0.setRand(rg);
zkp.s0.setRand(rg);
- G R01, R02, R11, R12;
- G t1, t2;
- powerG(t1, zkp.s0);
- G::power(t2, c.c1, zkp.c0);
- TagG::div(R01, t1, t2);
- powerH(t1, zkp.s0);
- G::power(t2, c.c2, zkp.c0);
- TagG::div(R02, t1, t2);
- powerG(R11, r1);
- powerH(R12, r1);
+ Ec R01, R02, R11, R12;
+ Ec t1, t2;
+ mulG(t1, zkp.s0);
+ Ec::mul(t2, c.c1, zkp.c0);
+ Ec::sub(R01, t1, t2);
+ mulH(t1, zkp.s0);
+ Ec::mul(t2, c.c2, zkp.c0);
+ Ec::sub(R02, t1, t2);
+ mulG(R11, r1);
+ mulH(R12, r1);
std::ostringstream os;
os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h;
hash.update(os.str());
const std::string digest = hash.digest();
Zn cc;
- cc.setRaw(digest.c_str(), digest.size());
+ cc.setArrayMask(digest.c_str(), digest.size());
zkp.c1 = cc - zkp.c0;
zkp.s1 = r1 + zkp.c1 * u;
} else {
@@ -251,23 +227,23 @@ struct ElgamalT {
r0.setRand(rg);
zkp.c1.setRand(rg);
zkp.s1.setRand(rg);
- G R01, R02, R11, R12;
- powerG(R01, r0);
- powerH(R02, r0);
- G t1, t2;
- powerG(t1, zkp.s1);
- G::power(t2, c.c1, zkp.c1);
- TagG::div(R11, t1, t2);
- powerH(t1, zkp.s1);
- TagG::div(t2, c.c2, f);
- G::power(t2, t2, zkp.c1);
- TagG::div(R12, t1, t2);
+ Ec R01, R02, R11, R12;
+ mulG(R01, r0);
+ mulH(R02, r0);
+ Ec t1, t2;
+ mulG(t1, zkp.s1);
+ Ec::mul(t2, c.c1, zkp.c1);
+ Ec::sub(R11, t1, t2);
+ mulH(t1, zkp.s1);
+ Ec::sub(t2, c.c2, f);
+ Ec::mul(t2, t2, zkp.c1);
+ Ec::sub(R12, t1, t2);
std::ostringstream os;
os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h;
hash.update(os.str());
const std::string digest = hash.digest();
Zn c;
- c.setRaw(digest.c_str(), digest.size());
+ c.setArrayMask(digest.c_str(), digest.size());
zkp.c0 = c - zkp.c1;
zkp.s0 = r0 + zkp.c0 * u;
}
@@ -278,27 +254,27 @@ struct ElgamalT {
template<class Hash>
bool verify(const CipherText& c, const Zkp& zkp, Hash& hash) const
{
- G R01, R02, R11, R12;
- G t1, t2;
- powerG(t1, zkp.s0);
- G::power(t2, c.c1, zkp.c0);
- TagG::div(R01, t1, t2);
- powerH(t1, zkp.s0);
- G::power(t2, c.c2, zkp.c0);
- TagG::div(R02, t1, t2);
- powerG(t1, zkp.s1);
- G::power(t2, c.c1, zkp.c1);
- TagG::div(R11, t1, t2);
- powerH(t1, zkp.s1);
- TagG::div(t2, c.c2, f);
- G::power(t2, t2, zkp.c1);
- TagG::div(R12, t1, t2);
+ Ec R01, R02, R11, R12;
+ Ec t1, t2;
+ mulG(t1, zkp.s0);
+ Ec::mul(t2, c.c1, zkp.c0);
+ Ec::sub(R01, t1, t2);
+ mulH(t1, zkp.s0);
+ Ec::mul(t2, c.c2, zkp.c0);
+ Ec::sub(R02, t1, t2);
+ mulG(t1, zkp.s1);
+ Ec::mul(t2, c.c1, zkp.c1);
+ Ec::sub(R11, t1, t2);
+ mulH(t1, zkp.s1);
+ Ec::sub(t2, c.c2, f);
+ Ec::mul(t2, t2, zkp.c1);
+ Ec::sub(R12, t1, t2);
std::ostringstream os;
os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h;
hash.update(os.str());
const std::string digest = hash.digest();
Zn cc;
- cc.setRaw(digest.c_str(), digest.size());
+ cc.setArrayMask(digest.c_str(), digest.size());
return cc == zkp.c0 + zkp.c1;
}
/*
@@ -311,11 +287,11 @@ struct ElgamalT {
{
Zn v;
v.setRand(rg);
- G t;
- powerG(t, v);
- TagG::mul(c.c1, c.c1, t);
- powerH(t, v);
- TagG::mul(c.c2, c.c2, t);
+ Ec t;
+ mulG(t, v);
+ Ec::add(c.c1, c.c1, t);
+ mulH(t, v);
+ Ec::add(c.c2, c.c2, t);
}
/*
add encoded message with plain message
@@ -325,9 +301,9 @@ struct ElgamalT {
template<class N>
void add(CipherText& c, const N& m) const
{
- G fm;
- powerF(fm, m);
- TagG::mul(c.c2, c.c2, fm);
+ Ec fm;
+ mulF(fm, m);
+ Ec::add(c.c2, c.c2, fm);
}
std::string toStr() const
{
@@ -351,7 +327,7 @@ struct ElgamalT {
{
std::ios_base::fmtflags flags = is.flags();
size_t bitSize;
- G f, g, h;
+ Ec f, g, h;
is >> std::dec >> bitSize >> std::hex >> f >> g >> h;
is.flags(flags);
self.init(bitSize, f, g, h);
@@ -363,23 +339,22 @@ struct ElgamalT {
PublicKey pub;
Zn z;
public:
- typedef _G G;
/*
init
input : f
output : (g, h, z)
- G = <f>
- g in G
+ Ec = <f>
+ g in Ec
h = g^z
*/
template<class RG>
- void init(const G& f, size_t bitSize, RG& rg)
+ void init(const Ec& f, size_t bitSize, RG& rg)
{
- G g, h;
+ Ec g, h;
z.setRand(rg);
- G::power(g, f, z);
+ Ec::mul(g, f, z);
z.setRand(rg);
- G::power(h, g, z);
+ Ec::mul(h, g, z);
pub.init(bitSize, f, g, h);
}
const PublicKey& getPublicKey() const { return pub; }
@@ -393,22 +368,22 @@ struct ElgamalT {
*/
void dec(Zn& m, const CipherText& c, int limit = 100000) const
{
- const G& f = pub.getF();
- G c1z;
- G::power(c1z, c.c1, z);
+ const Ec& f = pub.getF();
+ Ec c1z;
+ Ec::mul(c1z, c.c1, z);
if (c1z == c.c2) {
m = 0;
return;
}
- G t1(c1z);
- G t2(c.c2);
+ Ec t1(c1z);
+ Ec t2(c.c2);
for (int i = 1; i < limit; i++) {
- TagG::mul(t1, t1, f);
+ Ec::add(t1, t1, f);
if (t1 == c.c2) {
m = i;
return;
}
- TagG::mul(t2, t2, f);
+ Ec::add(t2, t2, f);
if (t2 == c1z) {
m = -i;
return;
@@ -419,19 +394,19 @@ struct ElgamalT {
/*
powfm = c2 / c1^z = f^m
*/
- void getPowerf(G& powfm, const CipherText& c) const
+ void getPowerf(Ec& powfm, const CipherText& c) const
{
- G c1z;
- G::power(c1z, c.c1, z);
- TagG::div(powfm, c.c2, c1z);
+ Ec c1z;
+ Ec::mul(c1z, c.c1, z);
+ Ec::sub(powfm, c.c2, c1z);
}
/*
check whether c is encrypted zero message
*/
bool isZeroMessage(const CipherText& c) const
{
- G c1z;
- G::power(c1z, c.c1, z);
+ Ec c1z;
+ Ec::mul(c1z, c.c1, z);
return c.c2 == c1z;
}
std::string toStr() const
@@ -464,35 +439,34 @@ struct ElgamalT {
create table f^i for i in [rangeMin, rangeMax]
*/
struct PowerCache {
- typedef _G G;
#if (CYBOZU_CPP_VERSION > CYBOZU_CPP_VERSION_CP03)
- typedef CYBOZU_NAMESPACE_STD::unordered_map<G, int> Cache;
+ typedef CYBOZU_NAMESPACE_STD::unordered_map<Ec, int> Cache;
#else
- typedef std::map<G, int> Cache;
+ typedef std::map<Ec, int> Cache;
#endif
Cache cache;
- void init(const G& f, int rangeMin, int rangeMax)
+ void init(const Ec& f, int rangeMin, int rangeMax)
{
if (rangeMin > rangeMax) throw cybozu::Exception("mcl:ElgamalT:PowerCache:bad range") << rangeMin << rangeMax;
- G x;
+ Ec x;
x.clear();
cache[x] = 0;
for (int i = 1; i <= rangeMax; i++) {
- TagG::mul(x, x, f);
+ Ec::add(x, x, f);
cache[x] = i;
}
- G nf;
- TagG::inv(nf, f);
+ Ec nf;
+ Ec::neg(nf, f);
x.clear();
for (int i = -1; i >= rangeMin; i--) {
- TagG::mul(x, x, nf);
+ Ec::add(x, x, nf);
cache[x] = i;
}
}
/*
return m such that f^m = g
*/
- int getExponent(const G& g) const
+ int getExponent(const Ec& g) const
{
typename Cache::const_iterator i = cache.find(g);
if (i == cache.end()) throw cybozu::Exception("Elgamal:PowerCache:getExponent:not found") << g;
diff --git a/include/mcl/fp.hpp b/include/mcl/fp.hpp
index 0922df4..27b559e 100644
--- a/include/mcl/fp.hpp
+++ b/include/mcl/fp.hpp
@@ -33,6 +33,8 @@ void arrayToStr(std::string& str, const Unit *x, size_t n, int base, bool withPr
void strToGmp(mpz_class& x, bool *isMinus, const std::string& str, int base);
+bool copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, bool doMask);
+
} // mcl::fp
template<class tag = fp::TagDefault, size_t maxBitSize = MCL_MAX_OP_BIT_SIZE>
@@ -45,7 +47,8 @@ class FpT {
public:
// return pointer to array v_[]
const Unit *getUnit() const { return v_; }
- size_t getUnitSize() const { return op_.N; }
+ static inline size_t getUnitSize() { return op_.N; }
+ static inline size_t getBitSize() { return op_.bitSize; }
void dump() const
{
const size_t N = op_.N;
@@ -139,17 +142,23 @@ public:
}
toMont(*this, *this);
}
- // alias of setStr
+ /*
+ if doMask
+ trim inBuf and sub p if necessary
+ otherwise throw exception if inBuf >= p
+ */
template<class S>
void setArray(const S *inBuf, size_t n)
{
- const size_t SbyteSize = sizeof(S) * n;
- const size_t fpByteSize = sizeof(Unit) * op_.N;
- if (SbyteSize > fpByteSize) throw cybozu::Exception("FpT:setArray:bad n") << n << fpByteSize;
- assert(SbyteSize <= fpByteSize);
- memcpy(v_, inBuf, SbyteSize);
- memset((char *)v_ + SbyteSize, 0, fpByteSize - SbyteSize);
- if (!isValid()) throw cybozu::Exception("FpT:setArray:large value");
+ if (!fp::copyAndMask(v_, inBuf, sizeof(S) * n, op_, false)) {
+ throw cybozu::Exception("FpT:setArray:large value") << n;
+ }
+ toMont(*this, *this);
+ }
+ template<class S>
+ void setArrayMask(const S *inBuf, size_t n)
+ {
+ fp::copyAndMask(v_, inBuf, sizeof(S) * n, op_, true);
toMont(*this, *this);
}
template<class S>
diff --git a/src/fp.cpp b/src/fp.cpp
index 7af1790..c35e58f 100644
--- a/src/fp.cpp
+++ b/src/fp.cpp
@@ -317,5 +317,26 @@ void arrayToStr(std::string& str, const Unit *x, size_t n, int base, bool withPr
}
}
+bool copyAndMask(Unit *y, const void *x, size_t xByteSize, const Op& op, bool doMask)
+{
+ const size_t fpByteSize = sizeof(Unit) * op.N;
+ if (xByteSize > fpByteSize) {
+ if (!doMask) return false;
+ xByteSize = fpByteSize;
+ }
+ memcpy(y, x, xByteSize);
+ memset((char *)y + xByteSize, 0, fpByteSize - xByteSize);
+ if (!doMask) return compareArray(y, op.p, op.N) < 0;
+
+ Unit r = op.bitSize % UnitBitSize;
+ if (r) {
+ y[op.N - 1] &= (Unit(1) << r) - 1;
+ }
+ if (compareArray(y, op.p, op.N) >= 0) {
+ op.subP(y, y, op.p, op.p);
+ }
+ return true;
+}
+
} } // mcl::fp
diff --git a/test/elgamal_test.cpp b/test/elgamal_test.cpp
index 0ceb86b..a5a26da 100644
--- a/test/elgamal_test.cpp
+++ b/test/elgamal_test.cpp
@@ -3,189 +3,23 @@
#include <mcl/gmp_util.hpp>
#include <mcl/elgamal.hpp>
#include <cybozu/random_generator.hpp>
-#include <mcl/ecparam.hpp>
-#include <cybozu/crypto.hpp>
#if defined(_WIN64) || defined(__x86_64__)
#define USE_MONT_FP
#endif
-#ifdef USE_MONT_FP
-#include <mcl/mont_fp.hpp>
-typedef mcl::MontFpT<3> Fp;
-#else
-typedef mcl::FpT<mcl::Gmp> Fp;
-#endif
-typedef mcl::EcT<Fp> Ec;
+#include <mcl/ecparam.hpp>
+#include <cybozu/crypto.hpp>
-struct TagFp;
-struct TagEc;
+struct TagZn;
+typedef mcl::FpT<> Fp;
+typedef mcl::FpT<TagZn> Zn;
+typedef mcl::EcT<Fp> Ec;
+typedef mcl::ElgamalT<Ec, Zn> ElgamalEc;
const mcl::EcParam& para = mcl::ecparam::secp192k1;
cybozu::RandomGenerator rg;
-CYBOZU_TEST_AUTO(testFp)
-{
- typedef mcl::FpT<mcl::Gmp, TagFp> Zn;
- typedef mcl::ElgamalT<Fp, Zn> ElgamalFp;
- /*
- Zn = (Z/mZ) - {0}
- */
- const int m = 65537;
- {
- std::ostringstream os;
- os << m;
- Fp::setModulo(os.str());
- }
- {
- std::ostringstream os;
- os << m - 1;
- Zn::setModulo(os.str());
- }
- ElgamalFp::PrivateKey prv;
-
- /*
- 3^(m-1) = 1
- */
- const int f = 3;
- {
- Fp x(f);
- Fp::power(x, x, m - 1);
- CYBOZU_TEST_EQUAL(x, 1);
- }
- prv.init(f, 17, rg);
- const ElgamalFp::PublicKey& pub = prv.getPublicKey();
-
- const int m1 = 12345;
- const int m2 = 17655;
- ElgamalFp::CipherText c1, c2;
- pub.enc(c1, m1, rg);
- pub.enc(c2, m2, rg);
- // BitVector
- {
- cybozu::BitVector bv;
- c1.appendToBitVec(bv);
- ElgamalFp::CipherText c3;
- c3.fromBitVec(bv);
- CYBOZU_TEST_EQUAL(c1.c1, c3.c1);
- CYBOZU_TEST_EQUAL(c1.c2, c3.c2);
- }
- Zn dec1, dec2;
- prv.dec(dec1, c1);
- prv.dec(dec2, c2);
- // dec(enc) = id
- CYBOZU_TEST_EQUAL(dec1, m1);
- CYBOZU_TEST_EQUAL(dec2, m2);
- // iostream
- {
- ElgamalFp::PublicKey pub2;
- ElgamalFp::PrivateKey prv2;
- ElgamalFp::CipherText cc1, cc2;
- {
- std::stringstream ss;
- ss << prv;
- ss >> prv2;
- }
- Zn d;
- prv2.dec(d, c1);
- CYBOZU_TEST_EQUAL(d, m1);
- {
- std::stringstream ss;
- ss << c1;
- ss >> cc1;
- }
- d = 0;
- prv2.dec(d, cc1);
- CYBOZU_TEST_EQUAL(d, m1);
- {
- std::stringstream ss;
- ss << pub;
- ss >> pub2;
- }
- pub2.enc(cc2, m2, rg);
- prv.dec(d, cc2);
- CYBOZU_TEST_EQUAL(d, m2);
- }
- // enc(m1) enc(m2) = enc(m1 + m2)
- c1.add(c2);
- prv.dec(dec1, c1);
- CYBOZU_TEST_EQUAL(dec1, m1 + m2);
- // enc(m1) x = enc(m1 + x)
- const int x = 555;
- pub.add(c1, x);
- prv.dec(dec1, c1);
- CYBOZU_TEST_EQUAL(dec1, m1 + m2 + x);
- // rerandomize
- c1 = c2;
- pub.rerandomize(c1, rg);
- // verify c1 != c2
- CYBOZU_TEST_ASSERT(c1.c1 != c2.c1);
- CYBOZU_TEST_ASSERT(c1.c2 != c2.c2);
- prv.dec(dec1, c1);
- // dec(c1) = dec(c2)
- CYBOZU_TEST_EQUAL(dec1, m2);
-
- // check neg
- {
- ElgamalFp::CipherText c;
- Zn m = 1234;
- pub.enc(c, m, rg);
- c.neg();
- Zn dec;
- prv.dec(dec, c);
- CYBOZU_TEST_EQUAL(dec, -m);
- }
- // check mul
- {
- ElgamalFp::CipherText c;
- Zn m = 1234;
- int x = 111;
- pub.enc(c, m, rg);
- c.mul(x);
- Zn dec;
- prv.dec(dec, c);
- m *= x;
- CYBOZU_TEST_EQUAL(dec, m);
- }
- // check negative value
- for (int i = -10; i < 10; i++) {
- ElgamalFp::CipherText c;
- const Zn mm = i;
- pub.enc(c, mm, rg);
- Zn dec;
- prv.dec(dec, c, 1000);
- CYBOZU_TEST_EQUAL(dec, mm);
- }
-
- // isZeroMessage
- for (int m = 0; m < 10; m++) {
- ElgamalFp::CipherText c0;
- pub.enc(c0, m, rg);
- if (m == 0) {
- CYBOZU_TEST_ASSERT(prv.isZeroMessage(c0));
- } else {
- CYBOZU_TEST_ASSERT(!prv.isZeroMessage(c0));
- }
- }
- // zkp
- {
- ElgamalFp::Zkp zkp;
- ElgamalFp::CipherText c;
- cybozu::crypto::Hash hash(cybozu::crypto::Hash::N_SHA256);
- pub.encWithZkp(c, zkp, 0, hash, rg);
- CYBOZU_TEST_ASSERT(pub.verify(c, zkp, hash));
- zkp.s0 += 1;
- CYBOZU_TEST_ASSERT(!pub.verify(c, zkp, hash));
- pub.encWithZkp(c, zkp, 1, hash, rg);
- CYBOZU_TEST_ASSERT(pub.verify(c, zkp, hash));
- zkp.s0 += 1;
- CYBOZU_TEST_ASSERT(!pub.verify(c, zkp, hash));
- CYBOZU_TEST_EXCEPTION_MESSAGE(pub.encWithZkp(c, zkp, 2, hash, rg), cybozu::Exception, "encWithZkp");
- }
-}
-
CYBOZU_TEST_AUTO(testEc)
{
- typedef mcl::FpT<mcl::Gmp, TagEc> Zn;
- typedef mcl::ElgamalT<Ec, Zn> ElgamalEc;
Fp::setModulo(para.p);
Zn::setModulo(para.n);
Ec::setParam(para.a, para.b);
@@ -205,15 +39,6 @@ CYBOZU_TEST_AUTO(testEc)
ElgamalEc::CipherText c1, c2;
pub.enc(c1, m1, rg);
pub.enc(c2, m2, rg);
- // BitVector
- {
- cybozu::BitVector bv;
- c1.appendToBitVec(bv);
- ElgamalEc::CipherText c3;
- c3.fromBitVec(bv);
- CYBOZU_TEST_EQUAL(c1.c1, c3.c1);
- CYBOZU_TEST_EQUAL(c1.c2, c3.c2);
- }
Zn dec1, dec2;
prv.dec(dec1, c1);
prv.dec(dec2, c2);
diff --git a/test/window_method_test.cpp b/test/window_method_test.cpp
index 2d651be..58547e2 100644
--- a/test/window_method_test.cpp
+++ b/test/window_method_test.cpp
@@ -36,10 +36,10 @@ CYBOZU_TEST_AUTO(int)
const Ec P(x, y);
typedef mcl::fp::WindowMethod<Ec> PW;
- const size_t bitSize = 16;
+ const size_t bitSize = 13;
Ec Q, R;
- for (size_t winSize = 2; winSize <= bitSize; winSize += 3) {
+ for (size_t winSize = 10; winSize <= bitSize; winSize++) {
PW pw(P, bitSize, winSize);
for (int i = 0; i < (1 << bitSize); i++) {
pw.mul(Q, i);