ge25519_double_scalarmult.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 = {{0xEBD69B9426B2F146, 0x00E0149A8283B156, 0x198E80F2EEF3D130, 0xA406D9DC56DFFCE7}};
  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_p3((ge25519_p3 *)&pre1[i+1], &t);
  42. /* Convert pre1[i+1] to projective Niels representation */
  43. d = pre1[i+1].ysubx;
  44. fe25519_sub(&pre1[i+1].ysubx, &pre1[i+1].xaddy, &pre1[i+1].ysubx);
  45. fe25519_add(&pre1[i+1].xaddy, &pre1[i+1].xaddy, &d);
  46. fe25519_mul(&pre1[i+1].t2d, &pre1[i+1].t2d, &ec2d);
  47. }
  48. setneutral(r);
  49. for (i = 255;i >= 0;--i) {
  50. if (slide1[i] || slide2[i]) goto firstbit;
  51. }
  52. for(;i>=0;i--)
  53. {
  54. firstbit:
  55. ge25519_dbl_p1p1(&t, (ge25519_p2 *)r);
  56. if(slide1[i]>0)
  57. {
  58. ge25519_p1p1_to_p3(r, &t);
  59. ge25519_pnielsadd_p1p1(&t, r, &pre1[slide1[i]/2]);
  60. }
  61. else if(slide1[i]<0)
  62. {
  63. ge25519_p1p1_to_p3(r, &t);
  64. neg = pre1[-slide1[i]/2];
  65. d = neg.ysubx;
  66. neg.ysubx = neg.xaddy;
  67. neg.xaddy = d;
  68. fe25519_neg(&neg.t2d, &neg.t2d);
  69. ge25519_pnielsadd_p1p1(&t, r, &neg);
  70. }
  71. if(slide2[i]>0)
  72. {
  73. ge25519_p1p1_to_p3(r, &t);
  74. ge25519_nielsadd_p1p1(&t, r, &pre2[slide2[i]/2]);
  75. }
  76. else if(slide2[i]<0)
  77. {
  78. ge25519_p1p1_to_p3(r, &t);
  79. nneg = pre2[-slide2[i]/2];
  80. d = nneg.ysubx;
  81. nneg.ysubx = nneg.xaddy;
  82. nneg.xaddy = d;
  83. fe25519_neg(&nneg.t2d, &nneg.t2d);
  84. ge25519_nielsadd_p1p1(&t, r, &nneg);
  85. }
  86. ge25519_p1p1_to_p2((ge25519_p2 *)r, &t);
  87. }
  88. }