key_exchange.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "ed25519.h"
  2. #include "fe.h"
  3. void ed25519_key_exchange(unsigned char *shared_secret, const unsigned char *public_key, const unsigned char *private_key) {
  4. unsigned char e[32];
  5. unsigned int i;
  6. fe x1;
  7. fe x2;
  8. fe z2;
  9. fe x3;
  10. fe z3;
  11. fe tmp0;
  12. fe tmp1;
  13. int pos;
  14. unsigned int swap;
  15. unsigned int b;
  16. /* copy the private key and make sure it's valid */
  17. for (i = 0; i < 32; ++i) {
  18. e[i] = private_key[i];
  19. }
  20. e[0] &= 248;
  21. e[31] &= 63;
  22. e[31] |= 64;
  23. /* unpack the public key and convert edwards to montgomery */
  24. /* due to CodesInChaos: montgomeryX = (edwardsY + 1)*inverse(1 - edwardsY) mod p */
  25. fe_frombytes(x1, public_key);
  26. fe_1(tmp1);
  27. fe_add(tmp0, x1, tmp1);
  28. fe_sub(tmp1, tmp1, x1);
  29. fe_invert(tmp1, tmp1);
  30. fe_mul(x1, tmp0, tmp1);
  31. fe_1(x2);
  32. fe_0(z2);
  33. fe_copy(x3, x1);
  34. fe_1(z3);
  35. swap = 0;
  36. for (pos = 254; pos >= 0; --pos) {
  37. b = e[pos / 8] >> (pos & 7);
  38. b &= 1;
  39. swap ^= b;
  40. fe_cswap(x2, x3, swap);
  41. fe_cswap(z2, z3, swap);
  42. swap = b;
  43. /* from montgomery.h */
  44. fe_sub(tmp0, x3, z3);
  45. fe_sub(tmp1, x2, z2);
  46. fe_add(x2, x2, z2);
  47. fe_add(z2, x3, z3);
  48. fe_mul(z3, tmp0, x2);
  49. fe_mul(z2, z2, tmp1);
  50. fe_sq(tmp0, tmp1);
  51. fe_sq(tmp1, x2);
  52. fe_add(x3, z3, z2);
  53. fe_sub(z2, z3, z2);
  54. fe_mul(x2, tmp1, tmp0);
  55. fe_sub(tmp1, tmp1, tmp0);
  56. fe_sq(z2, z2);
  57. fe_mul121666(z3, tmp1);
  58. fe_sq(x3, x3);
  59. fe_add(tmp0, tmp0, z3);
  60. fe_mul(z3, x1, z2);
  61. fe_mul(z2, tmp1, tmp0);
  62. }
  63. fe_cswap(x2, x3, swap);
  64. fe_cswap(z2, z3, swap);
  65. fe_invert(z2, z2);
  66. fe_mul(x2, x2, z2);
  67. fe_tobytes(shared_secret, x2);
  68. }