curve25519-donna-scalarmult-base.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include "ed25519-donna.h"
  2. #include "ed25519.h"
  3. /* Calculates nQ where Q is the x-coordinate of a point on the curve
  4. *
  5. * mypublic: the packed little endian x coordinate of the resulting curve point
  6. * n: a little endian, 32-byte number
  7. * basepoint: a packed little endian point of the curve
  8. */
  9. void curve25519_scalarmult_donna(curve25519_key mypublic, const curve25519_key n, const curve25519_key basepoint) {
  10. bignum25519 nqpqx = {1}, nqpqz = {0}, nqz = {1}, nqx = {0};
  11. bignum25519 q = {0}, qx = {0}, qpqx = {0}, qqx = {0}, zzz = {0}, zmone = {0};
  12. size_t bit = 0, lastbit = 0;
  13. int32_t i = 0;
  14. curve25519_expand(q, basepoint);
  15. curve25519_copy(nqx, q);
  16. /* bit 255 is always 0, and bit 254 is always 1, so skip bit 255 and
  17. start pre-swapped on bit 254 */
  18. lastbit = 1;
  19. /* we are doing bits 254..3 in the loop, but are swapping in bits 253..2 */
  20. for (i = 253; i >= 2; i--) {
  21. curve25519_add(qx, nqx, nqz);
  22. curve25519_sub(nqz, nqx, nqz);
  23. curve25519_add(qpqx, nqpqx, nqpqz);
  24. curve25519_sub(nqpqz, nqpqx, nqpqz);
  25. curve25519_mul(nqpqx, qpqx, nqz);
  26. curve25519_mul(nqpqz, qx, nqpqz);
  27. curve25519_add(qqx, nqpqx, nqpqz);
  28. curve25519_sub(nqpqz, nqpqx, nqpqz);
  29. curve25519_square(nqpqz, nqpqz);
  30. curve25519_square(nqpqx, qqx);
  31. curve25519_mul(nqpqz, nqpqz, q);
  32. curve25519_square(qx, qx);
  33. curve25519_square(nqz, nqz);
  34. curve25519_mul(nqx, qx, nqz);
  35. curve25519_sub(nqz, qx, nqz);
  36. curve25519_scalar_product(zzz, nqz, 121665);
  37. curve25519_add(zzz, zzz, qx);
  38. curve25519_mul(nqz, nqz, zzz);
  39. bit = (n[i/8] >> (i & 7)) & 1;
  40. curve25519_swap_conditional(nqx, nqpqx, bit ^ lastbit);
  41. curve25519_swap_conditional(nqz, nqpqz, bit ^ lastbit);
  42. lastbit = bit;
  43. }
  44. /* the final 3 bits are always zero, so we only need to double */
  45. for (i = 0; i < 3; i++) {
  46. curve25519_add(qx, nqx, nqz);
  47. curve25519_sub(nqz, nqx, nqz);
  48. curve25519_square(qx, qx);
  49. curve25519_square(nqz, nqz);
  50. curve25519_mul(nqx, qx, nqz);
  51. curve25519_sub(nqz, qx, nqz);
  52. curve25519_scalar_product(zzz, nqz, 121665);
  53. curve25519_add(zzz, zzz, qx);
  54. curve25519_mul(nqz, nqz, zzz);
  55. }
  56. curve25519_recip(zmone, nqz);
  57. curve25519_mul(nqz, nqx, zmone);
  58. curve25519_contract(mypublic, nqz);
  59. }