File Coverage

src/ec/ec_c25519_m15.c
Criterion Covered Total %
statement 0 829 0.0
branch 0 44 0.0
condition n/a
subroutine n/a
pod n/a
total 0 873 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2017 Thomas Pornin
3             *
4             * Permission is hereby granted, free of charge, to any person obtaining
5             * a copy of this software and associated documentation files (the
6             * "Software"), to deal in the Software without restriction, including
7             * without limitation the rights to use, copy, modify, merge, publish,
8             * distribute, sublicense, and/or sell copies of the Software, and to
9             * permit persons to whom the Software is furnished to do so, subject to
10             * the following conditions:
11             *
12             * The above copyright notice and this permission notice shall be
13             * included in all copies or substantial portions of the Software.
14             *
15             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19             * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20             * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21             * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22             * SOFTWARE.
23             */
24              
25             #include "inner.h"
26              
27             /* obsolete
28             #include
29             #include
30             static void
31             print_int(const char *name, const uint32_t *x)
32             {
33             size_t u;
34             unsigned char tmp[36];
35              
36             printf("%s = ", name);
37             for (u = 0; u < 20; u ++) {
38             if (x[u] > 0x1FFF) {
39             printf("INVALID:");
40             for (u = 0; u < 20; u ++) {
41             printf(" %04X", x[u]);
42             }
43             printf("\n");
44             return;
45             }
46             }
47             memset(tmp, 0, sizeof tmp);
48             for (u = 0; u < 20; u ++) {
49             uint32_t w;
50             int j, k;
51              
52             w = x[u];
53             j = 13 * (int)u;
54             k = j & 7;
55             if (k != 0) {
56             w <<= k;
57             j -= k;
58             }
59             k = j >> 3;
60             tmp[35 - k] |= (unsigned char)w;
61             tmp[34 - k] |= (unsigned char)(w >> 8);
62             tmp[33 - k] |= (unsigned char)(w >> 16);
63             tmp[32 - k] |= (unsigned char)(w >> 24);
64             }
65             for (u = 4; u < 36; u ++) {
66             printf("%02X", tmp[u]);
67             }
68             printf("\n");
69             }
70             */
71              
72             /*
73             * If BR_NO_ARITH_SHIFT is undefined, or defined to 0, then we _assume_
74             * that right-shifting a signed negative integer copies the sign bit
75             * (arithmetic right-shift). This is "implementation-defined behaviour",
76             * i.e. it is not undefined, but it may differ between compilers. Each
77             * compiler is supposed to document its behaviour in that respect. GCC
78             * explicitly defines that an arithmetic right shift is used. We expect
79             * all other compilers to do the same, because underlying CPU offer an
80             * arithmetic right shift opcode that could not be used otherwise.
81             */
82             #if BR_NO_ARITH_SHIFT
83             #define ARSH(x, n) (((uint32_t)(x) >> (n)) \
84             | ((-((uint32_t)(x) >> 31)) << (32 - (n))))
85             #else
86             #define ARSH(x, n) ((*(int32_t *)&(x)) >> (n))
87             #endif
88              
89             /*
90             * Convert an integer from unsigned little-endian encoding to a sequence of
91             * 13-bit words in little-endian order. The final "partial" word is
92             * returned.
93             */
94             static uint32_t
95 0           le8_to_le13(uint32_t *dst, const unsigned char *src, size_t len)
96             {
97             uint32_t acc;
98             int acc_len;
99              
100 0           acc = 0;
101 0           acc_len = 0;
102 0 0         while (len -- > 0) {
103 0           acc |= (uint32_t)(*src ++) << acc_len;
104 0           acc_len += 8;
105 0 0         if (acc_len >= 13) {
106 0           *dst ++ = acc & 0x1FFF;
107 0           acc >>= 13;
108 0           acc_len -= 13;
109             }
110             }
111 0           return acc;
112             }
113              
114             /*
115             * Convert an integer (13-bit words, little-endian) to unsigned
116             * little-endian encoding. The total encoding length is provided; all
117             * the destination bytes will be filled.
118             */
119             static void
120 0           le13_to_le8(unsigned char *dst, size_t len, const uint32_t *src)
121             {
122             uint32_t acc;
123             int acc_len;
124              
125 0           acc = 0;
126 0           acc_len = 0;
127 0 0         while (len -- > 0) {
128 0 0         if (acc_len < 8) {
129 0           acc |= (*src ++) << acc_len;
130 0           acc_len += 13;
131             }
132 0           *dst ++ = (unsigned char)acc;
133 0           acc >>= 8;
134 0           acc_len -= 8;
135             }
136 0           }
137              
138             /*
139             * Normalise an array of words to a strict 13 bits per word. Returned
140             * value is the resulting carry. The source (w) and destination (d)
141             * arrays may be identical, but shall not overlap partially.
142             */
143             static inline uint32_t
144 0           norm13(uint32_t *d, const uint32_t *w, size_t len)
145             {
146             size_t u;
147             uint32_t cc;
148              
149 0           cc = 0;
150 0 0         for (u = 0; u < len; u ++) {
151             int32_t z;
152              
153 0           z = w[u] + cc;
154 0           d[u] = z & 0x1FFF;
155 0           cc = ARSH(z, 13);
156             }
157 0           return cc;
158             }
159              
160             /*
161             * mul20() multiplies two 260-bit integers together. Each word must fit
162             * on 13 bits; source operands use 20 words, destination operand
163             * receives 40 words. All overlaps allowed.
164             *
165             * square20() computes the square of a 260-bit integer. Each word must
166             * fit on 13 bits; source operand uses 20 words, destination operand
167             * receives 40 words. All overlaps allowed.
168             */
169              
170             #if BR_SLOW_MUL15
171              
172             static void
173             mul20(uint32_t *d, const uint32_t *a, const uint32_t *b)
174             {
175             /*
176             * Two-level Karatsuba: turns a 20x20 multiplication into
177             * nine 5x5 multiplications. We use 13-bit words but do not
178             * propagate carries immediately, so words may expand:
179             *
180             * - First Karatsuba decomposition turns the 20x20 mul on
181             * 13-bit words into three 10x10 muls, two on 13-bit words
182             * and one on 14-bit words.
183             *
184             * - Second Karatsuba decomposition further splits these into:
185             *
186             * * four 5x5 muls on 13-bit words
187             * * four 5x5 muls on 14-bit words
188             * * one 5x5 mul on 15-bit words
189             *
190             * Highest word value is 8191, 16382 or 32764, for 13-bit, 14-bit
191             * or 15-bit words, respectively.
192             */
193             uint32_t u[45], v[45], w[90];
194             uint32_t cc;
195             int i;
196              
197             #define ZADD(dw, d_off, s1w, s1_off, s2w, s2_off) do { \
198             (dw)[5 * (d_off) + 0] = (s1w)[5 * (s1_off) + 0] \
199             + (s2w)[5 * (s2_off) + 0]; \
200             (dw)[5 * (d_off) + 1] = (s1w)[5 * (s1_off) + 1] \
201             + (s2w)[5 * (s2_off) + 1]; \
202             (dw)[5 * (d_off) + 2] = (s1w)[5 * (s1_off) + 2] \
203             + (s2w)[5 * (s2_off) + 2]; \
204             (dw)[5 * (d_off) + 3] = (s1w)[5 * (s1_off) + 3] \
205             + (s2w)[5 * (s2_off) + 3]; \
206             (dw)[5 * (d_off) + 4] = (s1w)[5 * (s1_off) + 4] \
207             + (s2w)[5 * (s2_off) + 4]; \
208             } while (0)
209              
210             #define ZADDT(dw, d_off, sw, s_off) do { \
211             (dw)[5 * (d_off) + 0] += (sw)[5 * (s_off) + 0]; \
212             (dw)[5 * (d_off) + 1] += (sw)[5 * (s_off) + 1]; \
213             (dw)[5 * (d_off) + 2] += (sw)[5 * (s_off) + 2]; \
214             (dw)[5 * (d_off) + 3] += (sw)[5 * (s_off) + 3]; \
215             (dw)[5 * (d_off) + 4] += (sw)[5 * (s_off) + 4]; \
216             } while (0)
217              
218             #define ZSUB2F(dw, d_off, s1w, s1_off, s2w, s2_off) do { \
219             (dw)[5 * (d_off) + 0] -= (s1w)[5 * (s1_off) + 0] \
220             + (s2w)[5 * (s2_off) + 0]; \
221             (dw)[5 * (d_off) + 1] -= (s1w)[5 * (s1_off) + 1] \
222             + (s2w)[5 * (s2_off) + 1]; \
223             (dw)[5 * (d_off) + 2] -= (s1w)[5 * (s1_off) + 2] \
224             + (s2w)[5 * (s2_off) + 2]; \
225             (dw)[5 * (d_off) + 3] -= (s1w)[5 * (s1_off) + 3] \
226             + (s2w)[5 * (s2_off) + 3]; \
227             (dw)[5 * (d_off) + 4] -= (s1w)[5 * (s1_off) + 4] \
228             + (s2w)[5 * (s2_off) + 4]; \
229             } while (0)
230              
231             #define CPR1(w, cprcc) do { \
232             uint32_t cprz = (w) + cprcc; \
233             (w) = cprz & 0x1FFF; \
234             cprcc = cprz >> 13; \
235             } while (0)
236              
237             #define CPR(dw, d_off) do { \
238             uint32_t cprcc; \
239             cprcc = 0; \
240             CPR1((dw)[(d_off) + 0], cprcc); \
241             CPR1((dw)[(d_off) + 1], cprcc); \
242             CPR1((dw)[(d_off) + 2], cprcc); \
243             CPR1((dw)[(d_off) + 3], cprcc); \
244             CPR1((dw)[(d_off) + 4], cprcc); \
245             CPR1((dw)[(d_off) + 5], cprcc); \
246             CPR1((dw)[(d_off) + 6], cprcc); \
247             CPR1((dw)[(d_off) + 7], cprcc); \
248             CPR1((dw)[(d_off) + 8], cprcc); \
249             (dw)[(d_off) + 9] = cprcc; \
250             } while (0)
251              
252             memcpy(u, a, 20 * sizeof *a);
253             ZADD(u, 4, a, 0, a, 1);
254             ZADD(u, 5, a, 2, a, 3);
255             ZADD(u, 6, a, 0, a, 2);
256             ZADD(u, 7, a, 1, a, 3);
257             ZADD(u, 8, u, 6, u, 7);
258              
259             memcpy(v, b, 20 * sizeof *b);
260             ZADD(v, 4, b, 0, b, 1);
261             ZADD(v, 5, b, 2, b, 3);
262             ZADD(v, 6, b, 0, b, 2);
263             ZADD(v, 7, b, 1, b, 3);
264             ZADD(v, 8, v, 6, v, 7);
265              
266             /*
267             * Do the eight first 8x8 muls. Source words are at most 16382
268             * each, so we can add product results together "as is" in 32-bit
269             * words.
270             */
271             for (i = 0; i < 40; i += 5) {
272             w[(i << 1) + 0] = MUL15(u[i + 0], v[i + 0]);
273             w[(i << 1) + 1] = MUL15(u[i + 0], v[i + 1])
274             + MUL15(u[i + 1], v[i + 0]);
275             w[(i << 1) + 2] = MUL15(u[i + 0], v[i + 2])
276             + MUL15(u[i + 1], v[i + 1])
277             + MUL15(u[i + 2], v[i + 0]);
278             w[(i << 1) + 3] = MUL15(u[i + 0], v[i + 3])
279             + MUL15(u[i + 1], v[i + 2])
280             + MUL15(u[i + 2], v[i + 1])
281             + MUL15(u[i + 3], v[i + 0]);
282             w[(i << 1) + 4] = MUL15(u[i + 0], v[i + 4])
283             + MUL15(u[i + 1], v[i + 3])
284             + MUL15(u[i + 2], v[i + 2])
285             + MUL15(u[i + 3], v[i + 1])
286             + MUL15(u[i + 4], v[i + 0]);
287             w[(i << 1) + 5] = MUL15(u[i + 1], v[i + 4])
288             + MUL15(u[i + 2], v[i + 3])
289             + MUL15(u[i + 3], v[i + 2])
290             + MUL15(u[i + 4], v[i + 1]);
291             w[(i << 1) + 6] = MUL15(u[i + 2], v[i + 4])
292             + MUL15(u[i + 3], v[i + 3])
293             + MUL15(u[i + 4], v[i + 2]);
294             w[(i << 1) + 7] = MUL15(u[i + 3], v[i + 4])
295             + MUL15(u[i + 4], v[i + 3]);
296             w[(i << 1) + 8] = MUL15(u[i + 4], v[i + 4]);
297             w[(i << 1) + 9] = 0;
298             }
299              
300             /*
301             * For the 9th multiplication, source words are up to 32764,
302             * so we must do some carry propagation. If we add up to
303             * 4 products and the carry is no more than 524224, then the
304             * result fits in 32 bits, and the next carry will be no more
305             * than 524224 (because 4*(32764^2)+524224 < 8192*524225).
306             *
307             * We thus just skip one of the products in the middle word,
308             * then do a carry propagation (this reduces words to 13 bits
309             * each, except possibly the last, which may use up to 17 bits
310             * or so), then add the missing product.
311             */
312             w[80 + 0] = MUL15(u[40 + 0], v[40 + 0]);
313             w[80 + 1] = MUL15(u[40 + 0], v[40 + 1])
314             + MUL15(u[40 + 1], v[40 + 0]);
315             w[80 + 2] = MUL15(u[40 + 0], v[40 + 2])
316             + MUL15(u[40 + 1], v[40 + 1])
317             + MUL15(u[40 + 2], v[40 + 0]);
318             w[80 + 3] = MUL15(u[40 + 0], v[40 + 3])
319             + MUL15(u[40 + 1], v[40 + 2])
320             + MUL15(u[40 + 2], v[40 + 1])
321             + MUL15(u[40 + 3], v[40 + 0]);
322             w[80 + 4] = MUL15(u[40 + 0], v[40 + 4])
323             + MUL15(u[40 + 1], v[40 + 3])
324             + MUL15(u[40 + 2], v[40 + 2])
325             + MUL15(u[40 + 3], v[40 + 1]);
326             /* + MUL15(u[40 + 4], v[40 + 0]) */
327             w[80 + 5] = MUL15(u[40 + 1], v[40 + 4])
328             + MUL15(u[40 + 2], v[40 + 3])
329             + MUL15(u[40 + 3], v[40 + 2])
330             + MUL15(u[40 + 4], v[40 + 1]);
331             w[80 + 6] = MUL15(u[40 + 2], v[40 + 4])
332             + MUL15(u[40 + 3], v[40 + 3])
333             + MUL15(u[40 + 4], v[40 + 2]);
334             w[80 + 7] = MUL15(u[40 + 3], v[40 + 4])
335             + MUL15(u[40 + 4], v[40 + 3]);
336             w[80 + 8] = MUL15(u[40 + 4], v[40 + 4]);
337              
338             CPR(w, 80);
339              
340             w[80 + 4] += MUL15(u[40 + 4], v[40 + 0]);
341              
342             /*
343             * The products on 14-bit words in slots 6 and 7 yield values
344             * up to 5*(16382^2) each, and we need to subtract two such
345             * values from the higher word. We need the subtraction to fit
346             * in a _signed_ 32-bit integer, i.e. 31 bits + a sign bit.
347             * However, 10*(16382^2) does not fit. So we must perform a
348             * bit of reduction here.
349             */
350             CPR(w, 60);
351             CPR(w, 70);
352              
353             /*
354             * Recompose results.
355             */
356              
357             /* 0..1*0..1 into 0..3 */
358             ZSUB2F(w, 8, w, 0, w, 2);
359             ZSUB2F(w, 9, w, 1, w, 3);
360             ZADDT(w, 1, w, 8);
361             ZADDT(w, 2, w, 9);
362              
363             /* 2..3*2..3 into 4..7 */
364             ZSUB2F(w, 10, w, 4, w, 6);
365             ZSUB2F(w, 11, w, 5, w, 7);
366             ZADDT(w, 5, w, 10);
367             ZADDT(w, 6, w, 11);
368              
369             /* (0..1+2..3)*(0..1+2..3) into 12..15 */
370             ZSUB2F(w, 16, w, 12, w, 14);
371             ZSUB2F(w, 17, w, 13, w, 15);
372             ZADDT(w, 13, w, 16);
373             ZADDT(w, 14, w, 17);
374              
375             /* first-level recomposition */
376             ZSUB2F(w, 12, w, 0, w, 4);
377             ZSUB2F(w, 13, w, 1, w, 5);
378             ZSUB2F(w, 14, w, 2, w, 6);
379             ZSUB2F(w, 15, w, 3, w, 7);
380             ZADDT(w, 2, w, 12);
381             ZADDT(w, 3, w, 13);
382             ZADDT(w, 4, w, 14);
383             ZADDT(w, 5, w, 15);
384              
385             /*
386             * Perform carry propagation to bring all words down to 13 bits.
387             */
388             cc = norm13(d, w, 40);
389             d[39] += (cc << 13);
390              
391             #undef ZADD
392             #undef ZADDT
393             #undef ZSUB2F
394             #undef CPR1
395             #undef CPR
396             }
397              
398             static inline void
399             square20(uint32_t *d, const uint32_t *a)
400             {
401             mul20(d, a, a);
402             }
403              
404             #else
405              
406             static void
407 0           mul20(uint32_t *d, const uint32_t *a, const uint32_t *b)
408             {
409             uint32_t t[39];
410              
411 0           t[ 0] = MUL15(a[ 0], b[ 0]);
412 0           t[ 1] = MUL15(a[ 0], b[ 1])
413 0           + MUL15(a[ 1], b[ 0]);
414 0           t[ 2] = MUL15(a[ 0], b[ 2])
415 0           + MUL15(a[ 1], b[ 1])
416 0           + MUL15(a[ 2], b[ 0]);
417 0           t[ 3] = MUL15(a[ 0], b[ 3])
418 0           + MUL15(a[ 1], b[ 2])
419 0           + MUL15(a[ 2], b[ 1])
420 0           + MUL15(a[ 3], b[ 0]);
421 0           t[ 4] = MUL15(a[ 0], b[ 4])
422 0           + MUL15(a[ 1], b[ 3])
423 0           + MUL15(a[ 2], b[ 2])
424 0           + MUL15(a[ 3], b[ 1])
425 0           + MUL15(a[ 4], b[ 0]);
426 0           t[ 5] = MUL15(a[ 0], b[ 5])
427 0           + MUL15(a[ 1], b[ 4])
428 0           + MUL15(a[ 2], b[ 3])
429 0           + MUL15(a[ 3], b[ 2])
430 0           + MUL15(a[ 4], b[ 1])
431 0           + MUL15(a[ 5], b[ 0]);
432 0           t[ 6] = MUL15(a[ 0], b[ 6])
433 0           + MUL15(a[ 1], b[ 5])
434 0           + MUL15(a[ 2], b[ 4])
435 0           + MUL15(a[ 3], b[ 3])
436 0           + MUL15(a[ 4], b[ 2])
437 0           + MUL15(a[ 5], b[ 1])
438 0           + MUL15(a[ 6], b[ 0]);
439 0           t[ 7] = MUL15(a[ 0], b[ 7])
440 0           + MUL15(a[ 1], b[ 6])
441 0           + MUL15(a[ 2], b[ 5])
442 0           + MUL15(a[ 3], b[ 4])
443 0           + MUL15(a[ 4], b[ 3])
444 0           + MUL15(a[ 5], b[ 2])
445 0           + MUL15(a[ 6], b[ 1])
446 0           + MUL15(a[ 7], b[ 0]);
447 0           t[ 8] = MUL15(a[ 0], b[ 8])
448 0           + MUL15(a[ 1], b[ 7])
449 0           + MUL15(a[ 2], b[ 6])
450 0           + MUL15(a[ 3], b[ 5])
451 0           + MUL15(a[ 4], b[ 4])
452 0           + MUL15(a[ 5], b[ 3])
453 0           + MUL15(a[ 6], b[ 2])
454 0           + MUL15(a[ 7], b[ 1])
455 0           + MUL15(a[ 8], b[ 0]);
456 0           t[ 9] = MUL15(a[ 0], b[ 9])
457 0           + MUL15(a[ 1], b[ 8])
458 0           + MUL15(a[ 2], b[ 7])
459 0           + MUL15(a[ 3], b[ 6])
460 0           + MUL15(a[ 4], b[ 5])
461 0           + MUL15(a[ 5], b[ 4])
462 0           + MUL15(a[ 6], b[ 3])
463 0           + MUL15(a[ 7], b[ 2])
464 0           + MUL15(a[ 8], b[ 1])
465 0           + MUL15(a[ 9], b[ 0]);
466 0           t[10] = MUL15(a[ 0], b[10])
467 0           + MUL15(a[ 1], b[ 9])
468 0           + MUL15(a[ 2], b[ 8])
469 0           + MUL15(a[ 3], b[ 7])
470 0           + MUL15(a[ 4], b[ 6])
471 0           + MUL15(a[ 5], b[ 5])
472 0           + MUL15(a[ 6], b[ 4])
473 0           + MUL15(a[ 7], b[ 3])
474 0           + MUL15(a[ 8], b[ 2])
475 0           + MUL15(a[ 9], b[ 1])
476 0           + MUL15(a[10], b[ 0]);
477 0           t[11] = MUL15(a[ 0], b[11])
478 0           + MUL15(a[ 1], b[10])
479 0           + MUL15(a[ 2], b[ 9])
480 0           + MUL15(a[ 3], b[ 8])
481 0           + MUL15(a[ 4], b[ 7])
482 0           + MUL15(a[ 5], b[ 6])
483 0           + MUL15(a[ 6], b[ 5])
484 0           + MUL15(a[ 7], b[ 4])
485 0           + MUL15(a[ 8], b[ 3])
486 0           + MUL15(a[ 9], b[ 2])
487 0           + MUL15(a[10], b[ 1])
488 0           + MUL15(a[11], b[ 0]);
489 0           t[12] = MUL15(a[ 0], b[12])
490 0           + MUL15(a[ 1], b[11])
491 0           + MUL15(a[ 2], b[10])
492 0           + MUL15(a[ 3], b[ 9])
493 0           + MUL15(a[ 4], b[ 8])
494 0           + MUL15(a[ 5], b[ 7])
495 0           + MUL15(a[ 6], b[ 6])
496 0           + MUL15(a[ 7], b[ 5])
497 0           + MUL15(a[ 8], b[ 4])
498 0           + MUL15(a[ 9], b[ 3])
499 0           + MUL15(a[10], b[ 2])
500 0           + MUL15(a[11], b[ 1])
501 0           + MUL15(a[12], b[ 0]);
502 0           t[13] = MUL15(a[ 0], b[13])
503 0           + MUL15(a[ 1], b[12])
504 0           + MUL15(a[ 2], b[11])
505 0           + MUL15(a[ 3], b[10])
506 0           + MUL15(a[ 4], b[ 9])
507 0           + MUL15(a[ 5], b[ 8])
508 0           + MUL15(a[ 6], b[ 7])
509 0           + MUL15(a[ 7], b[ 6])
510 0           + MUL15(a[ 8], b[ 5])
511 0           + MUL15(a[ 9], b[ 4])
512 0           + MUL15(a[10], b[ 3])
513 0           + MUL15(a[11], b[ 2])
514 0           + MUL15(a[12], b[ 1])
515 0           + MUL15(a[13], b[ 0]);
516 0           t[14] = MUL15(a[ 0], b[14])
517 0           + MUL15(a[ 1], b[13])
518 0           + MUL15(a[ 2], b[12])
519 0           + MUL15(a[ 3], b[11])
520 0           + MUL15(a[ 4], b[10])
521 0           + MUL15(a[ 5], b[ 9])
522 0           + MUL15(a[ 6], b[ 8])
523 0           + MUL15(a[ 7], b[ 7])
524 0           + MUL15(a[ 8], b[ 6])
525 0           + MUL15(a[ 9], b[ 5])
526 0           + MUL15(a[10], b[ 4])
527 0           + MUL15(a[11], b[ 3])
528 0           + MUL15(a[12], b[ 2])
529 0           + MUL15(a[13], b[ 1])
530 0           + MUL15(a[14], b[ 0]);
531 0           t[15] = MUL15(a[ 0], b[15])
532 0           + MUL15(a[ 1], b[14])
533 0           + MUL15(a[ 2], b[13])
534 0           + MUL15(a[ 3], b[12])
535 0           + MUL15(a[ 4], b[11])
536 0           + MUL15(a[ 5], b[10])
537 0           + MUL15(a[ 6], b[ 9])
538 0           + MUL15(a[ 7], b[ 8])
539 0           + MUL15(a[ 8], b[ 7])
540 0           + MUL15(a[ 9], b[ 6])
541 0           + MUL15(a[10], b[ 5])
542 0           + MUL15(a[11], b[ 4])
543 0           + MUL15(a[12], b[ 3])
544 0           + MUL15(a[13], b[ 2])
545 0           + MUL15(a[14], b[ 1])
546 0           + MUL15(a[15], b[ 0]);
547 0           t[16] = MUL15(a[ 0], b[16])
548 0           + MUL15(a[ 1], b[15])
549 0           + MUL15(a[ 2], b[14])
550 0           + MUL15(a[ 3], b[13])
551 0           + MUL15(a[ 4], b[12])
552 0           + MUL15(a[ 5], b[11])
553 0           + MUL15(a[ 6], b[10])
554 0           + MUL15(a[ 7], b[ 9])
555 0           + MUL15(a[ 8], b[ 8])
556 0           + MUL15(a[ 9], b[ 7])
557 0           + MUL15(a[10], b[ 6])
558 0           + MUL15(a[11], b[ 5])
559 0           + MUL15(a[12], b[ 4])
560 0           + MUL15(a[13], b[ 3])
561 0           + MUL15(a[14], b[ 2])
562 0           + MUL15(a[15], b[ 1])
563 0           + MUL15(a[16], b[ 0]);
564 0           t[17] = MUL15(a[ 0], b[17])
565 0           + MUL15(a[ 1], b[16])
566 0           + MUL15(a[ 2], b[15])
567 0           + MUL15(a[ 3], b[14])
568 0           + MUL15(a[ 4], b[13])
569 0           + MUL15(a[ 5], b[12])
570 0           + MUL15(a[ 6], b[11])
571 0           + MUL15(a[ 7], b[10])
572 0           + MUL15(a[ 8], b[ 9])
573 0           + MUL15(a[ 9], b[ 8])
574 0           + MUL15(a[10], b[ 7])
575 0           + MUL15(a[11], b[ 6])
576 0           + MUL15(a[12], b[ 5])
577 0           + MUL15(a[13], b[ 4])
578 0           + MUL15(a[14], b[ 3])
579 0           + MUL15(a[15], b[ 2])
580 0           + MUL15(a[16], b[ 1])
581 0           + MUL15(a[17], b[ 0]);
582 0           t[18] = MUL15(a[ 0], b[18])
583 0           + MUL15(a[ 1], b[17])
584 0           + MUL15(a[ 2], b[16])
585 0           + MUL15(a[ 3], b[15])
586 0           + MUL15(a[ 4], b[14])
587 0           + MUL15(a[ 5], b[13])
588 0           + MUL15(a[ 6], b[12])
589 0           + MUL15(a[ 7], b[11])
590 0           + MUL15(a[ 8], b[10])
591 0           + MUL15(a[ 9], b[ 9])
592 0           + MUL15(a[10], b[ 8])
593 0           + MUL15(a[11], b[ 7])
594 0           + MUL15(a[12], b[ 6])
595 0           + MUL15(a[13], b[ 5])
596 0           + MUL15(a[14], b[ 4])
597 0           + MUL15(a[15], b[ 3])
598 0           + MUL15(a[16], b[ 2])
599 0           + MUL15(a[17], b[ 1])
600 0           + MUL15(a[18], b[ 0]);
601 0           t[19] = MUL15(a[ 0], b[19])
602 0           + MUL15(a[ 1], b[18])
603 0           + MUL15(a[ 2], b[17])
604 0           + MUL15(a[ 3], b[16])
605 0           + MUL15(a[ 4], b[15])
606 0           + MUL15(a[ 5], b[14])
607 0           + MUL15(a[ 6], b[13])
608 0           + MUL15(a[ 7], b[12])
609 0           + MUL15(a[ 8], b[11])
610 0           + MUL15(a[ 9], b[10])
611 0           + MUL15(a[10], b[ 9])
612 0           + MUL15(a[11], b[ 8])
613 0           + MUL15(a[12], b[ 7])
614 0           + MUL15(a[13], b[ 6])
615 0           + MUL15(a[14], b[ 5])
616 0           + MUL15(a[15], b[ 4])
617 0           + MUL15(a[16], b[ 3])
618 0           + MUL15(a[17], b[ 2])
619 0           + MUL15(a[18], b[ 1])
620 0           + MUL15(a[19], b[ 0]);
621 0           t[20] = MUL15(a[ 1], b[19])
622 0           + MUL15(a[ 2], b[18])
623 0           + MUL15(a[ 3], b[17])
624 0           + MUL15(a[ 4], b[16])
625 0           + MUL15(a[ 5], b[15])
626 0           + MUL15(a[ 6], b[14])
627 0           + MUL15(a[ 7], b[13])
628 0           + MUL15(a[ 8], b[12])
629 0           + MUL15(a[ 9], b[11])
630 0           + MUL15(a[10], b[10])
631 0           + MUL15(a[11], b[ 9])
632 0           + MUL15(a[12], b[ 8])
633 0           + MUL15(a[13], b[ 7])
634 0           + MUL15(a[14], b[ 6])
635 0           + MUL15(a[15], b[ 5])
636 0           + MUL15(a[16], b[ 4])
637 0           + MUL15(a[17], b[ 3])
638 0           + MUL15(a[18], b[ 2])
639 0           + MUL15(a[19], b[ 1]);
640 0           t[21] = MUL15(a[ 2], b[19])
641 0           + MUL15(a[ 3], b[18])
642 0           + MUL15(a[ 4], b[17])
643 0           + MUL15(a[ 5], b[16])
644 0           + MUL15(a[ 6], b[15])
645 0           + MUL15(a[ 7], b[14])
646 0           + MUL15(a[ 8], b[13])
647 0           + MUL15(a[ 9], b[12])
648 0           + MUL15(a[10], b[11])
649 0           + MUL15(a[11], b[10])
650 0           + MUL15(a[12], b[ 9])
651 0           + MUL15(a[13], b[ 8])
652 0           + MUL15(a[14], b[ 7])
653 0           + MUL15(a[15], b[ 6])
654 0           + MUL15(a[16], b[ 5])
655 0           + MUL15(a[17], b[ 4])
656 0           + MUL15(a[18], b[ 3])
657 0           + MUL15(a[19], b[ 2]);
658 0           t[22] = MUL15(a[ 3], b[19])
659 0           + MUL15(a[ 4], b[18])
660 0           + MUL15(a[ 5], b[17])
661 0           + MUL15(a[ 6], b[16])
662 0           + MUL15(a[ 7], b[15])
663 0           + MUL15(a[ 8], b[14])
664 0           + MUL15(a[ 9], b[13])
665 0           + MUL15(a[10], b[12])
666 0           + MUL15(a[11], b[11])
667 0           + MUL15(a[12], b[10])
668 0           + MUL15(a[13], b[ 9])
669 0           + MUL15(a[14], b[ 8])
670 0           + MUL15(a[15], b[ 7])
671 0           + MUL15(a[16], b[ 6])
672 0           + MUL15(a[17], b[ 5])
673 0           + MUL15(a[18], b[ 4])
674 0           + MUL15(a[19], b[ 3]);
675 0           t[23] = MUL15(a[ 4], b[19])
676 0           + MUL15(a[ 5], b[18])
677 0           + MUL15(a[ 6], b[17])
678 0           + MUL15(a[ 7], b[16])
679 0           + MUL15(a[ 8], b[15])
680 0           + MUL15(a[ 9], b[14])
681 0           + MUL15(a[10], b[13])
682 0           + MUL15(a[11], b[12])
683 0           + MUL15(a[12], b[11])
684 0           + MUL15(a[13], b[10])
685 0           + MUL15(a[14], b[ 9])
686 0           + MUL15(a[15], b[ 8])
687 0           + MUL15(a[16], b[ 7])
688 0           + MUL15(a[17], b[ 6])
689 0           + MUL15(a[18], b[ 5])
690 0           + MUL15(a[19], b[ 4]);
691 0           t[24] = MUL15(a[ 5], b[19])
692 0           + MUL15(a[ 6], b[18])
693 0           + MUL15(a[ 7], b[17])
694 0           + MUL15(a[ 8], b[16])
695 0           + MUL15(a[ 9], b[15])
696 0           + MUL15(a[10], b[14])
697 0           + MUL15(a[11], b[13])
698 0           + MUL15(a[12], b[12])
699 0           + MUL15(a[13], b[11])
700 0           + MUL15(a[14], b[10])
701 0           + MUL15(a[15], b[ 9])
702 0           + MUL15(a[16], b[ 8])
703 0           + MUL15(a[17], b[ 7])
704 0           + MUL15(a[18], b[ 6])
705 0           + MUL15(a[19], b[ 5]);
706 0           t[25] = MUL15(a[ 6], b[19])
707 0           + MUL15(a[ 7], b[18])
708 0           + MUL15(a[ 8], b[17])
709 0           + MUL15(a[ 9], b[16])
710 0           + MUL15(a[10], b[15])
711 0           + MUL15(a[11], b[14])
712 0           + MUL15(a[12], b[13])
713 0           + MUL15(a[13], b[12])
714 0           + MUL15(a[14], b[11])
715 0           + MUL15(a[15], b[10])
716 0           + MUL15(a[16], b[ 9])
717 0           + MUL15(a[17], b[ 8])
718 0           + MUL15(a[18], b[ 7])
719 0           + MUL15(a[19], b[ 6]);
720 0           t[26] = MUL15(a[ 7], b[19])
721 0           + MUL15(a[ 8], b[18])
722 0           + MUL15(a[ 9], b[17])
723 0           + MUL15(a[10], b[16])
724 0           + MUL15(a[11], b[15])
725 0           + MUL15(a[12], b[14])
726 0           + MUL15(a[13], b[13])
727 0           + MUL15(a[14], b[12])
728 0           + MUL15(a[15], b[11])
729 0           + MUL15(a[16], b[10])
730 0           + MUL15(a[17], b[ 9])
731 0           + MUL15(a[18], b[ 8])
732 0           + MUL15(a[19], b[ 7]);
733 0           t[27] = MUL15(a[ 8], b[19])
734 0           + MUL15(a[ 9], b[18])
735 0           + MUL15(a[10], b[17])
736 0           + MUL15(a[11], b[16])
737 0           + MUL15(a[12], b[15])
738 0           + MUL15(a[13], b[14])
739 0           + MUL15(a[14], b[13])
740 0           + MUL15(a[15], b[12])
741 0           + MUL15(a[16], b[11])
742 0           + MUL15(a[17], b[10])
743 0           + MUL15(a[18], b[ 9])
744 0           + MUL15(a[19], b[ 8]);
745 0           t[28] = MUL15(a[ 9], b[19])
746 0           + MUL15(a[10], b[18])
747 0           + MUL15(a[11], b[17])
748 0           + MUL15(a[12], b[16])
749 0           + MUL15(a[13], b[15])
750 0           + MUL15(a[14], b[14])
751 0           + MUL15(a[15], b[13])
752 0           + MUL15(a[16], b[12])
753 0           + MUL15(a[17], b[11])
754 0           + MUL15(a[18], b[10])
755 0           + MUL15(a[19], b[ 9]);
756 0           t[29] = MUL15(a[10], b[19])
757 0           + MUL15(a[11], b[18])
758 0           + MUL15(a[12], b[17])
759 0           + MUL15(a[13], b[16])
760 0           + MUL15(a[14], b[15])
761 0           + MUL15(a[15], b[14])
762 0           + MUL15(a[16], b[13])
763 0           + MUL15(a[17], b[12])
764 0           + MUL15(a[18], b[11])
765 0           + MUL15(a[19], b[10]);
766 0           t[30] = MUL15(a[11], b[19])
767 0           + MUL15(a[12], b[18])
768 0           + MUL15(a[13], b[17])
769 0           + MUL15(a[14], b[16])
770 0           + MUL15(a[15], b[15])
771 0           + MUL15(a[16], b[14])
772 0           + MUL15(a[17], b[13])
773 0           + MUL15(a[18], b[12])
774 0           + MUL15(a[19], b[11]);
775 0           t[31] = MUL15(a[12], b[19])
776 0           + MUL15(a[13], b[18])
777 0           + MUL15(a[14], b[17])
778 0           + MUL15(a[15], b[16])
779 0           + MUL15(a[16], b[15])
780 0           + MUL15(a[17], b[14])
781 0           + MUL15(a[18], b[13])
782 0           + MUL15(a[19], b[12]);
783 0           t[32] = MUL15(a[13], b[19])
784 0           + MUL15(a[14], b[18])
785 0           + MUL15(a[15], b[17])
786 0           + MUL15(a[16], b[16])
787 0           + MUL15(a[17], b[15])
788 0           + MUL15(a[18], b[14])
789 0           + MUL15(a[19], b[13]);
790 0           t[33] = MUL15(a[14], b[19])
791 0           + MUL15(a[15], b[18])
792 0           + MUL15(a[16], b[17])
793 0           + MUL15(a[17], b[16])
794 0           + MUL15(a[18], b[15])
795 0           + MUL15(a[19], b[14]);
796 0           t[34] = MUL15(a[15], b[19])
797 0           + MUL15(a[16], b[18])
798 0           + MUL15(a[17], b[17])
799 0           + MUL15(a[18], b[16])
800 0           + MUL15(a[19], b[15]);
801 0           t[35] = MUL15(a[16], b[19])
802 0           + MUL15(a[17], b[18])
803 0           + MUL15(a[18], b[17])
804 0           + MUL15(a[19], b[16]);
805 0           t[36] = MUL15(a[17], b[19])
806 0           + MUL15(a[18], b[18])
807 0           + MUL15(a[19], b[17]);
808 0           t[37] = MUL15(a[18], b[19])
809 0           + MUL15(a[19], b[18]);
810 0           t[38] = MUL15(a[19], b[19]);
811              
812 0           d[39] = norm13(d, t, 39);
813 0           }
814              
815             static void
816 0           square20(uint32_t *d, const uint32_t *a)
817             {
818             uint32_t t[39];
819              
820 0           t[ 0] = MUL15(a[ 0], a[ 0]);
821 0           t[ 1] = ((MUL15(a[ 0], a[ 1])) << 1);
822 0           t[ 2] = MUL15(a[ 1], a[ 1])
823 0           + ((MUL15(a[ 0], a[ 2])) << 1);
824 0           t[ 3] = ((MUL15(a[ 0], a[ 3])
825 0           + MUL15(a[ 1], a[ 2])) << 1);
826 0           t[ 4] = MUL15(a[ 2], a[ 2])
827 0           + ((MUL15(a[ 0], a[ 4])
828 0           + MUL15(a[ 1], a[ 3])) << 1);
829 0           t[ 5] = ((MUL15(a[ 0], a[ 5])
830 0           + MUL15(a[ 1], a[ 4])
831 0           + MUL15(a[ 2], a[ 3])) << 1);
832 0           t[ 6] = MUL15(a[ 3], a[ 3])
833 0           + ((MUL15(a[ 0], a[ 6])
834 0           + MUL15(a[ 1], a[ 5])
835 0           + MUL15(a[ 2], a[ 4])) << 1);
836 0           t[ 7] = ((MUL15(a[ 0], a[ 7])
837 0           + MUL15(a[ 1], a[ 6])
838 0           + MUL15(a[ 2], a[ 5])
839 0           + MUL15(a[ 3], a[ 4])) << 1);
840 0           t[ 8] = MUL15(a[ 4], a[ 4])
841 0           + ((MUL15(a[ 0], a[ 8])
842 0           + MUL15(a[ 1], a[ 7])
843 0           + MUL15(a[ 2], a[ 6])
844 0           + MUL15(a[ 3], a[ 5])) << 1);
845 0           t[ 9] = ((MUL15(a[ 0], a[ 9])
846 0           + MUL15(a[ 1], a[ 8])
847 0           + MUL15(a[ 2], a[ 7])
848 0           + MUL15(a[ 3], a[ 6])
849 0           + MUL15(a[ 4], a[ 5])) << 1);
850 0           t[10] = MUL15(a[ 5], a[ 5])
851 0           + ((MUL15(a[ 0], a[10])
852 0           + MUL15(a[ 1], a[ 9])
853 0           + MUL15(a[ 2], a[ 8])
854 0           + MUL15(a[ 3], a[ 7])
855 0           + MUL15(a[ 4], a[ 6])) << 1);
856 0           t[11] = ((MUL15(a[ 0], a[11])
857 0           + MUL15(a[ 1], a[10])
858 0           + MUL15(a[ 2], a[ 9])
859 0           + MUL15(a[ 3], a[ 8])
860 0           + MUL15(a[ 4], a[ 7])
861 0           + MUL15(a[ 5], a[ 6])) << 1);
862 0           t[12] = MUL15(a[ 6], a[ 6])
863 0           + ((MUL15(a[ 0], a[12])
864 0           + MUL15(a[ 1], a[11])
865 0           + MUL15(a[ 2], a[10])
866 0           + MUL15(a[ 3], a[ 9])
867 0           + MUL15(a[ 4], a[ 8])
868 0           + MUL15(a[ 5], a[ 7])) << 1);
869 0           t[13] = ((MUL15(a[ 0], a[13])
870 0           + MUL15(a[ 1], a[12])
871 0           + MUL15(a[ 2], a[11])
872 0           + MUL15(a[ 3], a[10])
873 0           + MUL15(a[ 4], a[ 9])
874 0           + MUL15(a[ 5], a[ 8])
875 0           + MUL15(a[ 6], a[ 7])) << 1);
876 0           t[14] = MUL15(a[ 7], a[ 7])
877 0           + ((MUL15(a[ 0], a[14])
878 0           + MUL15(a[ 1], a[13])
879 0           + MUL15(a[ 2], a[12])
880 0           + MUL15(a[ 3], a[11])
881 0           + MUL15(a[ 4], a[10])
882 0           + MUL15(a[ 5], a[ 9])
883 0           + MUL15(a[ 6], a[ 8])) << 1);
884 0           t[15] = ((MUL15(a[ 0], a[15])
885 0           + MUL15(a[ 1], a[14])
886 0           + MUL15(a[ 2], a[13])
887 0           + MUL15(a[ 3], a[12])
888 0           + MUL15(a[ 4], a[11])
889 0           + MUL15(a[ 5], a[10])
890 0           + MUL15(a[ 6], a[ 9])
891 0           + MUL15(a[ 7], a[ 8])) << 1);
892 0           t[16] = MUL15(a[ 8], a[ 8])
893 0           + ((MUL15(a[ 0], a[16])
894 0           + MUL15(a[ 1], a[15])
895 0           + MUL15(a[ 2], a[14])
896 0           + MUL15(a[ 3], a[13])
897 0           + MUL15(a[ 4], a[12])
898 0           + MUL15(a[ 5], a[11])
899 0           + MUL15(a[ 6], a[10])
900 0           + MUL15(a[ 7], a[ 9])) << 1);
901 0           t[17] = ((MUL15(a[ 0], a[17])
902 0           + MUL15(a[ 1], a[16])
903 0           + MUL15(a[ 2], a[15])
904 0           + MUL15(a[ 3], a[14])
905 0           + MUL15(a[ 4], a[13])
906 0           + MUL15(a[ 5], a[12])
907 0           + MUL15(a[ 6], a[11])
908 0           + MUL15(a[ 7], a[10])
909 0           + MUL15(a[ 8], a[ 9])) << 1);
910 0           t[18] = MUL15(a[ 9], a[ 9])
911 0           + ((MUL15(a[ 0], a[18])
912 0           + MUL15(a[ 1], a[17])
913 0           + MUL15(a[ 2], a[16])
914 0           + MUL15(a[ 3], a[15])
915 0           + MUL15(a[ 4], a[14])
916 0           + MUL15(a[ 5], a[13])
917 0           + MUL15(a[ 6], a[12])
918 0           + MUL15(a[ 7], a[11])
919 0           + MUL15(a[ 8], a[10])) << 1);
920 0           t[19] = ((MUL15(a[ 0], a[19])
921 0           + MUL15(a[ 1], a[18])
922 0           + MUL15(a[ 2], a[17])
923 0           + MUL15(a[ 3], a[16])
924 0           + MUL15(a[ 4], a[15])
925 0           + MUL15(a[ 5], a[14])
926 0           + MUL15(a[ 6], a[13])
927 0           + MUL15(a[ 7], a[12])
928 0           + MUL15(a[ 8], a[11])
929 0           + MUL15(a[ 9], a[10])) << 1);
930 0           t[20] = MUL15(a[10], a[10])
931 0           + ((MUL15(a[ 1], a[19])
932 0           + MUL15(a[ 2], a[18])
933 0           + MUL15(a[ 3], a[17])
934 0           + MUL15(a[ 4], a[16])
935 0           + MUL15(a[ 5], a[15])
936 0           + MUL15(a[ 6], a[14])
937 0           + MUL15(a[ 7], a[13])
938 0           + MUL15(a[ 8], a[12])
939 0           + MUL15(a[ 9], a[11])) << 1);
940 0           t[21] = ((MUL15(a[ 2], a[19])
941 0           + MUL15(a[ 3], a[18])
942 0           + MUL15(a[ 4], a[17])
943 0           + MUL15(a[ 5], a[16])
944 0           + MUL15(a[ 6], a[15])
945 0           + MUL15(a[ 7], a[14])
946 0           + MUL15(a[ 8], a[13])
947 0           + MUL15(a[ 9], a[12])
948 0           + MUL15(a[10], a[11])) << 1);
949 0           t[22] = MUL15(a[11], a[11])
950 0           + ((MUL15(a[ 3], a[19])
951 0           + MUL15(a[ 4], a[18])
952 0           + MUL15(a[ 5], a[17])
953 0           + MUL15(a[ 6], a[16])
954 0           + MUL15(a[ 7], a[15])
955 0           + MUL15(a[ 8], a[14])
956 0           + MUL15(a[ 9], a[13])
957 0           + MUL15(a[10], a[12])) << 1);
958 0           t[23] = ((MUL15(a[ 4], a[19])
959 0           + MUL15(a[ 5], a[18])
960 0           + MUL15(a[ 6], a[17])
961 0           + MUL15(a[ 7], a[16])
962 0           + MUL15(a[ 8], a[15])
963 0           + MUL15(a[ 9], a[14])
964 0           + MUL15(a[10], a[13])
965 0           + MUL15(a[11], a[12])) << 1);
966 0           t[24] = MUL15(a[12], a[12])
967 0           + ((MUL15(a[ 5], a[19])
968 0           + MUL15(a[ 6], a[18])
969 0           + MUL15(a[ 7], a[17])
970 0           + MUL15(a[ 8], a[16])
971 0           + MUL15(a[ 9], a[15])
972 0           + MUL15(a[10], a[14])
973 0           + MUL15(a[11], a[13])) << 1);
974 0           t[25] = ((MUL15(a[ 6], a[19])
975 0           + MUL15(a[ 7], a[18])
976 0           + MUL15(a[ 8], a[17])
977 0           + MUL15(a[ 9], a[16])
978 0           + MUL15(a[10], a[15])
979 0           + MUL15(a[11], a[14])
980 0           + MUL15(a[12], a[13])) << 1);
981 0           t[26] = MUL15(a[13], a[13])
982 0           + ((MUL15(a[ 7], a[19])
983 0           + MUL15(a[ 8], a[18])
984 0           + MUL15(a[ 9], a[17])
985 0           + MUL15(a[10], a[16])
986 0           + MUL15(a[11], a[15])
987 0           + MUL15(a[12], a[14])) << 1);
988 0           t[27] = ((MUL15(a[ 8], a[19])
989 0           + MUL15(a[ 9], a[18])
990 0           + MUL15(a[10], a[17])
991 0           + MUL15(a[11], a[16])
992 0           + MUL15(a[12], a[15])
993 0           + MUL15(a[13], a[14])) << 1);
994 0           t[28] = MUL15(a[14], a[14])
995 0           + ((MUL15(a[ 9], a[19])
996 0           + MUL15(a[10], a[18])
997 0           + MUL15(a[11], a[17])
998 0           + MUL15(a[12], a[16])
999 0           + MUL15(a[13], a[15])) << 1);
1000 0           t[29] = ((MUL15(a[10], a[19])
1001 0           + MUL15(a[11], a[18])
1002 0           + MUL15(a[12], a[17])
1003 0           + MUL15(a[13], a[16])
1004 0           + MUL15(a[14], a[15])) << 1);
1005 0           t[30] = MUL15(a[15], a[15])
1006 0           + ((MUL15(a[11], a[19])
1007 0           + MUL15(a[12], a[18])
1008 0           + MUL15(a[13], a[17])
1009 0           + MUL15(a[14], a[16])) << 1);
1010 0           t[31] = ((MUL15(a[12], a[19])
1011 0           + MUL15(a[13], a[18])
1012 0           + MUL15(a[14], a[17])
1013 0           + MUL15(a[15], a[16])) << 1);
1014 0           t[32] = MUL15(a[16], a[16])
1015 0           + ((MUL15(a[13], a[19])
1016 0           + MUL15(a[14], a[18])
1017 0           + MUL15(a[15], a[17])) << 1);
1018 0           t[33] = ((MUL15(a[14], a[19])
1019 0           + MUL15(a[15], a[18])
1020 0           + MUL15(a[16], a[17])) << 1);
1021 0           t[34] = MUL15(a[17], a[17])
1022 0           + ((MUL15(a[15], a[19])
1023 0           + MUL15(a[16], a[18])) << 1);
1024 0           t[35] = ((MUL15(a[16], a[19])
1025 0           + MUL15(a[17], a[18])) << 1);
1026 0           t[36] = MUL15(a[18], a[18])
1027 0           + ((MUL15(a[17], a[19])) << 1);
1028 0           t[37] = ((MUL15(a[18], a[19])) << 1);
1029 0           t[38] = MUL15(a[19], a[19]);
1030              
1031 0           d[39] = norm13(d, t, 39);
1032 0           }
1033              
1034             #endif
1035              
1036             /*
1037             * Perform a "final reduction" in field F255 (field for Curve25519)
1038             * The source value must be less than twice the modulus. If the value
1039             * is not lower than the modulus, then the modulus is subtracted and
1040             * this function returns 1; otherwise, it leaves it untouched and it
1041             * returns 0.
1042             */
1043             static uint32_t
1044 0           reduce_final_f255(uint32_t *d)
1045             {
1046             uint32_t t[20];
1047             uint32_t cc;
1048             int i;
1049              
1050 0           memcpy(t, d, sizeof t);
1051 0           cc = 19;
1052 0 0         for (i = 0; i < 20; i ++) {
1053             uint32_t w;
1054              
1055 0           w = t[i] + cc;
1056 0           cc = w >> 13;
1057 0           t[i] = w & 0x1FFF;
1058             }
1059 0           cc = t[19] >> 8;
1060 0           t[19] &= 0xFF;
1061 0           CCOPY(cc, d, t, sizeof t);
1062 0           return cc;
1063             }
1064              
1065             static void
1066 0           f255_mulgen(uint32_t *d, const uint32_t *a, const uint32_t *b, int square)
1067             {
1068             uint32_t t[40], cc, w;
1069              
1070             /*
1071             * Compute raw multiplication. All result words fit in 13 bits
1072             * each; upper word (t[39]) must fit on 5 bits, since the product
1073             * of two 256-bit integers must fit on 512 bits.
1074             */
1075 0 0         if (square) {
1076 0           square20(t, a);
1077             } else {
1078 0           mul20(t, a, b);
1079             }
1080              
1081             /*
1082             * Modular reduction: each high word is added where necessary.
1083             * Since the modulus is 2^255-19 and word 20 corresponds to
1084             * offset 20*13 = 260, word 20+k must be added to word k with
1085             * a factor of 19*2^5 = 608. The extra bits in word 19 are also
1086             * added that way.
1087             */
1088 0           cc = MUL15(t[19] >> 8, 19);
1089 0           t[19] &= 0xFF;
1090              
1091             #define MM1(x) do { \
1092             w = t[x] + cc + MUL15(t[(x) + 20], 608); \
1093             t[x] = w & 0x1FFF; \
1094             cc = w >> 13; \
1095             } while (0)
1096              
1097 0           MM1( 0);
1098 0           MM1( 1);
1099 0           MM1( 2);
1100 0           MM1( 3);
1101 0           MM1( 4);
1102 0           MM1( 5);
1103 0           MM1( 6);
1104 0           MM1( 7);
1105 0           MM1( 8);
1106 0           MM1( 9);
1107 0           MM1(10);
1108 0           MM1(11);
1109 0           MM1(12);
1110 0           MM1(13);
1111 0           MM1(14);
1112 0           MM1(15);
1113 0           MM1(16);
1114 0           MM1(17);
1115 0           MM1(18);
1116 0           MM1(19);
1117              
1118             #undef MM1
1119              
1120 0           cc = MUL15(w >> 8, 19);
1121 0           t[19] &= 0xFF;
1122              
1123             #define MM2(x) do { \
1124             w = t[x] + cc; \
1125             d[x] = w & 0x1FFF; \
1126             cc = w >> 13; \
1127             } while (0)
1128              
1129 0           MM2( 0);
1130 0           MM2( 1);
1131 0           MM2( 2);
1132 0           MM2( 3);
1133 0           MM2( 4);
1134 0           MM2( 5);
1135 0           MM2( 6);
1136 0           MM2( 7);
1137 0           MM2( 8);
1138 0           MM2( 9);
1139 0           MM2(10);
1140 0           MM2(11);
1141 0           MM2(12);
1142 0           MM2(13);
1143 0           MM2(14);
1144 0           MM2(15);
1145 0           MM2(16);
1146 0           MM2(17);
1147 0           MM2(18);
1148 0           MM2(19);
1149              
1150             #undef MM2
1151 0           }
1152              
1153             /*
1154             * Perform a multiplication of two integers modulo 2^255-19.
1155             * Operands are arrays of 20 words, each containing 13 bits of data, in
1156             * little-endian order. Input value may be up to 2^256-1; on output, value
1157             * fits on 256 bits and is lower than twice the modulus.
1158             *
1159             * f255_mul() is the general multiplication, f255_square() is specialised
1160             * for squarings.
1161             */
1162             #define f255_mul(d, a, b) f255_mulgen(d, a, b, 0)
1163             #define f255_square(d, a) f255_mulgen(d, a, a, 1)
1164              
1165             /*
1166             * Add two values in F255. Partial reduction is performed (down to less
1167             * than twice the modulus).
1168             */
1169             static void
1170 0           f255_add(uint32_t *d, const uint32_t *a, const uint32_t *b)
1171             {
1172             int i;
1173             uint32_t cc, w;
1174              
1175 0           cc = 0;
1176 0 0         for (i = 0; i < 20; i ++) {
1177 0           w = a[i] + b[i] + cc;
1178 0           d[i] = w & 0x1FFF;
1179 0           cc = w >> 13;
1180             }
1181 0           cc = MUL15(w >> 8, 19);
1182 0           d[19] &= 0xFF;
1183 0 0         for (i = 0; i < 20; i ++) {
1184 0           w = d[i] + cc;
1185 0           d[i] = w & 0x1FFF;
1186 0           cc = w >> 13;
1187             }
1188 0           }
1189              
1190             /*
1191             * Subtract one value from another in F255. Partial reduction is
1192             * performed (down to less than twice the modulus).
1193             */
1194             static void
1195 0           f255_sub(uint32_t *d, const uint32_t *a, const uint32_t *b)
1196             {
1197             /*
1198             * We actually compute a - b + 2*p, so that the final value is
1199             * necessarily positive.
1200             */
1201             int i;
1202             uint32_t cc, w;
1203              
1204 0           cc = (uint32_t)-38;
1205 0 0         for (i = 0; i < 20; i ++) {
1206 0           w = a[i] - b[i] + cc;
1207 0           d[i] = w & 0x1FFF;
1208 0           cc = ARSH(w, 13);
1209             }
1210 0           cc = MUL15((w + 0x200) >> 8, 19);
1211 0           d[19] &= 0xFF;
1212 0 0         for (i = 0; i < 20; i ++) {
1213 0           w = d[i] + cc;
1214 0           d[i] = w & 0x1FFF;
1215 0           cc = w >> 13;
1216             }
1217 0           }
1218              
1219             /*
1220             * Multiply an integer by the 'A24' constant (121665). Partial reduction
1221             * is performed (down to less than twice the modulus).
1222             */
1223             static void
1224 0           f255_mul_a24(uint32_t *d, const uint32_t *a)
1225             {
1226             int i;
1227             uint32_t cc, w;
1228              
1229 0           cc = 0;
1230 0 0         for (i = 0; i < 20; i ++) {
1231 0           w = MUL15(a[i], 121665) + cc;
1232 0           d[i] = w & 0x1FFF;
1233 0           cc = w >> 13;
1234             }
1235 0           cc = MUL15(w >> 8, 19);
1236 0           d[19] &= 0xFF;
1237 0 0         for (i = 0; i < 20; i ++) {
1238 0           w = d[i] + cc;
1239 0           d[i] = w & 0x1FFF;
1240 0           cc = w >> 13;
1241             }
1242 0           }
1243              
1244             static const unsigned char GEN[] = {
1245             0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1246             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1247             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1249             };
1250              
1251             static const unsigned char ORDER[] = {
1252             0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1253             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1254             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1255             0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1256             };
1257              
1258             static const unsigned char *
1259 0           api_generator(int curve, size_t *len)
1260             {
1261             (void)curve;
1262 0           *len = 32;
1263 0           return GEN;
1264             }
1265              
1266             static const unsigned char *
1267 0           api_order(int curve, size_t *len)
1268             {
1269             (void)curve;
1270 0           *len = 32;
1271 0           return ORDER;
1272             }
1273              
1274             static size_t
1275 0           api_xoff(int curve, size_t *len)
1276             {
1277             (void)curve;
1278 0           *len = 32;
1279 0           return 0;
1280             }
1281              
1282             static void
1283 0           cswap(uint32_t *a, uint32_t *b, uint32_t ctl)
1284             {
1285             int i;
1286              
1287 0           ctl = -ctl;
1288 0 0         for (i = 0; i < 20; i ++) {
1289             uint32_t aw, bw, tw;
1290              
1291 0           aw = a[i];
1292 0           bw = b[i];
1293 0           tw = ctl & (aw ^ bw);
1294 0           a[i] = aw ^ tw;
1295 0           b[i] = bw ^ tw;
1296             }
1297 0           }
1298              
1299             static uint32_t
1300 0           api_mul(unsigned char *G, size_t Glen,
1301             const unsigned char *kb, size_t kblen, int curve)
1302             {
1303             uint32_t x1[20], x2[20], x3[20], z2[20], z3[20];
1304             uint32_t a[20], aa[20], b[20], bb[20];
1305             uint32_t c[20], d[20], e[20], da[20], cb[20];
1306             unsigned char k[32];
1307             uint32_t swap;
1308             int i;
1309              
1310             (void)curve;
1311              
1312             /*
1313             * Points are encoded over exactly 32 bytes. Multipliers must fit
1314             * in 32 bytes as well.
1315             * RFC 7748 mandates that the high bit of the last point byte must
1316             * be ignored/cleared.
1317             */
1318 0 0         if (Glen != 32 || kblen > 32) {
    0          
1319 0           return 0;
1320             }
1321 0           G[31] &= 0x7F;
1322              
1323             /*
1324             * Initialise variables x1, x2, z2, x3 and z3. We set all of them
1325             * into Montgomery representation.
1326             */
1327 0           x1[19] = le8_to_le13(x1, G, 32);
1328 0           memcpy(x3, x1, sizeof x1);
1329 0           memset(z2, 0, sizeof z2);
1330 0           memset(x2, 0, sizeof x2);
1331 0           x2[0] = 1;
1332 0           memset(z3, 0, sizeof z3);
1333 0           z3[0] = 1;
1334              
1335 0           memset(k, 0, (sizeof k) - kblen);
1336 0           memcpy(k + (sizeof k) - kblen, kb, kblen);
1337 0           k[31] &= 0xF8;
1338 0           k[0] &= 0x7F;
1339 0           k[0] |= 0x40;
1340              
1341             /* obsolete
1342             print_int("x1", x1);
1343             */
1344              
1345 0           swap = 0;
1346 0 0         for (i = 254; i >= 0; i --) {
1347             uint32_t kt;
1348              
1349 0           kt = (k[31 - (i >> 3)] >> (i & 7)) & 1;
1350 0           swap ^= kt;
1351 0           cswap(x2, x3, swap);
1352 0           cswap(z2, z3, swap);
1353 0           swap = kt;
1354              
1355             /* obsolete
1356             print_int("x2", x2);
1357             print_int("z2", z2);
1358             print_int("x3", x3);
1359             print_int("z3", z3);
1360             */
1361              
1362 0           f255_add(a, x2, z2);
1363 0           f255_square(aa, a);
1364 0           f255_sub(b, x2, z2);
1365 0           f255_square(bb, b);
1366 0           f255_sub(e, aa, bb);
1367 0           f255_add(c, x3, z3);
1368 0           f255_sub(d, x3, z3);
1369 0           f255_mul(da, d, a);
1370 0           f255_mul(cb, c, b);
1371              
1372             /* obsolete
1373             print_int("a ", a);
1374             print_int("aa", aa);
1375             print_int("b ", b);
1376             print_int("bb", bb);
1377             print_int("e ", e);
1378             print_int("c ", c);
1379             print_int("d ", d);
1380             print_int("da", da);
1381             print_int("cb", cb);
1382             */
1383              
1384 0           f255_add(x3, da, cb);
1385 0           f255_square(x3, x3);
1386 0           f255_sub(z3, da, cb);
1387 0           f255_square(z3, z3);
1388 0           f255_mul(z3, z3, x1);
1389 0           f255_mul(x2, aa, bb);
1390 0           f255_mul_a24(z2, e);
1391 0           f255_add(z2, z2, aa);
1392 0           f255_mul(z2, e, z2);
1393              
1394             /* obsolete
1395             print_int("x2", x2);
1396             print_int("z2", z2);
1397             print_int("x3", x3);
1398             print_int("z3", z3);
1399             */
1400             }
1401 0           cswap(x2, x3, swap);
1402 0           cswap(z2, z3, swap);
1403              
1404             /*
1405             * Inverse z2 with a modular exponentiation. This is a simple
1406             * square-and-multiply algorithm; we mutualise most non-squarings
1407             * since the exponent contains almost only ones.
1408             */
1409 0           memcpy(a, z2, sizeof z2);
1410 0 0         for (i = 0; i < 15; i ++) {
1411 0           f255_square(a, a);
1412 0           f255_mul(a, a, z2);
1413             }
1414 0           memcpy(b, a, sizeof a);
1415 0 0         for (i = 0; i < 14; i ++) {
1416             int j;
1417              
1418 0 0         for (j = 0; j < 16; j ++) {
1419 0           f255_square(b, b);
1420             }
1421 0           f255_mul(b, b, a);
1422             }
1423 0 0         for (i = 14; i >= 0; i --) {
1424 0           f255_square(b, b);
1425 0 0         if ((0xFFEB >> i) & 1) {
1426 0           f255_mul(b, z2, b);
1427             }
1428             }
1429 0           f255_mul(x2, x2, b);
1430 0           reduce_final_f255(x2);
1431 0           le13_to_le8(G, 32, x2);
1432 0           return 1;
1433             }
1434              
1435             static size_t
1436 0           api_mulgen(unsigned char *R,
1437             const unsigned char *x, size_t xlen, int curve)
1438             {
1439             const unsigned char *G;
1440             size_t Glen;
1441              
1442 0           G = api_generator(curve, &Glen);
1443 0           memcpy(R, G, Glen);
1444 0           api_mul(R, Glen, x, xlen, curve);
1445 0           return Glen;
1446             }
1447              
1448             static uint32_t
1449 0           api_muladd(unsigned char *A, const unsigned char *B, size_t len,
1450             const unsigned char *x, size_t xlen,
1451             const unsigned char *y, size_t ylen, int curve)
1452             {
1453             /*
1454             * We don't implement this method, since it is used for ECDSA
1455             * only, and there is no ECDSA over Curve25519 (which instead
1456             * uses EdDSA).
1457             */
1458             (void)A;
1459             (void)B;
1460             (void)len;
1461             (void)x;
1462             (void)xlen;
1463             (void)y;
1464             (void)ylen;
1465             (void)curve;
1466 0           return 0;
1467             }
1468              
1469             /* see bearssl_ec.h */
1470             const br_ec_impl br_ec_c25519_m15 = {
1471             (uint32_t)0x20000000,
1472             &api_generator,
1473             &api_order,
1474             &api_xoff,
1475             &api_mul,
1476             &api_mulgen,
1477             &api_muladd
1478             };