Code base obscuration (for images) 1.0
It implements different obscuration methods on portable images (.pgm and .ppm)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Paillier.hpp
Go to the documentation of this file.
1
11#define BITSETSIZE 64
12
13#ifndef PAILLIER_CRYPTOSYSTEM
14#define PAILLIER_CRYPTOSYSTEM
15
16#include <iostream>
17#include <bitset>
18#include <vector>
19#include <random> //Randomdevice and mt19937
20
21using namespace std;
22
31template <typename T_in, typename T_out>
33{
34public:
41
49
59 uint64_t random64(uint64_t min, uint64_t max)
60 {
61 static std::random_device rd;
62 static std::mt19937 gen(rd());
63 std::uniform_int_distribution<std::uint64_t> dis(min, max);
64 return dis(gen);
65 }
66
77 uint64_t fastMod_64t(uint64_t x, uint64_t e, uint64_t n)
78 {
79 uint64_t c = 1;
80 bitset<BITSETSIZE> bits = bitset<BITSETSIZE>(e);
81
82 for (int i = BITSETSIZE - 1; i >= 0; i--)
83 {
84 c = c * c % n;
85 if (bits[i] & 1)
86 c = c * x % n;
87 }
88
89 return c;
90 };
91
101 uint64_t gcd_64t(uint64_t a, uint64_t b)
102 {
103 if (b == 0)
104 {
105 return a;
106 }
107 return gcd_64t(b, a % b);
108 };
109
119 std::vector<uint64_t> calc_set_same_remainder_divide_euclide_64t(uint64_t n)
120 {
121 std::vector<uint64_t> result;
122 for (uint64_t i = 0; i < n; i++)
123 {
124 if (gcd_64t(i, n) == 1)
125 {
126 result.push_back(i);
127 }
128 }
129 return result;
130 };
131
142 std::vector<uint64_t> calc_set_same_remainder_divide_euclide_64t_v2(uint64_t n, const uint64_t &lambda)
143 {
144 std::vector<uint64_t> result;
145
146 uint64_t x, r = 0, mu = 0;
147 for (uint64_t g = 0; g < n; g++)
148 {
149 if (gcd_64t(g, n) == 1)
150 {
151 uint64_t u = fastMod_64t(g, lambda, n * n);
152 uint64_t l = (u - 1) / n;
153 r = (x - 1) % n; // Vérifier si x est entier.
154 mu = modInverse_64t(l, n);
155 if (mu != 0)
156 {
157 result.push_back(g);
158 }
159 }
160 }
161 return result;
162 };
163
175 uint64_t choose_g_in_vec_64t(std::vector<uint64_t> &set, const uint64_t &n, const uint64_t &lambda)
176 {
177 uint64_t x;
178 int i_position = 0;
179 uint64_t g = 0, r = 1, r2 = 1, mu = 0;
180 while (r != 0 && r2 != 0 && mu == 0)
181 {
182 i_position = rand() % set.size();
183 g = set.at(i_position);
184 x = fastMod_64t(g, lambda, n * n);
185 r = (x - 1) % n; // Vérifier si L(x) est entier.
186 r2 = (x - 1) / n; // Vérifier si L(x) est entier.
187 mu = modInverse_64t(r2, n); // Calculer μ en utilisant la formule donnée et la fonction modular_inverse pour calculer l'inverse modulaire
188 }
189 return g;
190 };
191
201 uint64_t choose_g_in_vec_64t_v2(std::vector<uint64_t> &set)
202 {
203 int i_position = rand() % set.size();
204 return set.at(i_position);
205 };
206
215 uint64_t L_64t(uint64_t x, uint64_t n)
216 {
217 return (x - 1) / n;
218 };
219
228 uint64_t lcm_64t(uint64_t a, uint64_t b)
229 {
230 return a * b / gcd_64t(a, b);
231 };
232
241 uint64_t modInverse_64t(uint64_t a, uint64_t n)
242 {
243 a = a % n;
244 for (uint64_t x = 1; x < n; x++)
245 {
246 if ((a * x) % n == 1)
247 return x;
248 }
249
250 return 0;
251 };
252
262 uint64_t pow_uint64_t(uint64_t x, uint64_t n)
263 {
264 if (n == 0)
265 {
266 return 1;
267 }
268 return x * pow_uint64_t(x, n - 1);
269 };
270
281 uint64_t randomZNStar(uint64_t n)
282 {
283 uint64_t r = 0;
284 do
285 {
286 r = random64(1, n);
287 } while (r >= 1 && gcd_64t(r, n) != 1);
288 return r;
289 };
290
299 std::vector<uint64_t> get_set_ZNZStar(uint64_t n)
300 {
301 std::vector<uint64_t> ZNZStar;
302 for (uint64_t i = 1; i < n; i++)
303 {
304 if (gcd_64t(i, n) == 1)
305 {
306 ZNZStar.push_back(i);
307 }
308 }
309 return ZNZStar;
310 }
311
321 std::vector<uint64_t> get_set_ZN2ZStar(uint64_t n, uint64_t lambda)
322 {
323 std::vector<uint64_t> ZN2ZStar;
324 for (uint64_t g = 1; g < n * n; g++)
325 {
326 uint64_t u, l;
327 u = fastMod_64t(g, lambda, n * n);
328 l = L_64t(u, n);
329 if (gcd_64t(l, n) == 1)
330 {
331 ZN2ZStar.push_back(g);
332 }
333 }
334 return ZN2ZStar;
335 }
336
347 uint64_t generate_g_64t(uint64_t n, uint64_t lambda)
348 {
349 uint64_t g, u, l;
350 do
351 {
352 g = randomZNStar(n * n); // generate g, a random integer in Z*_{n^2}
353 u = fastMod_64t(g, lambda, n * n);
354 l = L_64t(u, n);
355 } while (gcd_64t(l, n) != 1);
356 return g;
357 };
358
369 void generateMu_64t(uint64_t &mu, const uint64_t &g, const uint64_t &lambda, const uint64_t &n)
370 {
371 uint64_t u = fastMod_64t(g, lambda, n * n);
372 uint64_t l = (u - 1) / n;
373 mu = modInverse_64t(l, n);
374 };
375
387 void generatePrivateKey_64t(uint64_t &lambda, uint64_t &mu, const uint64_t &p, const uint64_t &q, const uint64_t &n, const uint64_t &g)
388 {
389 lambda = lcm_64t(p - 1, q - 1);
390
391 generateMu_64t(mu, g, lambda, n);
392 };
393
394 //================ Overload and Generic programming ================//
395
407 T_out paillierEncryption(uint64_t n, uint64_t g, T_in m)
408 {
409 if (m >= std::numeric_limits<uint64_t>::max())
410 {
411 throw std::runtime_error("Erreur m ne peut pas être stocké dans 64 bits.");
412 }
413 uint64_t m_64 = static_cast<uint64_t>(m);
414
415 uint64_t c;
416 // uint64_t r = random64(0,n);
417 // while (gcd_64t(r, n) != 1 || r == 0)
418 // {
419 // r = random64(0,n);
420 // }
421 uint64_t r = randomZNStar(n);
422
423 // fprintf(stdout, "r : %" PRIu64 "\n", r);
424
425 uint64_t fm1 = fastMod_64t(g, m_64, n * n);
426 uint64_t fm2 = fastMod_64t(r, n, n * n);
427 c = (fm1 * fm2) % (n * n);
428
429 if (c >= std::numeric_limits<T_out>::max())
430 {
431 throw std::runtime_error("Erreur le résultat ne peut pas être stocké dans n*2 bits.");
432 }
433 return static_cast<T_out>(c);
434 };
435
448 T_out paillierEncryption(uint64_t n, uint64_t g, T_in m, uint64_t r)
449 {
450 if (m >= std::numeric_limits<uint64_t>::max())
451 {
452 throw std::runtime_error("Erreur m ne peut pas être stocké dans 64 bits.");
453 }
454 uint64_t m_64 = static_cast<uint64_t>(m);
455
456 uint64_t c;
457 uint64_t fm1 = fastMod_64t(g, m_64, n * n);
458 uint64_t fm2 = fastMod_64t(r, n, n * n);
459 c = (fm1 * fm2) % (n * n);
460
461 if (c >= std::numeric_limits<T_out>::max())
462 {
463 throw std::runtime_error("Erreur le résultat ne peut pas être stocké dans n*2 bits.");
464 }
465 return static_cast<T_out>(c);
466 };
467
480 T_in paillierDecryption(uint64_t n, uint64_t lambda, uint64_t mu, T_out c)
481 {
482 if (c >= std::numeric_limits<uint64_t>::max())
483 {
484 throw std::runtime_error("Erreur m ne peut pas être stocké dans 64 bits.");
485 }
486 uint64_t c_64 = static_cast<uint64_t>(c);
487
488 // uint64_t result = (((fastMod_64t(c_64, lambda, n * n) - 1) / n) * mu) % n;
489 uint64_t result = ((fastMod_64t(c_64, lambda, n * n) - 1) / n) * mu % n;
490
491 if (result >= std::numeric_limits<T_in>::max())
492 {
493 throw std::runtime_error("Erreur le résultat ne peut pas être stocké dans 8 bits.");
494 }
495 return static_cast<T_in>(result);
496 };
497};
498
499#endif // PAILLIER_CRYPTOSYSTEM
#define BITSETSIZE
Definition Paillier.hpp:11
This class implements the Paillier cryptosystem.
Definition Paillier.hpp:33
std::vector< uint64_t > get_set_ZN2ZStar(uint64_t n, uint64_t lambda)
Return the set Z/n²Z* that satisfy the condition gcd(L(g^lambda mod n²), n) = 1 as a vector.
Definition Paillier.hpp:321
uint64_t choose_g_in_vec_64t(std::vector< uint64_t > &set, const uint64_t &n, const uint64_t &lambda)
Choose g from the set of elements in (Z/n²Z)* that satisfy the condition L(x) = (x-1)/n where x is a ...
Definition Paillier.hpp:175
void generatePrivateKey_64t(uint64_t &lambda, uint64_t &mu, const uint64_t &p, const uint64_t &q, const uint64_t &n, const uint64_t &g)
Generate private key for Paillier cryptosystem.
Definition Paillier.hpp:387
T_out paillierEncryption(uint64_t n, uint64_t g, T_in m)
Encrypt a message using Paillier cryptosystem.
Definition Paillier.hpp:407
uint64_t lcm_64t(uint64_t a, uint64_t b)
Calculate the least common multiple (LCM) of two 64-bit unsigned integers.
Definition Paillier.hpp:228
uint64_t L_64t(uint64_t x, uint64_t n)
Calculate L(x).
Definition Paillier.hpp:215
uint64_t fastMod_64t(uint64_t x, uint64_t e, uint64_t n)
Calculate the modular exponentiation of a base raised to a power modulo a modulus.
Definition Paillier.hpp:77
std::vector< uint64_t > calc_set_same_remainder_divide_euclide_64t_v2(uint64_t n, const uint64_t &lambda)
Calculate the set of elements in (Z/n²Z)* that satisfy the condition L(x) = (x-1)/n where x is a posi...
Definition Paillier.hpp:142
uint64_t pow_uint64_t(uint64_t x, uint64_t n)
Calculate the power of a 64-bit unsigned integer.
Definition Paillier.hpp:262
std::vector< uint64_t > calc_set_same_remainder_divide_euclide_64t(uint64_t n)
Calculate the set of elements in (Z/n²Z)*.
Definition Paillier.hpp:119
uint64_t modInverse_64t(uint64_t a, uint64_t n)
Calculate the modular inverse of a 64-bit unsigned integer modulo a modulus.
Definition Paillier.hpp:241
Paillier()
Construct a new Paillier object.
Definition Paillier.hpp:40
uint64_t choose_g_in_vec_64t_v2(std::vector< uint64_t > &set)
Choose g from the set of elements in (Z/n²Z)*.
Definition Paillier.hpp:201
T_in paillierDecryption(uint64_t n, uint64_t lambda, uint64_t mu, T_out c)
Decrypt a ciphertext using Paillier cryptosystem.
Definition Paillier.hpp:480
uint64_t generate_g_64t(uint64_t n, uint64_t lambda)
Generate g for Paillier cryptosystem.
Definition Paillier.hpp:347
uint64_t random64(uint64_t min, uint64_t max)
Generate a random 64-bit unsigned integer.
Definition Paillier.hpp:59
uint64_t gcd_64t(uint64_t a, uint64_t b)
Calculate the greatest common divisor (GCD) of two 64-bit unsigned integers.
Definition Paillier.hpp:101
std::vector< uint64_t > get_set_ZNZStar(uint64_t n)
Return the set Z/nZ* as a vector.
Definition Paillier.hpp:299
T_out paillierEncryption(uint64_t n, uint64_t g, T_in m, uint64_t r)
Encrypt a message using Paillier cryptosystem with a given random value.
Definition Paillier.hpp:448
~Paillier()
Destroy the Paillier object.
Definition Paillier.hpp:48
uint64_t randomZNStar(uint64_t n)
Choose a random element from the set Z/nZ*.
Definition Paillier.hpp:281
void generateMu_64t(uint64_t &mu, const uint64_t &g, const uint64_t &lambda, const uint64_t &n)
Generate Mu for Paillier cryptosystem.
Definition Paillier.hpp:369