elgamal.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "config.h"
  2. #include <gmp.h>
  3. #include "elgamal.h"
  4. #include "entropy.h"
  5. #include "group.h"
  6. #include "hss.h"
  7. void elgamal_keygen(elgamal_key_t rop)
  8. {
  9. mpz_set_ui(rop->pk, 2);
  10. /*
  11. yes we know GMP's RNG is NOT cryptographically secure.
  12. we laughed at the "random functions" page, too.
  13. however a rng mod p is not really the point of this project is it?
  14. */
  15. // mpz_urandomm(rop->sk, _rstate, q);
  16. mpz_urandomb(rop->sk, _rstate, SK_SIZE);
  17. mpz_powm(rop->pk, rop->pk, rop->sk, p);
  18. }
  19. void elgamal_encrypt(elgamal_cipher_t rop, const elgamal_key_t k, const mpz_t m)
  20. {
  21. mpz_t x;
  22. mpz_init(x);
  23. mpz_urandomm(x, _rstate, q);
  24. mpz_set_ui(rop->c1, 2);
  25. mpz_powm(rop->c1, rop->c1, x, p);
  26. mpz_invert(rop->c1, rop->c1, p);
  27. /* cached intermediate values */
  28. mpz_t e;
  29. mpz_init_set_ui(e, 1);
  30. mpz_mul_2exp(e, e, 64);
  31. mpz_powm(rop->c1e64, rop->c1, e, p);
  32. mpz_powm(rop->c1e128, rop->c1e64, e, p);
  33. mpz_clear(e);
  34. mpz_set(rop->c2, k->pk);
  35. mpz_powm(rop->c2, rop->c2, x, p);
  36. mpz_set_ui(x, 2);
  37. mpz_powm(x, x, m, p);
  38. mpz_mul_modp(rop->c2, rop->c2, x);
  39. mpz_clear(x);
  40. /* fixed bases */
  41. fb_set(rop->fb_c1, rop->c1);
  42. fb_set(rop->fb_c1e64, rop->c1e64);
  43. fb_set(rop->fb_c1e128, rop->c1e128);
  44. fb_set_small(rop->fb_c2, rop->c2);
  45. }
  46. void elgamal_decrypt(mpz_t rop, const elgamal_key_t k, const elgamal_cipher_t c)
  47. {
  48. mpz_powm(rop, c->c1, k->sk, p);
  49. mpz_mul(rop, rop, c->c2);
  50. mpz_mod(rop, rop, p);
  51. }
  52. void elgamal_cipher_init(elgamal_cipher_t c)
  53. {
  54. mpz_inits(c->c1, c->c2, c->c1e64, c->c1e128, NULL); \
  55. c->fb_c1 = fb_init();
  56. c->fb_c1e64 = fb_init();
  57. c->fb_c1e128 = fb_init();
  58. c->fb_c2 = fb_init();
  59. }
  60. void elgamal_cipher_clear(elgamal_cipher_t c)
  61. {
  62. mpz_clears(c->c1, c->c2, c->c1e64, c->c1e128, NULL); \
  63. fb_clear(c->fb_c1);
  64. fb_clear(c->fb_c1e64);
  65. fb_clear(c->fb_c1e128);
  66. fb_clear(c->fb_c2);
  67. }
  68. void elgamal_cipher_set(elgamal_cipher_t rop, const elgamal_cipher_t op1)
  69. {
  70. mpz_set(rop->c1, op1->c1);
  71. mpz_set(rop->c2, op1->c2);
  72. mpz_set(rop->c1e64, op1->c1e64);
  73. mpz_set(rop->c1e128, op1->c1e128);
  74. /* fixed bases */
  75. fb_copy(rop->fb_c1, op1->fb_c1);
  76. fb_copy(rop->fb_c1e64, op1->fb_c1e64);
  77. fb_copy(rop->fb_c1e128, op1->fb_c1e128);
  78. fb_copy(rop->fb_c2, op1->fb_c2);
  79. }