3 #define WINDOWSIZE 4 /* Should be 1,2, or 4 */
4 #define WINDOWMASK ((1<<WINDOWSIZE)-1)
6 static void reduce_add_sub(fe25519
*r
)
11 for(rep
=0;rep
<4;rep
++)
26 static void reduce_mul(fe25519
*r
)
31 for(rep
=0;rep
<2;rep
++)
46 /* reduction modulo 2^255-19 */
47 static void freeze(fe25519
*r
)
50 unsigned int m
= (r
->v
[31] == 127);
52 m
*= (r
->v
[i
] == 255);
53 m
*= (r
->v
[0] >= 237);
61 /*freeze input before calling isone*/
62 static int isone(const fe25519
*x
)
65 int r
= (x
->v
[0] == 1);
71 /*freeze input before calling iszero*/
72 static int iszero(const fe25519
*x
)
75 int r
= (x
->v
[0] == 0);
82 static int issquare(const fe25519
*x
)
84 unsigned char e
[32] = {0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f}; /* (p-1)/2 */
89 return isone(&t
) || iszero(&t
);
92 void fe25519_unpack(fe25519
*r
, const unsigned char x
[32])
95 for(i
=0;i
<32;i
++) r
->v
[i
] = x
[i
];
99 /* Assumes input x being reduced mod 2^255 */
100 void fe25519_pack(unsigned char r
[32], const fe25519
*x
)
106 /* freeze byte array */
107 unsigned int m
= (r
[31] == 127); /* XXX: some compilers might use branches; fix */
117 void fe25519_cmov(fe25519
*r
, const fe25519
*x
, unsigned char b
)
119 unsigned char nb
= 1-b
;
121 for(i
=0;i
<32;i
++) r
->v
[i
] = nb
* r
->v
[i
] + b
* x
->v
[i
];
124 unsigned char fe25519_getparity(const fe25519
*x
)
128 for(i
=0;i
<32;i
++) t
.v
[i
] = x
->v
[i
];
133 void fe25519_setone(fe25519
*r
)
137 for(i
=1;i
<32;i
++) r
->v
[i
]=0;
140 void fe25519_setzero(fe25519
*r
)
143 for(i
=0;i
<32;i
++) r
->v
[i
]=0;
146 void fe25519_neg(fe25519
*r
, const fe25519
*x
)
150 for(i
=0;i
<32;i
++) t
.v
[i
]=x
->v
[i
];
152 fe25519_sub(r
, r
, &t
);
155 void fe25519_add(fe25519
*r
, const fe25519
*x
, const fe25519
*y
)
158 for(i
=0;i
<32;i
++) r
->v
[i
] = x
->v
[i
] + y
->v
[i
];
162 void fe25519_sub(fe25519
*r
, const fe25519
*x
, const fe25519
*y
)
166 t
[0] = x
->v
[0] + 0x1da;
167 t
[31] = x
->v
[31] + 0xfe;
168 for(i
=1;i
<31;i
++) t
[i
] = x
->v
[i
] + 0x1fe;
169 for(i
=0;i
<32;i
++) r
->v
[i
] = t
[i
] - y
->v
[i
];
173 void fe25519_mul(fe25519
*r
, const fe25519
*x
, const fe25519
*y
)
177 for(i
=0;i
<63;i
++)t
[i
] = 0;
181 t
[i
+j
] += x
->v
[i
] * y
->v
[j
];
184 r
->v
[i
-32] = t
[i
-32] + 38*t
[i
];
185 r
->v
[31] = t
[31]; /* result now in r[0]...r[31] */
190 void fe25519_square(fe25519
*r
, const fe25519
*x
)
192 fe25519_mul(r
, x
, x
);
195 /*XXX: Make constant time! */
196 void fe25519_pow(fe25519
*r
, const fe25519
*x
, const unsigned char *e
)
207 fe25519_square(&g,&g);
209 fe25519_mul(&g,&g,x);
212 for(i=0;i<32;i++) r->v[i] = g.v[i];
217 fe25519 pre
[(1 << WINDOWSIZE
)];
224 for(i
=2;i
<(1<<WINDOWSIZE
);i
+=2)
226 fe25519_square(pre
+i
, pre
+i
/2);
227 fe25519_mul(pre
+i
+1, pre
+i
, pre
+1);
230 // Fixed-window scalar multiplication
233 for(j
=8-WINDOWSIZE
;j
>=0;j
-=WINDOWSIZE
)
235 for(k
=0;k
<WINDOWSIZE
;k
++)
236 fe25519_square(&g
, &g
);
237 // Cache-timing resistant loading of precomputed value:
238 w
= (e
[i
-1]>>j
) & WINDOWMASK
;
240 for(k
=1;k
<(1<<WINDOWSIZE
);k
++)
241 fe25519_cmov(&t
, &pre
[k
], k
==w
);
242 fe25519_mul(&g
, &g
, &t
);
248 /* Return 0 on success, 1 otherwise */
249 int fe25519_sqrt_vartime(fe25519
*r
, const fe25519
*x
, unsigned char parity
)
251 /* See HAC, Alg. 3.37 */
252 if (!issquare(x
)) return -1;
253 unsigned char e
[32] = {0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f}; /* (p-1)/4 */
254 unsigned char e2
[32] = {0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f}; /* (p+3)/8 */
255 unsigned char e3
[32] = {0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f}; /* (p-5)/8 */
267 fe25519_pow(&d
,&d
,e3
);
273 if((r
->v
[0] & 1) != (parity
& 1))
280 void fe25519_invert(fe25519
*r
, const fe25519
*x
)
294 /* 2 */ fe25519_square(&z2
,x
);
295 /* 4 */ fe25519_square(&t1
,&z2
);
296 /* 8 */ fe25519_square(&t0
,&t1
);
297 /* 9 */ fe25519_mul(&z9
,&t0
,x
);
298 /* 11 */ fe25519_mul(&z11
,&z9
,&z2
);
299 /* 22 */ fe25519_square(&t0
,&z11
);
300 /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0
,&t0
,&z9
);
302 /* 2^6 - 2^1 */ fe25519_square(&t0
,&z2_5_0
);
303 /* 2^7 - 2^2 */ fe25519_square(&t1
,&t0
);
304 /* 2^8 - 2^3 */ fe25519_square(&t0
,&t1
);
305 /* 2^9 - 2^4 */ fe25519_square(&t1
,&t0
);
306 /* 2^10 - 2^5 */ fe25519_square(&t0
,&t1
);
307 /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0
,&t0
,&z2_5_0
);
309 /* 2^11 - 2^1 */ fe25519_square(&t0
,&z2_10_0
);
310 /* 2^12 - 2^2 */ fe25519_square(&t1
,&t0
);
311 /* 2^20 - 2^10 */ for (i
= 2;i
< 10;i
+= 2) { fe25519_square(&t0
,&t1
); fe25519_square(&t1
,&t0
); }
312 /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0
,&t1
,&z2_10_0
);
314 /* 2^21 - 2^1 */ fe25519_square(&t0
,&z2_20_0
);
315 /* 2^22 - 2^2 */ fe25519_square(&t1
,&t0
);
316 /* 2^40 - 2^20 */ for (i
= 2;i
< 20;i
+= 2) { fe25519_square(&t0
,&t1
); fe25519_square(&t1
,&t0
); }
317 /* 2^40 - 2^0 */ fe25519_mul(&t0
,&t1
,&z2_20_0
);
319 /* 2^41 - 2^1 */ fe25519_square(&t1
,&t0
);
320 /* 2^42 - 2^2 */ fe25519_square(&t0
,&t1
);
321 /* 2^50 - 2^10 */ for (i
= 2;i
< 10;i
+= 2) { fe25519_square(&t1
,&t0
); fe25519_square(&t0
,&t1
); }
322 /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0
,&t0
,&z2_10_0
);
324 /* 2^51 - 2^1 */ fe25519_square(&t0
,&z2_50_0
);
325 /* 2^52 - 2^2 */ fe25519_square(&t1
,&t0
);
326 /* 2^100 - 2^50 */ for (i
= 2;i
< 50;i
+= 2) { fe25519_square(&t0
,&t1
); fe25519_square(&t1
,&t0
); }
327 /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0
,&t1
,&z2_50_0
);
329 /* 2^101 - 2^1 */ fe25519_square(&t1
,&z2_100_0
);
330 /* 2^102 - 2^2 */ fe25519_square(&t0
,&t1
);
331 /* 2^200 - 2^100 */ for (i
= 2;i
< 100;i
+= 2) { fe25519_square(&t1
,&t0
); fe25519_square(&t0
,&t1
); }
332 /* 2^200 - 2^0 */ fe25519_mul(&t1
,&t0
,&z2_100_0
);
334 /* 2^201 - 2^1 */ fe25519_square(&t0
,&t1
);
335 /* 2^202 - 2^2 */ fe25519_square(&t1
,&t0
);
336 /* 2^250 - 2^50 */ for (i
= 2;i
< 50;i
+= 2) { fe25519_square(&t0
,&t1
); fe25519_square(&t1
,&t0
); }
337 /* 2^250 - 2^0 */ fe25519_mul(&t0
,&t1
,&z2_50_0
);
339 /* 2^251 - 2^1 */ fe25519_square(&t1
,&t0
);
340 /* 2^252 - 2^2 */ fe25519_square(&t0
,&t1
);
341 /* 2^253 - 2^3 */ fe25519_square(&t1
,&t0
);
342 /* 2^254 - 2^4 */ fe25519_square(&t0
,&t1
);
343 /* 2^255 - 2^5 */ fe25519_square(&t1
,&t0
);
344 /* 2^255 - 21 */ fe25519_mul(r
,&t1
,&z11
);