mont25519.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include "crypto_scalarmult.h"
  2. #include "fe25519.h"
  3. #define work_cswap crypto_scalarmult_curve25519_amd64_64_work_cswap
  4. #define ladderstep crypto_scalarmult_curve25519_amd64_64_ladderstep
  5. extern void work_cswap(fe25519 *, unsigned long long);
  6. extern void ladderstep(fe25519 *work);
  7. static void mladder(fe25519 *xr, fe25519 *zr, const unsigned char s[32])
  8. {
  9. fe25519 work[5];
  10. unsigned char bit, prevbit=0;
  11. unsigned long long swap;
  12. int j;
  13. int i;
  14. work[0] = *xr;
  15. fe25519_setint(work+1,1);
  16. fe25519_setint(work+2,0);
  17. work[3] = *xr;
  18. fe25519_setint(work+4,1);
  19. j = 6;
  20. for(i=31;i>=0;i--)
  21. {
  22. while(j >= 0)
  23. {
  24. bit = 1&(s[i]>>j);
  25. swap = bit ^ prevbit;
  26. prevbit = bit;
  27. work_cswap(work+1,swap);
  28. ladderstep(work);
  29. j -= 1;
  30. }
  31. j = 7;
  32. }
  33. *xr = work[1];
  34. *zr = work[2];
  35. }
  36. int crypto_scalarmult(unsigned char *r,
  37. const unsigned char *s,
  38. const unsigned char *p)
  39. {
  40. unsigned char e[32];
  41. int i;
  42. for(i=0;i<32;i++) e[i] = s[i];
  43. e[0] &= 248;
  44. e[31] &= 127;
  45. e[31] |= 64;
  46. fe25519 t;
  47. fe25519 z;
  48. fe25519_unpack(&t, p);
  49. mladder(&t, &z, e);
  50. fe25519_invert(&z, &z);
  51. fe25519_mul(&t, &t, &z);
  52. fe25519_pack(r, &t);
  53. return 0;
  54. }
  55. static const unsigned char base[32] = {9};
  56. int crypto_scalarmult_base(unsigned char *q, const unsigned char *n)
  57. {
  58. return crypto_scalarmult(q,n,base);
  59. }