aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2015-11-05 20:39:00 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2015-11-05 20:39:00 +0800
commit5a1e0f32a45aaab012298100d0390e92ef8d701c (patch)
tree33444e810725b881d2d0738b2e41c543efdbb182
parent68ae774b9f6592437cef6f10c8578cbf67e47136 (diff)
downloaddexon-mcl-5a1e0f32a45aaab012298100d0390e92ef8d701c.tar.gz
dexon-mcl-5a1e0f32a45aaab012298100d0390e92ef8d701c.tar.zst
dexon-mcl-5a1e0f32a45aaab012298100d0390e92ef8d701c.zip
update elgamal.hpp
-rw-r--r--include/mcl/elgamal.hpp122
1 files changed, 82 insertions, 40 deletions
diff --git a/include/mcl/elgamal.hpp b/include/mcl/elgamal.hpp
index 1938a8e..f52da1b 100644
--- a/include/mcl/elgamal.hpp
+++ b/include/mcl/elgamal.hpp
@@ -345,10 +345,63 @@ struct ElgamalT {
return is;
}
};
-
+ /*
+ create table f^i for i in [rangeMin, rangeMax]
+ */
+ struct PowerCache {
+#if (CYBOZU_CPP_VERSION > CYBOZU_CPP_VERSION_CP03)
+ typedef CYBOZU_NAMESPACE_STD::unordered_map<Ec, int> Cache;
+#else
+ typedef std::map<Ec, int> Cache;
+#endif
+ Cache cache;
+ void init(const Ec& f, int rangeMin, int rangeMax)
+ {
+ if (rangeMin > rangeMax) throw cybozu::Exception("mcl:ElgamalT:PowerCache:bad range") << rangeMin << rangeMax;
+ Ec x;
+ x.clear();
+ cache[x] = 0;
+ for (int i = 1; i <= rangeMax; i++) {
+ Ec::add(x, x, f);
+ cache[x] = i;
+ }
+ Ec nf;
+ Ec::neg(nf, f);
+ x.clear();
+ for (int i = -1; i >= rangeMin; i--) {
+ Ec::add(x, x, nf);
+ cache[x] = i;
+ }
+ }
+ /*
+ return m such that f^m = g
+ */
+ int getExponent(const Ec& g, bool *b = 0) const
+ {
+ typename Cache::const_iterator i = cache.find(g);
+ if (i == cache.end()) {
+ if (b) {
+ *b = false;
+ return 0;
+ }
+ throw cybozu::Exception("Elgamal:PowerCache:getExponent:not found") << g;
+ }
+ if (b) *b = true;
+ return i->second;
+ }
+ void clear()
+ {
+ cache.clear();
+ }
+ bool isEmpty() const
+ {
+ return cache.empty();
+ }
+ };
class PrivateKey {
PublicKey pub;
Zn z;
+ PowerCache cache;
public:
/*
init
@@ -370,7 +423,7 @@ struct ElgamalT {
}
const PublicKey& getPublicKey() const { return pub; }
/*
- decode message
+ decode message by brute-force attack
input : c = (c1, c2)
output : m
M = c2 / c1^z
@@ -412,6 +465,33 @@ struct ElgamalT {
Ec::sub(powfm, c.c2, c1z);
}
/*
+ set range of message to decode quickly
+ */
+ void setCache(int rangeMin, int rangeMax)
+ {
+ cache.init(pub.getF(), rangeMin, rangeMax);
+ }
+ /*
+ clear cache
+ */
+ void clearCache()
+ {
+ cache.clear();
+ }
+ /*
+ decode message by lookup table if !cache.isEmpty()
+ brute-force attack otherwise
+ input : c = (c1, c2)
+ b : set false if not found
+ return m
+ */
+ int dec(const CipherText& c, bool *b = 0) const
+ {
+ Ec powfm;
+ getPowerf(powfm, c);
+ return cache.getExponent(powfm, b);
+ }
+ /*
check whether c is encrypted zero message
*/
bool isZeroMessage(const CipherText& c) const
@@ -448,44 +528,6 @@ struct ElgamalT {
return is;
}
};
- /*
- create table f^i for i in [rangeMin, rangeMax]
- */
- struct PowerCache {
-#if (CYBOZU_CPP_VERSION > CYBOZU_CPP_VERSION_CP03)
- typedef CYBOZU_NAMESPACE_STD::unordered_map<Ec, int> Cache;
-#else
- typedef std::map<Ec, int> Cache;
-#endif
- Cache cache;
- void init(const Ec& f, int rangeMin, int rangeMax)
- {
- if (rangeMin > rangeMax) throw cybozu::Exception("mcl:ElgamalT:PowerCache:bad range") << rangeMin << rangeMax;
- Ec x;
- x.clear();
- cache[x] = 0;
- for (int i = 1; i <= rangeMax; i++) {
- Ec::add(x, x, f);
- cache[x] = i;
- }
- Ec nf;
- Ec::neg(nf, f);
- x.clear();
- for (int i = -1; i >= rangeMin; i--) {
- Ec::add(x, x, nf);
- cache[x] = i;
- }
- }
- /*
- return m such that f^m = g
- */
- 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;
- return i->second;
- }
- };
};
} // mcl