ge25519_double_scalarmult.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include "fe25519.h"
  2. #include "sc25519.h"
  3. #include "ge25519.h"
  4. #define S1_SWINDOWSIZE 5
  5. #define PRE1_SIZE (1<<(S1_SWINDOWSIZE-2))
  6. #define S2_SWINDOWSIZE 7
  7. #define PRE2_SIZE (1<<(S2_SWINDOWSIZE-2))
  8. static const ge25519_niels pre2[PRE2_SIZE] = {
  9. #include "ge25519_base_slide_multiples.data"
  10. };
  11. static const fe25519 ec2d = {{1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903}};
  12. static void setneutral(ge25519 *r)
  13. {
  14. fe25519_setint(&r->x,0);
  15. fe25519_setint(&r->y,1);
  16. fe25519_setint(&r->z,1);
  17. fe25519_setint(&r->t,0);
  18. }
  19. /* computes [s1]p1 + [s2]p2 */
  20. void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const sc25519 *s2)
  21. {
  22. signed char slide1[256], slide2[256];
  23. ge25519_pniels pre1[PRE1_SIZE], neg;
  24. ge25519_p3 d1;
  25. ge25519_p1p1 t;
  26. ge25519_niels nneg;
  27. fe25519 d;
  28. int i;
  29. sc25519_slide(slide1, s1, S1_SWINDOWSIZE);
  30. sc25519_slide(slide2, s2, S2_SWINDOWSIZE);
  31. /* precomputation */
  32. pre1[0] = *(ge25519_pniels *)p1;
  33. ge25519_dbl_p1p1(&t,(ge25519_p2 *)pre1); ge25519_p1p1_to_p3(&d1, &t);
  34. /* Convert pre[0] to projective Niels representation */
  35. d = pre1[0].ysubx;
  36. fe25519_sub(&pre1[0].ysubx, &pre1[0].xaddy, &pre1[0].ysubx);
  37. fe25519_add(&pre1[0].xaddy, &pre1[0].xaddy, &d);
  38. fe25519_mul(&pre1[0].t2d, &pre1[0].t2d, &ec2d);
  39. for(i=0;i<PRE1_SIZE-1;i++)
  40. {
  41. ge25519_pnielsadd_p1p1(&t, &d1, &pre1[i]); ge25519_p1p1_to_pniels(&pre1[i+1], &t);
  42. }
  43. setneutral(r);
  44. for (i = 255;i >= 0;--i) {
  45. if (slide1[i] || slide2[i]) goto firstbit;
  46. }
  47. for(;i>=0;i--)
  48. {
  49. firstbit:
  50. ge25519_dbl_p1p1(&t, (ge25519_p2 *)r);
  51. if(slide1[i]>0)
  52. {
  53. ge25519_p1p1_to_p3(r, &t);
  54. ge25519_pnielsadd_p1p1(&t, r, &pre1[slide1[i]/2]);
  55. }
  56. else if(slide1[i]<0)
  57. {
  58. ge25519_p1p1_to_p3(r, &t);
  59. neg = pre1[-slide1[i]/2];
  60. d = neg.ysubx;
  61. neg.ysubx = neg.xaddy;
  62. neg.xaddy = d;
  63. fe25519_neg(&neg.t2d, &neg.t2d);
  64. ge25519_pnielsadd_p1p1(&t, r, &neg);
  65. }
  66. if(slide2[i]>0)
  67. {
  68. ge25519_p1p1_to_p3(r, &t);
  69. ge25519_nielsadd_p1p1(&t, r, &pre2[slide2[i]/2]);
  70. }
  71. else if(slide2[i]<0)
  72. {
  73. ge25519_p1p1_to_p3(r, &t);
  74. nneg = pre2[-slide2[i]/2];
  75. d = nneg.ysubx;
  76. nneg.ysubx = nneg.xaddy;
  77. nneg.xaddy = d;
  78. fe25519_neg(&nneg.t2d, &nneg.t2d);
  79. ge25519_nielsadd_p1p1(&t, r, &nneg);
  80. }
  81. ge25519_p1p1_to_p2((ge25519_p2 *)r, &t);
  82. }
  83. }