OpenCoverage

curve448.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/ec/curve448/curve448.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.-
3 * Copyright 2015-2016 Cryptography Research, Inc.-
4 *-
5 * Licensed under the OpenSSL license (the "License"). You may not use-
6 * this file except in compliance with the License. You can obtain a copy-
7 * in the file LICENSE in the source distribution or at-
8 * https://www.openssl.org/source/license.html-
9 *-
10 * Originally written by Mike Hamburg-
11 */-
12#include <openssl/crypto.h>-
13#include "word.h"-
14#include "field.h"-
15-
16#include "point_448.h"-
17#include "ed448.h"-
18#include "curve448_lcl.h"-
19-
20#define COFACTOR 4-
21-
22#define C448_WNAF_FIXED_TABLE_BITS 5-
23#define C448_WNAF_VAR_TABLE_BITS 3-
24-
25#define EDWARDS_D (-39081)-
26-
27static const curve448_scalar_t precomputed_scalarmul_adjustment = {-
28 {-
29 {-
30 SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad),-
31 SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163)-
32 }-
33 }-
34};-
35-
36#define TWISTED_D (EDWARDS_D - 1)-
37-
38#define WBITS C448_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */-
39-
40/* Inverse. */-
41static void gf_invert(gf y, const gf x, int assert_nonzero)-
42{-
43 mask_t ret;-
44 gf t1, t2;-
45-
46 gf_sqr(t1, x); /* o^2 */-
47 ret = gf_isr(t2, t1); /* +-1/sqrt(o^2) = +-1/o */-
48 (void)ret;-
49 if (assert_nonzero)
assert_nonzeroDescription
TRUEevaluated 63 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 1073 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
63-1073
50 assert(ret);
executed 63 times by 2 tests: ((void) (0)) ;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
63
51 gf_sqr(t1, t2);-
52 gf_mul(t2, t1, x); /* not direct to y in case of alias. */-
53 gf_copy(y, t2);-
54}
executed 1136 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
1136
55-
56/** identity = (0,1) */-
57const curve448_point_t curve448_point_identity =-
58 { {{{{0}}}, {{{1}}}, {{{1}}}, {{{0}}}} };-
59-
60static void point_double_internal(curve448_point_t p, const curve448_point_t q,-
61 int before_double)-
62{-
63 gf a, b, c, d;-
64-
65 gf_sqr(c, q->x);-
66 gf_sqr(a, q->y);-
67 gf_add_nr(d, c, a); /* 2+e */-
68 gf_add_nr(p->t, q->y, q->x); /* 2+e */-
69 gf_sqr(b, p->t);-
70 gf_subx_nr(b, b, d, 3); /* 4+e */-
71 gf_sub_nr(p->t, a, c); /* 3+e */-
72 gf_sqr(p->x, q->z);-
73 gf_add_nr(p->z, p->x, p->x); /* 2+e */-
74 gf_subx_nr(a, p->z, p->t, 4); /* 6+e */-
75 if (GF_HEADROOM == 5)
2 == 5Description
TRUEnever evaluated
FALSEevaluated 6091 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
0-6091
76 gf_weak_reduce(a); /* or 1+e */
never executed: gf_weak_reduce(a);
0
77 gf_mul(p->x, a, b);-
78 gf_mul(p->z, p->t, a);-
79 gf_mul(p->y, p->t, d);-
80 if (!before_double)
!before_doubleDescription
TRUEevaluated 3161 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 2930 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
2930-3161
81 gf_mul(p->t, b, d);
executed 3161 times by 2 tests: gf_mul(p->t, b, d);
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
3161
82}
executed 6091 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
6091
83-
84void curve448_point_double(curve448_point_t p, const curve448_point_t q)-
85{-
86 point_double_internal(p, q, 0);-
87}
executed 9 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
9
88-
89/* Operations on [p]niels */-
90static ossl_inline void cond_neg_niels(niels_t n, mask_t neg)-
91{-
92 gf_cond_swap(n->a, n->b, neg);-
93 gf_cond_neg(n->c, neg);-
94}
executed 10980 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
10980
95-
96static void pt_to_pniels(pniels_t b, const curve448_point_t a)-
97{-
98 gf_sub(b->n->a, a->y, a->x);-
99 gf_add(b->n->b, a->x, a->y);-
100 gf_mulw(b->n->c, a->t, 2 * TWISTED_D);-
101 gf_add(b->z, a->z, a->z);-
102}
executed 81 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
81
103-
104static void pniels_to_pt(curve448_point_t e, const pniels_t d)-
105{-
106 gf eu;-
107-
108 gf_add(eu, d->n->b, d->n->a);-
109 gf_sub(e->y, d->n->b, d->n->a);-
110 gf_mul(e->t, e->y, eu);-
111 gf_mul(e->x, d->z, e->y);-
112 gf_mul(e->y, d->z, eu);-
113 gf_sqr(e->z, d->z);-
114}
executed 6 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
6
115-
116static void niels_to_pt(curve448_point_t e, const niels_t n)-
117{-
118 gf_add(e->y, n->b, n->a);-
119 gf_sub(e->x, n->b, n->a);-
120 gf_mul(e->t, e->y, e->x);-
121 gf_copy(e->z, ONE);-
122}
executed 125 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
125
123-
124static void add_niels_to_pt(curve448_point_t d, const niels_t e,-
125 int before_double)-
126{-
127 gf a, b, c;-
128-
129 gf_sub_nr(b, d->y, d->x); /* 3+e */-
130 gf_mul(a, e->a, b);-
131 gf_add_nr(b, d->x, d->y); /* 2+e */-
132 gf_mul(d->y, e->b, b);-
133 gf_mul(d->x, e->c, d->t);-
134 gf_add_nr(c, a, d->y); /* 2+e */-
135 gf_sub_nr(b, d->y, a); /* 3+e */-
136 gf_sub_nr(d->y, d->z, d->x); /* 3+e */-
137 gf_add_nr(a, d->x, d->z); /* 2+e */-
138 gf_mul(d->z, a, d->y);-
139 gf_mul(d->x, d->y, b);-
140 gf_mul(d->y, a, c);-
141 if (!before_double)
!before_doubleDescription
TRUEevaluated 8899 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 2619 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
2619-8899
142 gf_mul(d->t, b, c);
executed 8899 times by 2 tests: gf_mul(d->t, b, c);
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
8899
143}
executed 11518 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
11518
144-
145static void sub_niels_from_pt(curve448_point_t d, const niels_t e,-
146 int before_double)-
147{-
148 gf a, b, c;-
149-
150 gf_sub_nr(b, d->y, d->x); /* 3+e */-
151 gf_mul(a, e->b, b);-
152 gf_add_nr(b, d->x, d->y); /* 2+e */-
153 gf_mul(d->y, e->a, b);-
154 gf_mul(d->x, e->c, d->t);-
155 gf_add_nr(c, a, d->y); /* 2+e */-
156 gf_sub_nr(b, d->y, a); /* 3+e */-
157 gf_add_nr(d->y, d->z, d->x); /* 2+e */-
158 gf_sub_nr(a, d->z, d->x); /* 3+e */-
159 gf_mul(d->z, a, d->y);-
160 gf_mul(d->x, d->y, b);-
161 gf_mul(d->y, a, c);-
162 if (!before_double)
!before_doubleDescription
TRUEevaluated 54 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 525 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
54-525
163 gf_mul(d->t, b, c);
executed 54 times by 1 test: gf_mul(d->t, b, c);
Executed by:
  • libcrypto.so.1.1
54
164}
executed 579 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
579
165-
166static void add_pniels_to_pt(curve448_point_t p, const pniels_t pn,-
167 int before_double)-
168{-
169 gf L0;-
170-
171 gf_mul(L0, p->z, pn->z);-
172 gf_copy(p->z, L0);-
173 add_niels_to_pt(p, pn->n, before_double);-
174}
executed 379 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
379
175-
176static void sub_pniels_from_pt(curve448_point_t p, const pniels_t pn,-
177 int before_double)-
178{-
179 gf L0;-
180-
181 gf_mul(L0, p->z, pn->z);-
182 gf_copy(p->z, L0);-
183 sub_niels_from_pt(p, pn->n, before_double);-
184}
executed 350 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
350
185-
186c448_bool_t curve448_point_eq(const curve448_point_t p,-
187 const curve448_point_t q)-
188{-
189 mask_t succ;-
190 gf a, b;-
191-
192 /* equality mod 2-torsion compares x/y */-
193 gf_mul(a, p->y, q->x);-
194 gf_mul(b, q->y, p->x);-
195 succ = gf_eq(a, b);-
196-
197 return mask_to_bool(succ);
executed 9 times by 1 test: return mask_to_bool(succ);
Executed by:
  • libcrypto.so.1.1
9
198}-
199-
200c448_bool_t curve448_point_valid(const curve448_point_t p)-
201{-
202 mask_t out;-
203 gf a, b, c;-
204-
205 gf_mul(a, p->x, p->y);-
206 gf_mul(b, p->z, p->t);-
207 out = gf_eq(a, b);-
208 gf_sqr(a, p->x);-
209 gf_sqr(b, p->y);-
210 gf_sub(a, b, a);-
211 gf_sqr(b, p->t);-
212 gf_mulw(c, b, TWISTED_D);-
213 gf_sqr(b, p->z);-
214 gf_add(b, b, c);-
215 out &= gf_eq(a, b);-
216 out &= ~gf_eq(p->z, ZERO);-
217 return mask_to_bool(out);
never executed: return mask_to_bool(out);
0
218}-
219-
220static ossl_inline void constant_time_lookup_niels(niels_s * RESTRICT ni,-
221 const niels_t * table,-
222 int nelts, int idx)-
223{-
224 constant_time_lookup(ni, table, sizeof(niels_s), nelts, idx);-
225}
executed 10980 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
10980
226-
227void curve448_precomputed_scalarmul(curve448_point_t out,-
228 const curve448_precomputed_s * table,-
229 const curve448_scalar_t scalar)-
230{-
231 unsigned int i, j, k;-
232 const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S;-
233 niels_t ni;-
234 curve448_scalar_t scalar1x;-
235-
236 curve448_scalar_add(scalar1x, scalar, precomputed_scalarmul_adjustment);-
237 curve448_scalar_halve(scalar1x, scalar1x);-
238-
239 for (i = s; i > 0; i--) {
i > 0Description
TRUEevaluated 2196 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 122 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
122-2196
240 if (i != s)
i != sDescription
TRUEevaluated 2074 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 122 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
122-2074
241 point_double_internal(out, out, 0);
executed 2074 times by 2 tests: point_double_internal(out, out, 0);
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
2074
242-
243 for (j = 0; j < n; j++) {
j < nDescription
TRUEevaluated 10980 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 2196 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
2196-10980
244 int tab = 0;-
245 mask_t invert;-
246-
247 for (k = 0; k < t; k++) {
k < tDescription
TRUEevaluated 54900 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 10980 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
10980-54900
248 unsigned int bit = (i - 1) + s * (k + j * t);-
249-
250 if (bit < C448_SCALAR_BITS)
bit < 446Description
TRUEevaluated 54412 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 488 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
488-54412
251 tab |=
executed 54412 times by 2 tests: tab |= (scalar1x->limb[bit / 64] >> (bit % 64) & 1) << k;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
54412
252 (scalar1x->limb[bit / WBITS] >> (bit % WBITS) & 1) << k;
executed 54412 times by 2 tests: tab |= (scalar1x->limb[bit / 64] >> (bit % 64) & 1) << k;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
54412
253 }
executed 54900 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
54900
254-
255 invert = (tab >> (t - 1)) - 1;-
256 tab ^= invert;-
257 tab &= (1 << (t - 1)) - 1;-
258-
259 constant_time_lookup_niels(ni, &table->table[j << (t - 1)],-
260 1 << (t - 1), tab);-
261-
262 cond_neg_niels(ni, invert);-
263 if ((i != s) || j != 0)
(i != s)Description
TRUEevaluated 10370 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 610 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
j != 0Description
TRUEevaluated 488 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 122 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
122-10370
264 add_niels_to_pt(out, ni, j == n - 1 && i != 1);
executed 10858 times by 2 tests: add_niels_to_pt(out, ni, j == n - 1 && i != 1);
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
10858
265 else-
266 niels_to_pt(out, ni);
executed 122 times by 2 tests: niels_to_pt(out, ni);
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
122
267 }-
268 }
executed 2196 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
2196
269-
270 OPENSSL_cleanse(ni, sizeof(ni));-
271 OPENSSL_cleanse(scalar1x, sizeof(scalar1x));-
272}
executed 122 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
122
273-
274void curve448_point_mul_by_ratio_and_encode_like_eddsa(-
275 uint8_t enc[EDDSA_448_PUBLIC_BYTES],-
276 const curve448_point_t p)-
277{-
278 gf x, y, z, t;-
279 curve448_point_t q;-
280-
281 /* The point is now on the twisted curve. Move it to untwisted. */-
282 curve448_point_copy(q, p);-
283-
284 {-
285 /* 4-isogeny: 2xy/(y^+x^2), (y^2-x^2)/(2z^2-y^2+x^2) */-
286 gf u;-
287-
288 gf_sqr(x, q->x);-
289 gf_sqr(t, q->y);-
290 gf_add(u, x, t);-
291 gf_add(z, q->y, q->x);-
292 gf_sqr(y, z);-
293 gf_sub(y, y, u);-
294 gf_sub(z, t, x);-
295 gf_sqr(x, q->z);-
296 gf_add(t, x, x);-
297 gf_sub(t, t, z);-
298 gf_mul(x, t, y);-
299 gf_mul(y, z, u);-
300 gf_mul(z, u, t);-
301 OPENSSL_cleanse(u, sizeof(u));-
302 }-
303-
304 /* Affinize */-
305 gf_invert(z, z, 1);-
306 gf_mul(t, x, z);-
307 gf_mul(x, y, z);-
308-
309 /* Encode */-
310 enc[EDDSA_448_PRIVATE_BYTES - 1] = 0;-
311 gf_serialize(enc, x, 1);-
312 enc[EDDSA_448_PRIVATE_BYTES - 1] |= 0x80 & gf_lobit(t);-
313-
314 OPENSSL_cleanse(x, sizeof(x));-
315 OPENSSL_cleanse(y, sizeof(y));-
316 OPENSSL_cleanse(z, sizeof(z));-
317 OPENSSL_cleanse(t, sizeof(t));-
318 curve448_point_destroy(q);-
319}
executed 63 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
63
320-
321c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio(-
322 curve448_point_t p,-
323 const uint8_t enc[EDDSA_448_PUBLIC_BYTES])-
324{-
325 uint8_t enc2[EDDSA_448_PUBLIC_BYTES];-
326 mask_t low;-
327 mask_t succ;-
328-
329 memcpy(enc2, enc, sizeof(enc2));-
330-
331 low = ~word_is_zero(enc2[EDDSA_448_PRIVATE_BYTES - 1] & 0x80);-
332 enc2[EDDSA_448_PRIVATE_BYTES - 1] &= ~0x80;-
333-
334 succ = gf_deserialize(p->y, enc2, 1, 0);-
335 succ &= word_is_zero(enc2[EDDSA_448_PRIVATE_BYTES - 1]);-
336-
337 gf_sqr(p->x, p->y);-
338 gf_sub(p->z, ONE, p->x); /* num = 1-y^2 */-
339 gf_mulw(p->t, p->x, EDWARDS_D); /* dy^2 */-
340 gf_sub(p->t, ONE, p->t); /* denom = 1-dy^2 or 1-d + dy^2 */-
341-
342 gf_mul(p->x, p->z, p->t);-
343 succ &= gf_isr(p->t, p->x); /* 1/sqrt(num * denom) */-
344-
345 gf_mul(p->x, p->t, p->z); /* sqrt(num / denom) */-
346 gf_cond_neg(p->x, gf_lobit(p->x) ^ low);-
347 gf_copy(p->z, ONE);-
348-
349 {-
350 gf a, b, c, d;-
351-
352 /* 4-isogeny 2xy/(y^2-ax^2), (y^2+ax^2)/(2-y^2-ax^2) */-
353 gf_sqr(c, p->x);-
354 gf_sqr(a, p->y);-
355 gf_add(d, c, a);-
356 gf_add(p->t, p->y, p->x);-
357 gf_sqr(b, p->t);-
358 gf_sub(b, b, d);-
359 gf_sub(p->t, a, c);-
360 gf_sqr(p->x, p->z);-
361 gf_add(p->z, p->x, p->x);-
362 gf_sub(a, p->z, d);-
363 gf_mul(p->x, a, b);-
364 gf_mul(p->z, p->t, a);-
365 gf_mul(p->y, p->t, d);-
366 gf_mul(p->t, b, d);-
367 OPENSSL_cleanse(a, sizeof(a));-
368 OPENSSL_cleanse(b, sizeof(b));-
369 OPENSSL_cleanse(c, sizeof(c));-
370 OPENSSL_cleanse(d, sizeof(d));-
371 }-
372-
373 OPENSSL_cleanse(enc2, sizeof(enc2));-
374 assert(curve448_point_valid(p) || ~succ);-
375-
376 return c448_succeed_if(mask_to_bool(succ));
executed 18 times by 1 test: return c448_succeed_if(mask_to_bool(succ));
Executed by:
  • libcrypto.so.1.1
18
377}-
378-
379c448_error_t x448_int(uint8_t out[X_PUBLIC_BYTES],-
380 const uint8_t base[X_PUBLIC_BYTES],-
381 const uint8_t scalar[X_PRIVATE_BYTES])-
382{-
383 gf x1, x2, z2, x3, z3, t1, t2;-
384 int t;-
385 mask_t swap = 0;-
386 mask_t nz;-
387-
388 (void)gf_deserialize(x1, base, 1, 0);-
389 gf_copy(x2, ONE);-
390 gf_copy(z2, ZERO);-
391 gf_copy(x3, x1);-
392 gf_copy(z3, ONE);-
393-
394 for (t = X_PRIVATE_BITS - 1; t >= 0; t--) {
t >= 0Description
TRUEevaluated 454272 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 1014 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
1014-454272
395 uint8_t sb = scalar[t / 8];-
396 mask_t k_t;-
397-
398 /* Scalar conditioning */-
399 if (t / 8 == 0)
t / 8 == 0Description
TRUEevaluated 8112 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 446160 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
8112-446160
400 sb &= -(uint8_t)COFACTOR;
executed 8112 times by 2 tests: sb &= -(uint8_t)4;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
8112
401 else if (t == X_PRIVATE_BITS - 1)
t == 448 - 1Description
TRUEevaluated 1014 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
FALSEevaluated 445146 times by 2 tests
Evaluated by:
  • curve448_internal_test
  • libcrypto.so.1.1
1014-445146
402 sb = -1;
executed 1014 times by 2 tests: sb = -1;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
1014
403-
404 k_t = (sb >> (t % 8)) & 1;-
405 k_t = 0 - k_t; /* set to all 0s or all 1s */-
406-
407 swap ^= k_t;-
408 gf_cond_swap(x2, x3, swap);-
409 gf_cond_swap(z2, z3, swap);-
410 swap = k_t;-
411-
412 /*-
413 * The "_nr" below skips coefficient reduction. In the following-
414 * comments, "2+e" is saying that the coefficients are at most 2+epsilon-
415 * times the reduction limit.-
416 */-
417 gf_add_nr(t1, x2, z2); /* A = x2 + z2 */ /* 2+e */-
418 gf_sub_nr(t2, x2, z2); /* B = x2 - z2 */ /* 3+e */-
419 gf_sub_nr(z2, x3, z3); /* D = x3 - z3 */ /* 3+e */-
420 gf_mul(x2, t1, z2); /* DA */-
421 gf_add_nr(z2, z3, x3); /* C = x3 + z3 */ /* 2+e */-
422 gf_mul(x3, t2, z2); /* CB */-
423 gf_sub_nr(z3, x2, x3); /* DA-CB */ /* 3+e */-
424 gf_sqr(z2, z3); /* (DA-CB)^2 */-
425 gf_mul(z3, x1, z2); /* z3 = x1(DA-CB)^2 */-
426 gf_add_nr(z2, x2, x3); /* (DA+CB) */ /* 2+e */-
427 gf_sqr(x3, z2); /* x3 = (DA+CB)^2 */-
428-
429 gf_sqr(z2, t1); /* AA = A^2 */-
430 gf_sqr(t1, t2); /* BB = B^2 */-
431 gf_mul(x2, z2, t1); /* x2 = AA*BB */-
432 gf_sub_nr(t2, z2, t1); /* E = AA-BB */ /* 3+e */-
433-
434 gf_mulw(t1, t2, -EDWARDS_D); /* E*-d = a24*E */-
435 gf_add_nr(t1, t1, z2); /* AA + a24*E */ /* 2+e */-
436 gf_mul(z2, t2, t1); /* z2 = E(AA+a24*E) */-
437 }
executed 454272 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
454272
438-
439 /* Finish */-
440 gf_cond_swap(x2, x3, swap);-
441 gf_cond_swap(z2, z3, swap);-
442 gf_invert(z2, z2, 0);-
443 gf_mul(x1, x2, z2);-
444 gf_serialize(out, x1, 1);-
445 nz = ~gf_eq(x1, ZERO);-
446-
447 OPENSSL_cleanse(x1, sizeof(x1));-
448 OPENSSL_cleanse(x2, sizeof(x2));-
449 OPENSSL_cleanse(z2, sizeof(z2));-
450 OPENSSL_cleanse(x3, sizeof(x3));-
451 OPENSSL_cleanse(z3, sizeof(z3));-
452 OPENSSL_cleanse(t1, sizeof(t1));-
453 OPENSSL_cleanse(t2, sizeof(t2));-
454-
455 return c448_succeed_if(mask_to_bool(nz));
executed 1014 times by 2 tests: return c448_succeed_if(mask_to_bool(nz));
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
1014
456}-
457-
458void curve448_point_mul_by_ratio_and_encode_like_x448(uint8_t-
459 out[X_PUBLIC_BYTES],-
460 const curve448_point_t p)-
461{-
462 curve448_point_t q;-
463-
464 curve448_point_copy(q, p);-
465 gf_invert(q->t, q->x, 0); /* 1/x */-
466 gf_mul(q->z, q->t, q->y); /* y/x */-
467 gf_sqr(q->y, q->z); /* (y/x)^2 */-
468 gf_serialize(out, q->y, 1);-
469 curve448_point_destroy(q);-
470}
executed 59 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
59
471-
472void x448_derive_public_key(uint8_t out[X_PUBLIC_BYTES],-
473 const uint8_t scalar[X_PRIVATE_BYTES])-
474{-
475 /* Scalar conditioning */-
476 uint8_t scalar2[X_PRIVATE_BYTES];-
477 curve448_scalar_t the_scalar;-
478 curve448_point_t p;-
479 unsigned int i;-
480-
481 memcpy(scalar2, scalar, sizeof(scalar2));-
482 scalar2[0] &= -(uint8_t)COFACTOR;-
483-
484 scalar2[X_PRIVATE_BYTES - 1] &= ~((0u - 1u) << ((X_PRIVATE_BITS + 7) % 8));-
485 scalar2[X_PRIVATE_BYTES - 1] |= 1 << ((X_PRIVATE_BITS + 7) % 8);-
486-
487 curve448_scalar_decode_long(the_scalar, scalar2, sizeof(scalar2));-
488-
489 /* Compensate for the encoding ratio */-
490 for (i = 1; i < X448_ENCODE_RATIO; i <<= 1)
i < 2Description
TRUEevaluated 59 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 59 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
59
491 curve448_scalar_halve(the_scalar, the_scalar);
executed 59 times by 1 test: curve448_scalar_halve(the_scalar, the_scalar);
Executed by:
  • libcrypto.so.1.1
59
492-
493 curve448_precomputed_scalarmul(p, curve448_precomputed_base, the_scalar);-
494 curve448_point_mul_by_ratio_and_encode_like_x448(out, p);-
495 curve448_point_destroy(p);-
496}
executed 59 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
59
497-
498/* Control for variable-time scalar multiply algorithms. */-
499struct smvt_control {-
500 int power, addend;-
501};-
502-
503#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3))-
504# define NUMTRAILINGZEROS __builtin_ctz-
505#else-
506# define NUMTRAILINGZEROS numtrailingzeros-
507static uint32_t numtrailingzeros(uint32_t i)-
508{-
509 uint32_t tmp;-
510 uint32_t num = 31;-
511-
512 if (i == 0)-
513 return 32;-
514-
515 tmp = i << 16;-
516 if (tmp != 0) {-
517 i = tmp;-
518 num -= 16;-
519 }-
520 tmp = i << 8;-
521 if (tmp != 0) {-
522 i = tmp;-
523 num -= 8;-
524 }-
525 tmp = i << 4;-
526 if (tmp != 0) {-
527 i = tmp;-
528 num -= 4;-
529 }-
530 tmp = i << 2;-
531 if (tmp != 0) {-
532 i = tmp;-
533 num -= 2;-
534 }-
535 tmp = i << 1;-
536 if (tmp != 0)-
537 num--;-
538-
539 return num;-
540}-
541#endif-
542-
543static int recode_wnaf(struct smvt_control *control,-
544 /* [nbits/(table_bits + 1) + 3] */-
545 const curve448_scalar_t scalar,-
546 unsigned int table_bits)-
547{-
548 unsigned int table_size = C448_SCALAR_BITS / (table_bits + 1) + 3;-
549 int position = table_size - 1; /* at the end */-
550 uint64_t current = scalar->limb[0] & 0xFFFF;-
551 uint32_t mask = (1 << (table_bits + 1)) - 1;-
552 unsigned int w;-
553 const unsigned int B_OVER_16 = sizeof(scalar->limb[0]) / 2;-
554 unsigned int n, i;-
555-
556 /* place the end marker */-
557 control[position].power = -1;-
558 control[position].addend = 0;-
559 position--;-
560-
561 /*-
562 * PERF: Could negate scalar if it's large. But then would need more cases-
563 * in the actual code that uses it, all for an expected reduction of like-
564 * 1/5 op. Probably not worth it.-
565 */-
566-
567 for (w = 1; w < (C448_SCALAR_BITS - 1) / 16 + 3; w++) {
w < (446 - 1) / 16 + 3Description
TRUEevaluated 522 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 18 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
18-522
568 if (w < (C448_SCALAR_BITS - 1) / 16 + 1) {
w < (446 - 1) / 16 + 1Description
TRUEevaluated 486 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 36 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
36-486
569 /* Refill the 16 high bits of current */-
570 current += (uint32_t)((scalar->limb[w / B_OVER_16]-
571 >> (16 * (w % B_OVER_16))) << 16);-
572 }
executed 486 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
486
573-
574 while (current & 0xFFFF) {
current & 0xFFFFDescription
TRUEevaluated 1185 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 522 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
522-1185
575 uint32_t pos = NUMTRAILINGZEROS((uint32_t)current);-
576 uint32_t odd = (uint32_t)current >> pos;-
577 int32_t delta = odd & mask;-
578-
579 assert(position >= 0);-
580 if (odd & (1 << (table_bits + 1)))
odd & (1 << (table_bits + 1))Description
TRUEevaluated 579 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 606 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
579-606
581 delta -= (1 << (table_bits + 1));
executed 579 times by 1 test: delta -= (1 << (table_bits + 1));
Executed by:
  • libcrypto.so.1.1
579
582 current -= delta * (1 << pos);-
583 control[position].power = pos + 16 * (w - 1);-
584 control[position].addend = delta;-
585 position--;-
586 }
executed 1185 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
1185
587 current >>= 16;-
588 }
executed 522 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
522
589 assert(current == 0);-
590-
591 position++;-
592 n = table_size - position;-
593 for (i = 0; i < n; i++)
i < nDescription
TRUEevaluated 1203 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 18 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
18-1203
594 control[i] = control[i + position];
executed 1203 times by 1 test: control[i] = control[i + position];
Executed by:
  • libcrypto.so.1.1
1203
595-
596 return n - 1;
executed 18 times by 1 test: return n - 1;
Executed by:
  • libcrypto.so.1.1
18
597}-
598-
599static void prepare_wnaf_table(pniels_t * output,-
600 const curve448_point_t working,-
601 unsigned int tbits)-
602{-
603 curve448_point_t tmp;-
604 int i;-
605 pniels_t twop;-
606-
607 pt_to_pniels(output[0], working);-
608-
609 if (tbits == 0)
tbits == 0Description
TRUEnever evaluated
FALSEevaluated 9 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-9
610 return;
never executed: return;
0
611-
612 curve448_point_double(tmp, working);-
613 pt_to_pniels(twop, tmp);-
614-
615 add_pniels_to_pt(tmp, output[0], 0);-
616 pt_to_pniels(output[1], tmp);-
617-
618 for (i = 2; i < 1 << tbits; i++) {
i < 1 << tbitsDescription
TRUEevaluated 54 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 9 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
9-54
619 add_pniels_to_pt(tmp, twop, 0);-
620 pt_to_pniels(output[i], tmp);-
621 }
executed 54 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
54
622-
623 curve448_point_destroy(tmp);-
624 OPENSSL_cleanse(twop, sizeof(twop));-
625}
executed 9 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
9
626-
627void curve448_base_double_scalarmul_non_secret(curve448_point_t combo,-
628 const curve448_scalar_t scalar1,-
629 const curve448_point_t base2,-
630 const curve448_scalar_t scalar2)-
631{-
632 const int table_bits_var = C448_WNAF_VAR_TABLE_BITS;-
633 const int table_bits_pre = C448_WNAF_FIXED_TABLE_BITS;-
634 struct smvt_control control_var[C448_SCALAR_BITS /-
635 (C448_WNAF_VAR_TABLE_BITS + 1) + 3];-
636 struct smvt_control control_pre[C448_SCALAR_BITS /-
637 (C448_WNAF_FIXED_TABLE_BITS + 1) + 3];-
638 int ncb_pre = recode_wnaf(control_pre, scalar1, table_bits_pre);-
639 int ncb_var = recode_wnaf(control_var, scalar2, table_bits_var);-
640 pniels_t precmp_var[1 << C448_WNAF_VAR_TABLE_BITS];-
641 int contp = 0, contv = 0, i;-
642-
643 prepare_wnaf_table(precmp_var, base2, table_bits_var);-
644 i = control_var[0].power;-
645-
646 if (i < 0) {
i < 0Description
TRUEnever evaluated
FALSEevaluated 9 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
0-9
647 curve448_point_copy(combo, curve448_point_identity);-
648 return;
never executed: return;
0
649 }-
650 if (i > control_pre[0].power) {
i > control_pre[0].powerDescription
TRUEevaluated 5 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 4 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
4-5
651 pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]);-
652 contv++;-
653 } else if (i == control_pre[0].power && i >= 0) {
executed 5 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
i == control_pre[0].powerDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 3 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
i >= 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEnever evaluated
0-5
654 pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]);-
655 add_niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1],-
656 i);-
657 contv++;-
658 contp++;-
659 } else {
executed 1 time by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
1
660 i = control_pre[0].power;-
661 niels_to_pt(combo, curve448_wnaf_base[control_pre[0].addend >> 1]);-
662 contp++;-
663 }
executed 3 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
3
664-
665 for (i--; i >= 0; i--) {
i >= 0Description
TRUEevaluated 4008 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 9 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
9-4008
666 int cv = (i == control_var[contv].power);-
667 int cp = (i == control_pre[contp].power);-
668-
669 point_double_internal(combo, combo, i && !(cv || cp));-
670-
671 if (cv) {
cvDescription
TRUEevaluated 666 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 3342 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
666-3342
672 assert(control_var[contv].addend);-
673-
674 if (control_var[contv].addend > 0)
control_var[contv].addend > 0Description
TRUEevaluated 316 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 350 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
316-350
675 add_pniels_to_pt(combo,
executed 316 times by 1 test: add_pniels_to_pt(combo, precmp_var[control_var[contv].addend >> 1], i && !cp);
Executed by:
  • libcrypto.so.1.1
316
676 precmp_var[control_var[contv].addend >> 1],
executed 316 times by 1 test: add_pniels_to_pt(combo, precmp_var[control_var[contv].addend >> 1], i && !cp);
Executed by:
  • libcrypto.so.1.1
316
677 i && !cp);
executed 316 times by 1 test: add_pniels_to_pt(combo, precmp_var[control_var[contv].addend >> 1], i && !cp);
Executed by:
  • libcrypto.so.1.1
316
678 else-
679 sub_pniels_from_pt(combo,
executed 350 times by 1 test: sub_pniels_from_pt(combo, precmp_var[(-control_var[contv].addend) >> 1], i && !cp);
Executed by:
  • libcrypto.so.1.1
350
680 precmp_var[(-control_var[contv].addend)
executed 350 times by 1 test: sub_pniels_from_pt(combo, precmp_var[(-control_var[contv].addend) >> 1], i && !cp);
Executed by:
  • libcrypto.so.1.1
350
681 >> 1], i && !cp);
executed 350 times by 1 test: sub_pniels_from_pt(combo, precmp_var[(-control_var[contv].addend) >> 1], i && !cp);
Executed by:
  • libcrypto.so.1.1
350
682 contv++;-
683 }
executed 666 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
666
684-
685 if (cp) {
cpDescription
TRUEevaluated 509 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 3499 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
509-3499
686 assert(control_pre[contp].addend);-
687-
688 if (control_pre[contp].addend > 0)
control_pre[contp].addend > 0Description
TRUEevaluated 280 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
FALSEevaluated 229 times by 1 test
Evaluated by:
  • libcrypto.so.1.1
229-280
689 add_niels_to_pt(combo,
executed 280 times by 1 test: add_niels_to_pt(combo, curve448_wnaf_base[control_pre[contp].addend >> 1], i);
Executed by:
  • libcrypto.so.1.1
280
690 curve448_wnaf_base[control_pre[contp].addend
executed 280 times by 1 test: add_niels_to_pt(combo, curve448_wnaf_base[control_pre[contp].addend >> 1], i);
Executed by:
  • libcrypto.so.1.1
280
691 >> 1], i);
executed 280 times by 1 test: add_niels_to_pt(combo, curve448_wnaf_base[control_pre[contp].addend >> 1], i);
Executed by:
  • libcrypto.so.1.1
280
692 else-
693 sub_niels_from_pt(combo,
executed 229 times by 1 test: sub_niels_from_pt(combo, curve448_wnaf_base[(-control_pre [contp].addend) >> 1], i);
Executed by:
  • libcrypto.so.1.1
229
694 curve448_wnaf_base[(-control_pre
executed 229 times by 1 test: sub_niels_from_pt(combo, curve448_wnaf_base[(-control_pre [contp].addend) >> 1], i);
Executed by:
  • libcrypto.so.1.1
229
695 [contp].addend) >> 1], i);
executed 229 times by 1 test: sub_niels_from_pt(combo, curve448_wnaf_base[(-control_pre [contp].addend) >> 1], i);
Executed by:
  • libcrypto.so.1.1
229
696 contp++;-
697 }
executed 509 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
509
698 }
executed 4008 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
4008
699-
700 /* This function is non-secret, but whatever this is cheap. */-
701 OPENSSL_cleanse(control_var, sizeof(control_var));-
702 OPENSSL_cleanse(control_pre, sizeof(control_pre));-
703 OPENSSL_cleanse(precmp_var, sizeof(precmp_var));-
704-
705 assert(contv == ncb_var);-
706 (void)ncb_var;-
707 assert(contp == ncb_pre);-
708 (void)ncb_pre;-
709}
executed 9 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
9
710-
711void curve448_point_destroy(curve448_point_t point)-
712{-
713 OPENSSL_cleanse(point, sizeof(curve448_point_t));-
714}
executed 253 times by 2 tests: end of block
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
253
715-
716int X448(uint8_t out_shared_key[56], const uint8_t private_key[56],-
717 const uint8_t peer_public_value[56])-
718{-
719 return x448_int(out_shared_key, peer_public_value, private_key)
executed 1014 times by 2 tests: return x448_int(out_shared_key, peer_public_value, private_key) == C448_SUCCESS;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
1014
720 == C448_SUCCESS;
executed 1014 times by 2 tests: return x448_int(out_shared_key, peer_public_value, private_key) == C448_SUCCESS;
Executed by:
  • curve448_internal_test
  • libcrypto.so.1.1
1014
721}-
722-
723void X448_public_from_private(uint8_t out_public_value[56],-
724 const uint8_t private_key[56])-
725{-
726 x448_derive_public_key(out_public_value, private_key);-
727}
executed 59 times by 1 test: end of block
Executed by:
  • libcrypto.so.1.1
59
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2