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