elgamal.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. // mpz_urandomm(rop->sk, _rstate, q);
  11. mpz_urandomb(rop->sk, _rstate, 160);
  12. mpz_powm(rop->pk, rop->pk, rop->sk, p);
  13. }
  14. void elgamal_encrypt(elgamal_cipher_t rop, const elgamal_key_t k, const mpz_t m)
  15. {
  16. mpz_t x;
  17. mpz_init(x);
  18. mpz_urandomm(x, _rstate, q);
  19. mpz_set_ui(rop->c1, 2);
  20. mpz_powm(rop->c1, rop->c1, x, p);
  21. mpz_invert(rop->c1, rop->c1, p);
  22. /* cached intermediate values */
  23. mpz_t e;
  24. mpz_init_set_ui(e, 1);
  25. mpz_mul_2exp(e, e, 64);
  26. mpz_powm(rop->c1e64, rop->c1, e, p);
  27. mpz_powm(rop->c1e128, rop->c1e64, e, p);
  28. mpz_clear(e);
  29. mpz_set(rop->c2, k->pk);
  30. mpz_powm(rop->c2, rop->c2, x, p);
  31. mpz_set_ui(x, 2);
  32. mpz_powm(x, x, m, p);
  33. mpz_mul_modp(rop->c2, rop->c2, x);
  34. mpz_clear(x);
  35. /* fixed bases */
  36. fb_set(rop->fb_c1, rop->c1);
  37. fb_set(rop->fb_c1e64, rop->c1e64);
  38. fb_set(rop->fb_c1e128, rop->c1e128);
  39. fb_set_small(rop->fb_c2, rop->c2);
  40. }
  41. void elgamal_decrypt(mpz_t rop, const elgamal_key_t k, const elgamal_cipher_t c)
  42. {
  43. mpz_powm(rop, c->c1, k->sk, p);
  44. mpz_mul(rop, rop, c->c2);
  45. mpz_mod(rop, rop, p);
  46. }
  47. void elgamal_cipher_init(elgamal_cipher_t c)
  48. {
  49. mpz_inits(c->c1, c->c2, c->c1e64, c->c1e128, NULL); \
  50. c->fb_c1 = fb_init();
  51. c->fb_c1e64 = fb_init();
  52. c->fb_c1e128 = fb_init();
  53. c->fb_c2 = fb_init();
  54. }
  55. void elgamal_cipher_clear(elgamal_cipher_t c)
  56. {
  57. mpz_clears(c->c1, c->c2, c->c1e64, c->c1e128, NULL); \
  58. fb_clear(c->fb_c1);
  59. fb_clear(c->fb_c1e64);
  60. fb_clear(c->fb_c1e128);
  61. fb_clear(c->fb_c2);
  62. }
  63. void elgamal_cipher_set(elgamal_cipher_t rop, const elgamal_cipher_t op1)
  64. {
  65. mpz_set(rop->c1, op1->c1);
  66. mpz_set(rop->c2, op1->c2);
  67. mpz_set(rop->c1e64, op1->c1e64);
  68. mpz_set(rop->c1e128, op1->c1e128);
  69. /* fixed bases */
  70. fb_copy(rop->fb_c1, op1->fb_c1);
  71. fb_copy(rop->fb_c1e64, op1->fb_c1e64);
  72. fb_copy(rop->fb_c1e128, op1->fb_c1e128);
  73. fb_copy(rop->fb_c2, op1->fb_c2);
  74. }