File Coverage

src/ec/ec_prime_i31.c
Criterion Covered Total %
statement 0 158 0.0
branch 0 14 0.0
condition n/a
subroutine n/a
pod n/a
total 0 172 0.0


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2016 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             /*
28             * Parameters for supported curves (field modulus, and 'b' equation
29             * parameter; both values use the 'i31' format, and 'b' is in Montgomery
30             * representation).
31             */
32              
33             static const uint32_t P256_P[] = {
34             0x00000108,
35             0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x00000007,
36             0x00000000, 0x00000000, 0x00000040, 0x7FFFFF80,
37             0x000000FF
38             };
39              
40             static const uint32_t P256_R2[] = {
41             0x00000108,
42             0x00014000, 0x00018000, 0x00000000, 0x7FF40000,
43             0x7FEFFFFF, 0x7FF7FFFF, 0x7FAFFFFF, 0x005FFFFF,
44             0x00000000
45             };
46              
47             static const uint32_t P256_B[] = {
48             0x00000108,
49             0x6FEE1803, 0x6229C4BD, 0x21B139BE, 0x327150AA,
50             0x3567802E, 0x3F7212ED, 0x012E4355, 0x782DD38D,
51             0x0000000E
52             };
53              
54             static const uint32_t P384_P[] = {
55             0x0000018C,
56             0x7FFFFFFF, 0x00000001, 0x00000000, 0x7FFFFFF8,
57             0x7FFFFFEF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF,
58             0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF,
59             0x00000FFF
60             };
61              
62             static const uint32_t P384_R2[] = {
63             0x0000018C,
64             0x00000000, 0x00000080, 0x7FFFFE00, 0x000001FF,
65             0x00000800, 0x00000000, 0x7FFFE000, 0x00001FFF,
66             0x00008000, 0x00008000, 0x00000000, 0x00000000,
67             0x00000000
68             };
69              
70             static const uint32_t P384_B[] = {
71             0x0000018C,
72             0x6E666840, 0x070D0392, 0x5D810231, 0x7651D50C,
73             0x17E218D6, 0x1B192002, 0x44EFE441, 0x3A524E2B,
74             0x2719BA5F, 0x41F02209, 0x36C5643E, 0x5813EFFE,
75             0x000008A5
76             };
77              
78             static const uint32_t P521_P[] = {
79             0x00000219,
80             0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF,
81             0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF,
82             0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF,
83             0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF,
84             0x01FFFFFF
85             };
86              
87             static const uint32_t P521_R2[] = {
88             0x00000219,
89             0x00001000, 0x00000000, 0x00000000, 0x00000000,
90             0x00000000, 0x00000000, 0x00000000, 0x00000000,
91             0x00000000, 0x00000000, 0x00000000, 0x00000000,
92             0x00000000, 0x00000000, 0x00000000, 0x00000000,
93             0x00000000
94             };
95              
96             static const uint32_t P521_B[] = {
97             0x00000219,
98             0x540FC00A, 0x228FEA35, 0x2C34F1EF, 0x67BF107A,
99             0x46FC1CD5, 0x1605E9DD, 0x6937B165, 0x272A3D8F,
100             0x42785586, 0x44C8C778, 0x15F3B8B4, 0x64B73366,
101             0x03BA8B69, 0x0D05B42A, 0x21F929A2, 0x2C31C393,
102             0x00654FAE
103             };
104              
105             typedef struct {
106             const uint32_t *p;
107             const uint32_t *b;
108             const uint32_t *R2;
109             uint32_t p0i;
110             size_t point_len;
111             } curve_params;
112              
113             static inline const curve_params *
114 0           id_to_curve(int curve)
115             {
116             static const curve_params pp[] = {
117             { P256_P, P256_B, P256_R2, 0x00000001, 65 },
118             { P384_P, P384_B, P384_R2, 0x00000001, 97 },
119             { P521_P, P521_B, P521_R2, 0x00000001, 133 }
120             };
121              
122 0           return &pp[curve - BR_EC_secp256r1];
123             }
124              
125             #define I31_LEN ((BR_MAX_EC_SIZE + 61) / 31)
126              
127             /*
128             * Type for a point in Jacobian coordinates:
129             * -- three values, x, y and z, in Montgomery representation
130             * -- affine coordinates are X = x / z^2 and Y = y / z^3
131             * -- for the point at infinity, z = 0
132             */
133             typedef struct {
134             uint32_t c[3][I31_LEN];
135             } jacobian;
136              
137             /*
138             * We use a custom interpreter that uses a dozen registers, and
139             * only six operations:
140             * MSET(d, a) copy a into d
141             * MADD(d, a) d = d+a (modular)
142             * MSUB(d, a) d = d-a (modular)
143             * MMUL(d, a, b) d = a*b (Montgomery multiplication)
144             * MINV(d, a, b) invert d modulo p; a and b are used as scratch registers
145             * MTZ(d) clear return value if d = 0
146             * Destination of MMUL (d) must be distinct from operands (a and b).
147             * There is no such constraint for MSUB and MADD.
148             *
149             * Registers include the operand coordinates, and temporaries.
150             */
151             #define MSET(d, a) (0x0000 + ((d) << 8) + ((a) << 4))
152             #define MADD(d, a) (0x1000 + ((d) << 8) + ((a) << 4))
153             #define MSUB(d, a) (0x2000 + ((d) << 8) + ((a) << 4))
154             #define MMUL(d, a, b) (0x3000 + ((d) << 8) + ((a) << 4) + (b))
155             #define MINV(d, a, b) (0x4000 + ((d) << 8) + ((a) << 4) + (b))
156             #define MTZ(d) (0x5000 + ((d) << 8))
157             #define ENDCODE 0
158              
159             /*
160             * Registers for the input operands.
161             */
162             #define P1x 0
163             #define P1y 1
164             #define P1z 2
165             #define P2x 3
166             #define P2y 4
167             #define P2z 5
168              
169             /*
170             * Alternate names for the first input operand.
171             */
172             #define Px 0
173             #define Py 1
174             #define Pz 2
175              
176             /*
177             * Temporaries.
178             */
179             #define t1 6
180             #define t2 7
181             #define t3 8
182             #define t4 9
183             #define t5 10
184             #define t6 11
185             #define t7 12
186              
187             /*
188             * Extra scratch registers available when there is no second operand (e.g.
189             * for "double" and "affine").
190             */
191             #define t8 3
192             #define t9 4
193             #define t10 5
194              
195             /*
196             * Doubling formulas are:
197             *
198             * s = 4*x*y^2
199             * m = 3*(x + z^2)*(x - z^2)
200             * x' = m^2 - 2*s
201             * y' = m*(s - x') - 8*y^4
202             * z' = 2*y*z
203             *
204             * If y = 0 (P has order 2) then this yields infinity (z' = 0), as it
205             * should. This case should not happen anyway, because our curves have
206             * prime order, and thus do not contain any point of order 2.
207             *
208             * If P is infinity (z = 0), then again the formulas yield infinity,
209             * which is correct. Thus, this code works for all points.
210             *
211             * Cost: 8 multiplications
212             */
213             static const uint16_t code_double[] = {
214             /*
215             * Compute z^2 (in t1).
216             */
217             MMUL(t1, Pz, Pz),
218              
219             /*
220             * Compute x-z^2 (in t2) and then x+z^2 (in t1).
221             */
222             MSET(t2, Px),
223             MSUB(t2, t1),
224             MADD(t1, Px),
225              
226             /*
227             * Compute m = 3*(x+z^2)*(x-z^2) (in t1).
228             */
229             MMUL(t3, t1, t2),
230             MSET(t1, t3),
231             MADD(t1, t3),
232             MADD(t1, t3),
233              
234             /*
235             * Compute s = 4*x*y^2 (in t2) and 2*y^2 (in t3).
236             */
237             MMUL(t3, Py, Py),
238             MADD(t3, t3),
239             MMUL(t2, Px, t3),
240             MADD(t2, t2),
241              
242             /*
243             * Compute x' = m^2 - 2*s.
244             */
245             MMUL(Px, t1, t1),
246             MSUB(Px, t2),
247             MSUB(Px, t2),
248              
249             /*
250             * Compute z' = 2*y*z.
251             */
252             MMUL(t4, Py, Pz),
253             MSET(Pz, t4),
254             MADD(Pz, t4),
255              
256             /*
257             * Compute y' = m*(s - x') - 8*y^4. Note that we already have
258             * 2*y^2 in t3.
259             */
260             MSUB(t2, Px),
261             MMUL(Py, t1, t2),
262             MMUL(t4, t3, t3),
263             MSUB(Py, t4),
264             MSUB(Py, t4),
265              
266             ENDCODE
267             };
268              
269             /*
270             * Addtions formulas are:
271             *
272             * u1 = x1 * z2^2
273             * u2 = x2 * z1^2
274             * s1 = y1 * z2^3
275             * s2 = y2 * z1^3
276             * h = u2 - u1
277             * r = s2 - s1
278             * x3 = r^2 - h^3 - 2 * u1 * h^2
279             * y3 = r * (u1 * h^2 - x3) - s1 * h^3
280             * z3 = h * z1 * z2
281             *
282             * If both P1 and P2 are infinity, then z1 == 0 and z2 == 0, implying that
283             * z3 == 0, so the result is correct.
284             * If either of P1 or P2 is infinity, but not both, then z3 == 0, which is
285             * not correct.
286             * h == 0 only if u1 == u2; this happens in two cases:
287             * -- if s1 == s2 then P1 and/or P2 is infinity, or P1 == P2
288             * -- if s1 != s2 then P1 + P2 == infinity (but neither P1 or P2 is infinity)
289             *
290             * Thus, the following situations are not handled correctly:
291             * -- P1 = 0 and P2 != 0
292             * -- P1 != 0 and P2 = 0
293             * -- P1 = P2
294             * All other cases are properly computed. However, even in "incorrect"
295             * situations, the three coordinates still are properly formed field
296             * elements.
297             *
298             * The returned flag is cleared if r == 0. This happens in the following
299             * cases:
300             * -- Both points are on the same horizontal line (same Y coordinate).
301             * -- Both points are infinity.
302             * -- One point is infinity and the other is on line Y = 0.
303             * The third case cannot happen with our curves (there is no valid point
304             * on line Y = 0 since that would be a point of order 2). If the two
305             * source points are non-infinity, then remains only the case where the
306             * two points are on the same horizontal line.
307             *
308             * This allows us to detect the "P1 == P2" case, assuming that P1 != 0 and
309             * P2 != 0:
310             * -- If the returned value is not the point at infinity, then it was properly
311             * computed.
312             * -- Otherwise, if the returned flag is 1, then P1+P2 = 0, and the result
313             * is indeed the point at infinity.
314             * -- Otherwise (result is infinity, flag is 0), then P1 = P2 and we should
315             * use the 'double' code.
316             *
317             * Cost: 16 multiplications
318             */
319             static const uint16_t code_add[] = {
320             /*
321             * Compute u1 = x1*z2^2 (in t1) and s1 = y1*z2^3 (in t3).
322             */
323             MMUL(t3, P2z, P2z),
324             MMUL(t1, P1x, t3),
325             MMUL(t4, P2z, t3),
326             MMUL(t3, P1y, t4),
327              
328             /*
329             * Compute u2 = x2*z1^2 (in t2) and s2 = y2*z1^3 (in t4).
330             */
331             MMUL(t4, P1z, P1z),
332             MMUL(t2, P2x, t4),
333             MMUL(t5, P1z, t4),
334             MMUL(t4, P2y, t5),
335              
336             /*
337             * Compute h = u2 - u1 (in t2) and r = s2 - s1 (in t4).
338             */
339             MSUB(t2, t1),
340             MSUB(t4, t3),
341              
342             /*
343             * Report cases where r = 0 through the returned flag.
344             */
345             MTZ(t4),
346              
347             /*
348             * Compute u1*h^2 (in t6) and h^3 (in t5).
349             */
350             MMUL(t7, t2, t2),
351             MMUL(t6, t1, t7),
352             MMUL(t5, t7, t2),
353              
354             /*
355             * Compute x3 = r^2 - h^3 - 2*u1*h^2.
356             * t1 and t7 can be used as scratch registers.
357             */
358             MMUL(P1x, t4, t4),
359             MSUB(P1x, t5),
360             MSUB(P1x, t6),
361             MSUB(P1x, t6),
362              
363             /*
364             * Compute y3 = r*(u1*h^2 - x3) - s1*h^3.
365             */
366             MSUB(t6, P1x),
367             MMUL(P1y, t4, t6),
368             MMUL(t1, t5, t3),
369             MSUB(P1y, t1),
370              
371             /*
372             * Compute z3 = h*z1*z2.
373             */
374             MMUL(t1, P1z, P2z),
375             MMUL(P1z, t1, t2),
376              
377             ENDCODE
378             };
379              
380             /*
381             * Check that the point is on the curve. This code snippet assumes the
382             * following conventions:
383             * -- Coordinates x and y have been freshly decoded in P1 (but not
384             * converted to Montgomery coordinates yet).
385             * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1.
386             */
387             static const uint16_t code_check[] = {
388              
389             /* Convert x and y to Montgomery representation. */
390             MMUL(t1, P1x, P2x),
391             MMUL(t2, P1y, P2x),
392             MSET(P1x, t1),
393             MSET(P1y, t2),
394              
395             /* Compute x^3 in t1. */
396             MMUL(t2, P1x, P1x),
397             MMUL(t1, P1x, t2),
398              
399             /* Subtract 3*x from t1. */
400             MSUB(t1, P1x),
401             MSUB(t1, P1x),
402             MSUB(t1, P1x),
403              
404             /* Add b. */
405             MADD(t1, P2y),
406              
407             /* Compute y^2 in t2. */
408             MMUL(t2, P1y, P1y),
409              
410             /* Compare y^2 with x^3 - 3*x + b; they must match. */
411             MSUB(t1, t2),
412             MTZ(t1),
413              
414             /* Set z to 1 (in Montgomery representation). */
415             MMUL(P1z, P2x, P2z),
416              
417             ENDCODE
418             };
419              
420             /*
421             * Conversion back to affine coordinates. This code snippet assumes that
422             * the z coordinate of P2 is set to 1 (not in Montgomery representation).
423             */
424             static const uint16_t code_affine[] = {
425              
426             /* Save z*R in t1. */
427             MSET(t1, P1z),
428              
429             /* Compute z^3 in t2. */
430             MMUL(t2, P1z, P1z),
431             MMUL(t3, P1z, t2),
432             MMUL(t2, t3, P2z),
433              
434             /* Invert to (1/z^3) in t2. */
435             MINV(t2, t3, t4),
436              
437             /* Compute y. */
438             MSET(t3, P1y),
439             MMUL(P1y, t2, t3),
440              
441             /* Compute (1/z^2) in t3. */
442             MMUL(t3, t2, t1),
443              
444             /* Compute x. */
445             MSET(t2, P1x),
446             MMUL(P1x, t2, t3),
447              
448             ENDCODE
449             };
450              
451             static uint32_t
452 0           run_code(jacobian *P1, const jacobian *P2,
453             const curve_params *cc, const uint16_t *code)
454             {
455             uint32_t r;
456             uint32_t t[13][I31_LEN];
457             size_t u;
458              
459 0           r = 1;
460              
461             /*
462             * Copy the two operands in the dedicated registers.
463             */
464 0           memcpy(t[P1x], P1->c, 3 * I31_LEN * sizeof(uint32_t));
465 0           memcpy(t[P2x], P2->c, 3 * I31_LEN * sizeof(uint32_t));
466              
467             /*
468             * Run formulas.
469             */
470 0           for (u = 0;; u ++) {
471             unsigned op, d, a, b;
472              
473 0           op = code[u];
474 0 0         if (op == 0) {
475 0           break;
476             }
477 0           d = (op >> 8) & 0x0F;
478 0           a = (op >> 4) & 0x0F;
479 0           b = op & 0x0F;
480 0           op >>= 12;
481 0           switch (op) {
482             uint32_t ctl;
483             size_t plen;
484             unsigned char tp[(BR_MAX_EC_SIZE + 7) >> 3];
485              
486 0           case 0:
487 0           memcpy(t[d], t[a], I31_LEN * sizeof(uint32_t));
488 0           break;
489 0           case 1:
490 0           ctl = br_i31_add(t[d], t[a], 1);
491 0           ctl |= NOT(br_i31_sub(t[d], cc->p, 0));
492 0           br_i31_sub(t[d], cc->p, ctl);
493 0           break;
494 0           case 2:
495 0           br_i31_add(t[d], cc->p, br_i31_sub(t[d], t[a], 1));
496 0           break;
497 0           case 3:
498 0           br_i31_montymul(t[d], t[a], t[b], cc->p, cc->p0i);
499 0           break;
500 0           case 4:
501 0           plen = (cc->p[0] - (cc->p[0] >> 5) + 7) >> 3;
502 0           br_i31_encode(tp, plen, cc->p);
503 0           tp[plen - 1] -= 2;
504 0           br_i31_modpow(t[d], tp, plen,
505 0           cc->p, cc->p0i, t[a], t[b]);
506 0           break;
507 0           default:
508 0           r &= ~br_i31_iszero(t[d]);
509 0           break;
510             }
511             }
512              
513             /*
514             * Copy back result.
515             */
516 0           memcpy(P1->c, t[P1x], 3 * I31_LEN * sizeof(uint32_t));
517 0           return r;
518             }
519              
520             static void
521 0           set_one(uint32_t *x, const uint32_t *p)
522             {
523             size_t plen;
524              
525 0           plen = (p[0] + 63) >> 5;
526 0           memset(x, 0, plen * sizeof *x);
527 0           x[0] = p[0];
528 0           x[1] = 0x00000001;
529 0           }
530              
531             static void
532 0           point_zero(jacobian *P, const curve_params *cc)
533             {
534 0           memset(P, 0, sizeof *P);
535 0           P->c[0][0] = P->c[1][0] = P->c[2][0] = cc->p[0];
536 0           }
537              
538             static inline void
539 0           point_double(jacobian *P, const curve_params *cc)
540             {
541 0           run_code(P, P, cc, code_double);
542 0           }
543              
544             static inline uint32_t
545 0           point_add(jacobian *P1, const jacobian *P2, const curve_params *cc)
546             {
547 0           return run_code(P1, P2, cc, code_add);
548             }
549              
550             static void
551 0           point_mul(jacobian *P, const unsigned char *x, size_t xlen,
552             const curve_params *cc)
553             {
554             /*
555             * We do a simple double-and-add ladder with a 2-bit window
556             * to make only one add every two doublings. We thus first
557             * precompute 2P and 3P in some local buffers.
558             *
559             * We always perform two doublings and one addition; the
560             * addition is with P, 2P and 3P and is done in a temporary
561             * array.
562             *
563             * The addition code cannot handle cases where one of the
564             * operands is infinity, which is the case at the start of the
565             * ladder. We therefore need to maintain a flag that controls
566             * this situation.
567             */
568             uint32_t qz;
569             jacobian P2, P3, Q, T, U;
570              
571 0           memcpy(&P2, P, sizeof P2);
572 0           point_double(&P2, cc);
573 0           memcpy(&P3, P, sizeof P3);
574 0           point_add(&P3, &P2, cc);
575              
576 0           point_zero(&Q, cc);
577 0           qz = 1;
578 0 0         while (xlen -- > 0) {
579             int k;
580              
581 0 0         for (k = 6; k >= 0; k -= 2) {
582             uint32_t bits;
583             uint32_t bnz;
584              
585 0           point_double(&Q, cc);
586 0           point_double(&Q, cc);
587 0           memcpy(&T, P, sizeof T);
588 0           memcpy(&U, &Q, sizeof U);
589 0           bits = (*x >> k) & (uint32_t)3;
590 0           bnz = NEQ(bits, 0);
591 0           CCOPY(EQ(bits, 2), &T, &P2, sizeof T);
592 0           CCOPY(EQ(bits, 3), &T, &P3, sizeof T);
593 0           point_add(&U, &T, cc);
594 0           CCOPY(bnz & qz, &Q, &T, sizeof Q);
595 0           CCOPY(bnz & ~qz, &Q, &U, sizeof Q);
596 0           qz &= ~bnz;
597             }
598 0           x ++;
599             }
600 0           memcpy(P, &Q, sizeof Q);
601 0           }
602              
603             /*
604             * Decode point into Jacobian coordinates. This function does not support
605             * the point at infinity. If the point is invalid then this returns 0, but
606             * the coordinates are still set to properly formed field elements.
607             */
608             static uint32_t
609 0           point_decode(jacobian *P, const void *src, size_t len, const curve_params *cc)
610             {
611             /*
612             * Points must use uncompressed format:
613             * -- first byte is 0x04;
614             * -- coordinates X and Y use unsigned big-endian, with the same
615             * length as the field modulus.
616             *
617             * We don't support hybrid format (uncompressed, but first byte
618             * has value 0x06 or 0x07, depending on the least significant bit
619             * of Y) because it is rather useless, and explicitly forbidden
620             * by PKIX (RFC 5480, section 2.2).
621             *
622             * We don't support compressed format either, because it is not
623             * much used in practice (there are or were patent-related
624             * concerns about point compression, which explains the lack of
625             * generalised support). Also, point compression support would
626             * need a bit more code.
627             */
628             const unsigned char *buf;
629             size_t plen, zlen;
630             uint32_t r;
631             jacobian Q;
632              
633 0           buf = src;
634 0           point_zero(P, cc);
635 0           plen = (cc->p[0] - (cc->p[0] >> 5) + 7) >> 3;
636 0 0         if (len != 1 + (plen << 1)) {
637 0           return 0;
638             }
639 0           r = br_i31_decode_mod(P->c[0], buf + 1, plen, cc->p);
640 0           r &= br_i31_decode_mod(P->c[1], buf + 1 + plen, plen, cc->p);
641              
642             /*
643             * Check first byte.
644             */
645 0           r &= EQ(buf[0], 0x04);
646             /* obsolete
647             r &= EQ(buf[0], 0x04) | (EQ(buf[0] & 0xFE, 0x06)
648             & ~(uint32_t)(buf[0] ^ buf[plen << 1]));
649             */
650              
651             /*
652             * Convert coordinates and check that the point is valid.
653             */
654 0           zlen = ((cc->p[0] + 63) >> 5) * sizeof(uint32_t);
655 0           memcpy(Q.c[0], cc->R2, zlen);
656 0           memcpy(Q.c[1], cc->b, zlen);
657 0           set_one(Q.c[2], cc->p);
658 0           r &= ~run_code(P, &Q, cc, code_check);
659 0           return r;
660             }
661              
662             /*
663             * Encode a point. This method assumes that the point is correct and is
664             * not the point at infinity. Encoded size is always 1+2*plen, where
665             * plen is the field modulus length, in bytes.
666             */
667             static void
668 0           point_encode(void *dst, const jacobian *P, const curve_params *cc)
669             {
670             unsigned char *buf;
671             uint32_t xbl;
672             size_t plen;
673             jacobian Q, T;
674              
675 0           buf = dst;
676 0           xbl = cc->p[0];
677 0           xbl -= (xbl >> 5);
678 0           plen = (xbl + 7) >> 3;
679 0           buf[0] = 0x04;
680 0           memcpy(&Q, P, sizeof *P);
681 0           set_one(T.c[2], cc->p);
682 0           run_code(&Q, &T, cc, code_affine);
683 0           br_i31_encode(buf + 1, plen, Q.c[0]);
684 0           br_i31_encode(buf + 1 + plen, plen, Q.c[1]);
685 0           }
686              
687             static const br_ec_curve_def *
688 0           id_to_curve_def(int curve)
689             {
690 0           switch (curve) {
691 0           case BR_EC_secp256r1:
692 0           return &br_secp256r1;
693 0           case BR_EC_secp384r1:
694 0           return &br_secp384r1;
695 0           case BR_EC_secp521r1:
696 0           return &br_secp521r1;
697             }
698 0           return NULL;
699             }
700              
701             static const unsigned char *
702 0           api_generator(int curve, size_t *len)
703             {
704             const br_ec_curve_def *cd;
705              
706 0           cd = id_to_curve_def(curve);
707 0           *len = cd->generator_len;
708 0           return cd->generator;
709             }
710              
711             static const unsigned char *
712 0           api_order(int curve, size_t *len)
713             {
714             const br_ec_curve_def *cd;
715              
716 0           cd = id_to_curve_def(curve);
717 0           *len = cd->order_len;
718 0           return cd->order;
719             }
720              
721             static size_t
722 0           api_xoff(int curve, size_t *len)
723             {
724 0           api_generator(curve, len);
725 0           *len >>= 1;
726 0           return 1;
727             }
728              
729             static uint32_t
730 0           api_mul(unsigned char *G, size_t Glen,
731             const unsigned char *x, size_t xlen, int curve)
732             {
733             uint32_t r;
734             const curve_params *cc;
735             jacobian P;
736              
737 0           cc = id_to_curve(curve);
738 0 0         if (Glen != cc->point_len) {
739 0           return 0;
740             }
741 0           r = point_decode(&P, G, Glen, cc);
742 0           point_mul(&P, x, xlen, cc);
743 0           point_encode(G, &P, cc);
744 0           return r;
745             }
746              
747             static size_t
748 0           api_mulgen(unsigned char *R,
749             const unsigned char *x, size_t xlen, int curve)
750             {
751             const unsigned char *G;
752             size_t Glen;
753              
754 0           G = api_generator(curve, &Glen);
755 0           memcpy(R, G, Glen);
756 0           api_mul(R, Glen, x, xlen, curve);
757 0           return Glen;
758             }
759              
760             static uint32_t
761 0           api_muladd(unsigned char *A, const unsigned char *B, size_t len,
762             const unsigned char *x, size_t xlen,
763             const unsigned char *y, size_t ylen, int curve)
764             {
765             uint32_t r, t, z;
766             const curve_params *cc;
767             jacobian P, Q;
768              
769             /*
770             * TODO: see about merging the two ladders. Right now, we do
771             * two independent point multiplications, which is a bit
772             * wasteful of CPU resources (but yields short code).
773             */
774              
775 0           cc = id_to_curve(curve);
776 0 0         if (len != cc->point_len) {
777 0           return 0;
778             }
779 0           r = point_decode(&P, A, len, cc);
780 0 0         if (B == NULL) {
781             size_t Glen;
782              
783 0           B = api_generator(curve, &Glen);
784             }
785 0           r &= point_decode(&Q, B, len, cc);
786 0           point_mul(&P, x, xlen, cc);
787 0           point_mul(&Q, y, ylen, cc);
788              
789             /*
790             * We want to compute P+Q. Since the base points A and B are distinct
791             * from infinity, and the multipliers are non-zero and lower than the
792             * curve order, then we know that P and Q are non-infinity. This
793             * leaves two special situations to test for:
794             * -- If P = Q then we must use point_double().
795             * -- If P+Q = 0 then we must report an error.
796             */
797 0           t = point_add(&P, &Q, cc);
798 0           point_double(&Q, cc);
799 0           z = br_i31_iszero(P.c[2]);
800              
801             /*
802             * If z is 1 then either P+Q = 0 (t = 1) or P = Q (t = 0). So we
803             * have the following:
804             *
805             * z = 0, t = 0 return P (normal addition)
806             * z = 0, t = 1 return P (normal addition)
807             * z = 1, t = 0 return Q (a 'double' case)
808             * z = 1, t = 1 report an error (P+Q = 0)
809             */
810 0           CCOPY(z & ~t, &P, &Q, sizeof Q);
811 0           point_encode(A, &P, cc);
812 0           r &= ~(z & t);
813              
814 0           return r;
815             }
816              
817             /* see bearssl_ec.h */
818             const br_ec_impl br_ec_prime_i31 = {
819             (uint32_t)0x03800000,
820             &api_generator,
821             &api_order,
822             &api_xoff,
823             &api_mul,
824             &api_mulgen,
825             &api_muladd
826             };