4 * Copyright (c) 2013-2019
5 * Frank Denis <j at pureftpd dot org>
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include "private/common.h"
24 #include "private/quirks.h"
34 memset(&h[0], 0, 5 * sizeof h[0]);
45 memset(&h[1], 0, 4 * sizeof h[0]);
50 Can overlap h with f or g.
54 fe25519_add(fe25519 h, const fe25519 f, const fe25519 g)
56 uint64_t h0 = f[0] + g[0];
57 uint64_t h1 = f[1] + g[1];
58 uint64_t h2 = f[2] + g[2];
59 uint64_t h3 = f[3] + g[3];
60 uint64_t h4 = f[4] + g[4];
74 fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g)
76 const uint64_t mask = 0x7ffffffffffffULL;
77 uint64_t h0, h1, h2, h3, h4;
93 h0 += 19ULL * (h4 >> 51);
96 h0 = (f[0] + 0xfffffffffffdaULL) - h0;
97 h1 = (f[1] + 0xffffffffffffeULL) - h1;
98 h2 = (f[2] + 0xffffffffffffeULL) - h2;
99 h3 = (f[3] + 0xffffffffffffeULL) - h3;
100 h4 = (f[4] + 0xffffffffffffeULL) - h4;
114 fe25519_neg(fe25519 h, const fe25519 f)
119 fe25519_sub(h, zero, f);
123 Replace (f,g) with (g,g) if b == 1;
124 replace (f,g) with (f,g) if b == 0.
126 Preconditions: b in {0,1}.
130 fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b)
132 const uint64_t mask = (uint64_t) (-(int64_t) b);
140 uint64_t x0 = f0 ^ g[0];
141 uint64_t x1 = f1 ^ g[1];
142 uint64_t x2 = f2 ^ g[2];
143 uint64_t x3 = f3 ^ g[3];
144 uint64_t x4 = f4 ^ g[4];
160 Replace (f,g) with (g,f) if b == 1;
161 replace (f,g) with (f,g) if b == 0.
163 Preconditions: b in {0,1}.
167 fe25519_cswap(fe25519 f, fe25519 g, unsigned int b)
169 const uint64_t mask = (uint64_t) (-(int64_t) b);
183 uint64_t x0 = f0 ^ g0;
184 uint64_t x1 = f1 ^ g1;
185 uint64_t x2 = f2 ^ g2;
186 uint64_t x3 = f3 ^ g3;
187 uint64_t x4 = f4 ^ g4;
213 fe25519_copy(fe25519 h, const fe25519 f)
229 return 1 if f is in {1,3,5,...,q-2}
230 return 0 if f is in {0,2,4,...,q-1}
234 fe25519_isnegative(const fe25519 f)
238 fe25519_tobytes(s, f);
249 fe25519_iszero(const fe25519 f)
253 fe25519_tobytes(s, f);
255 return sodium_is_zero(s, 32);
260 Can overlap h with f or g.
264 fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g)
266 const uint64_t mask = 0x7ffffffffffffULL;
267 uint128_t r0, r1, r2, r3, r4, carry;
268 uint64_t f0, f1, f2, f3, f4;
269 uint64_t f1_19, f2_19, f3_19, f4_19;
270 uint64_t g0, g1, g2, g3, g4;
271 uint64_t r00, r01, r02, r03, r04;
290 r0 = ((uint128_t) f0 ) * ((uint128_t) g0);
291 r0 += ((uint128_t) f1_19) * ((uint128_t) g4);
292 r0 += ((uint128_t) f2_19) * ((uint128_t) g3);
293 r0 += ((uint128_t) f3_19) * ((uint128_t) g2);
294 r0 += ((uint128_t) f4_19) * ((uint128_t) g1);
296 r1 = ((uint128_t) f0 ) * ((uint128_t) g1);
297 r1 += ((uint128_t) f1 ) * ((uint128_t) g0);
298 r1 += ((uint128_t) f2_19) * ((uint128_t) g4);
299 r1 += ((uint128_t) f3_19) * ((uint128_t) g3);
300 r1 += ((uint128_t) f4_19) * ((uint128_t) g2);
302 r2 = ((uint128_t) f0 ) * ((uint128_t) g2);
303 r2 += ((uint128_t) f1 ) * ((uint128_t) g1);
304 r2 += ((uint128_t) f2 ) * ((uint128_t) g0);
305 r2 += ((uint128_t) f3_19) * ((uint128_t) g4);
306 r2 += ((uint128_t) f4_19) * ((uint128_t) g3);
308 r3 = ((uint128_t) f0 ) * ((uint128_t) g3);
309 r3 += ((uint128_t) f1 ) * ((uint128_t) g2);
310 r3 += ((uint128_t) f2 ) * ((uint128_t) g1);
311 r3 += ((uint128_t) f3 ) * ((uint128_t) g0);
312 r3 += ((uint128_t) f4_19) * ((uint128_t) g4);
314 r4 = ((uint128_t) f0 ) * ((uint128_t) g4);
315 r4 += ((uint128_t) f1 ) * ((uint128_t) g3);
316 r4 += ((uint128_t) f2 ) * ((uint128_t) g2);
317 r4 += ((uint128_t) f3 ) * ((uint128_t) g1);
318 r4 += ((uint128_t) f4 ) * ((uint128_t) g0);
320 r00 = ((uint64_t) r0) & mask;
323 r01 = ((uint64_t) r1) & mask;
326 r02 = ((uint64_t) r2) & mask;
329 r03 = ((uint64_t) r3) & mask;
332 r04 = ((uint64_t) r4) & mask;
334 r00 += 19ULL * (uint64_t) carry;
337 r01 += (uint64_t) carry;
340 r02 += (uint64_t) carry;
351 Can overlap h with f.
355 fe25519_sq(fe25519 h, const fe25519 f)
357 const uint64_t mask = 0x7ffffffffffffULL;
358 uint128_t r0, r1, r2, r3, r4, carry;
359 uint64_t f0, f1, f2, f3, f4;
360 uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19;
361 uint64_t r00, r01, r02, r03, r04;
379 r0 = ((uint128_t) f0 ) * ((uint128_t) f0);
380 r0 += ((uint128_t) f1_38) * ((uint128_t) f4);
381 r0 += ((uint128_t) f2_38) * ((uint128_t) f3);
383 r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1);
384 r1 += ((uint128_t) f2_38) * ((uint128_t) f4);
385 r1 += ((uint128_t) f3_19) * ((uint128_t) f3);
387 r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2);
388 r2 += ((uint128_t) f1 ) * ((uint128_t) f1);
389 r2 += ((uint128_t) f3_38) * ((uint128_t) f4);
391 r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3);
392 r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2);
393 r3 += ((uint128_t) f4_19) * ((uint128_t) f4);
395 r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4);
396 r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3);
397 r4 += ((uint128_t) f2 ) * ((uint128_t) f2);
399 r00 = ((uint64_t) r0) & mask;
402 r01 = ((uint64_t) r1) & mask;
405 r02 = ((uint64_t) r2) & mask;
408 r03 = ((uint64_t) r3) & mask;
411 r04 = ((uint64_t) r4) & mask;
413 r00 += 19ULL * (uint64_t) carry;
416 r01 += (uint64_t) carry;
419 r02 += (uint64_t) carry;
430 Can overlap h with f.
434 fe25519_sq2(fe25519 h, const fe25519 f)
436 const uint64_t mask = 0x7ffffffffffffULL;
437 uint128_t r0, r1, r2, r3, r4, carry;
438 uint64_t f0, f1, f2, f3, f4;
439 uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19;
440 uint64_t r00, r01, r02, r03, r04;
458 r0 = ((uint128_t) f0 ) * ((uint128_t) f0);
459 r0 += ((uint128_t) f1_38) * ((uint128_t) f4);
460 r0 += ((uint128_t) f2_38) * ((uint128_t) f3);
462 r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1);
463 r1 += ((uint128_t) f2_38) * ((uint128_t) f4);
464 r1 += ((uint128_t) f3_19) * ((uint128_t) f3);
466 r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2);
467 r2 += ((uint128_t) f1 ) * ((uint128_t) f1);
468 r2 += ((uint128_t) f3_38) * ((uint128_t) f4);
470 r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3);
471 r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2);
472 r3 += ((uint128_t) f4_19) * ((uint128_t) f4);
474 r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4);
475 r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3);
476 r4 += ((uint128_t) f2 ) * ((uint128_t) f2);
484 r00 = ((uint64_t) r0) & mask;
487 r01 = ((uint64_t) r1) & mask;
490 r02 = ((uint64_t) r2) & mask;
493 r03 = ((uint64_t) r3) & mask;
496 r04 = ((uint64_t) r4) & mask;
498 r00 += 19ULL * (uint64_t) carry;
501 r01 += (uint64_t) carry;
504 r02 += (uint64_t) carry;
514 fe25519_scalar_product(fe25519 h, const fe25519 f, uint32_t n)
516 const uint64_t mask = 0x7ffffffffffffULL;
518 uint128_t sn = (uint128_t) n;
519 uint64_t h0, h1, h2, h3, h4;
522 h0 = ((uint64_t) a) & mask;
523 a = f[1] * sn + ((uint64_t) (a >> 51));
524 h1 = ((uint64_t) a) & mask;
525 a = f[2] * sn + ((uint64_t) (a >> 51));
526 h2 = ((uint64_t) a) & mask;
527 a = f[3] * sn + ((uint64_t) (a >> 51));
528 h3 = ((uint64_t) a) & mask;
529 a = f[4] * sn + ((uint64_t) (a >> 51));
530 h4 = ((uint64_t) a) & mask;
532 h0 += (a >> 51) * 19ULL;