Coverage Report

Created: 2026-02-05 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/lib/freebl/verified/Hacl_P384.c
Line
Count
Source
1
/* MIT License
2
 *
3
 * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation
4
 * Copyright (c) 2022-2023 HACL* Contributors
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in all
14
 * copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 * SOFTWARE.
23
 */
24
25
#include "Hacl_P384.h"
26
27
#include "internal/Hacl_Krmllib.h"
28
#include "internal/Hacl_Bignum_Base.h"
29
30
static inline uint64_t
31
bn_is_eq_mask(uint64_t *x, uint64_t *y)
32
4.36k
{
33
4.36k
    uint64_t mask = 0xFFFFFFFFFFFFFFFFULL;
34
4.36k
    KRML_MAYBE_FOR6(i,
35
4.36k
                    0U,
36
4.36k
                    6U,
37
4.36k
                    1U,
38
4.36k
                    uint64_t uu____0 = FStar_UInt64_eq_mask(x[i], y[i]);
39
4.36k
                    mask = uu____0 & mask;);
40
4.36k
    uint64_t mask1 = mask;
41
4.36k
    return mask1;
42
4.36k
}
43
44
static inline void
45
bn_cmovznz(uint64_t *a, uint64_t b, uint64_t *c, uint64_t *d)
46
353
{
47
353
    uint64_t mask = ~FStar_UInt64_eq_mask(b, 0ULL);
48
353
    KRML_MAYBE_FOR6(i,
49
353
                    0U,
50
353
                    6U,
51
353
                    1U,
52
353
                    uint64_t *os = a;
53
353
                    uint64_t uu____0 = c[i];
54
353
                    uint64_t x = uu____0 ^ (mask & (d[i] ^ uu____0));
55
353
                    os[i] = x;);
56
353
}
57
58
static inline void
59
bn_add_mod(uint64_t *a, uint64_t *b, uint64_t *c, uint64_t *d)
60
12.6M
{
61
12.6M
    uint64_t c10 = 0ULL;
62
12.6M
    {
63
12.6M
        uint64_t t1 = c[4U * 0U];
64
12.6M
        uint64_t t20 = d[4U * 0U];
65
12.6M
        uint64_t *res_i0 = a + 4U * 0U;
66
12.6M
        c10 = Lib_IntTypes_Intrinsics_add_carry_u64(c10, t1, t20, res_i0);
67
12.6M
        uint64_t t10 = c[4U * 0U + 1U];
68
12.6M
        uint64_t t21 = d[4U * 0U + 1U];
69
12.6M
        uint64_t *res_i1 = a + 4U * 0U + 1U;
70
12.6M
        c10 = Lib_IntTypes_Intrinsics_add_carry_u64(c10, t10, t21, res_i1);
71
12.6M
        uint64_t t11 = c[4U * 0U + 2U];
72
12.6M
        uint64_t t22 = d[4U * 0U + 2U];
73
12.6M
        uint64_t *res_i2 = a + 4U * 0U + 2U;
74
12.6M
        c10 = Lib_IntTypes_Intrinsics_add_carry_u64(c10, t11, t22, res_i2);
75
12.6M
        uint64_t t12 = c[4U * 0U + 3U];
76
12.6M
        uint64_t t2 = d[4U * 0U + 3U];
77
12.6M
        uint64_t *res_i = a + 4U * 0U + 3U;
78
12.6M
        c10 = Lib_IntTypes_Intrinsics_add_carry_u64(c10, t12, t2, res_i);
79
12.6M
    }
80
12.6M
    KRML_MAYBE_FOR2(i,
81
12.6M
                    4U,
82
12.6M
                    6U,
83
12.6M
                    1U,
84
12.6M
                    uint64_t t1 = c[i];
85
12.6M
                    uint64_t t2 = d[i];
86
12.6M
                    uint64_t *res_i = a + i;
87
12.6M
                    c10 = Lib_IntTypes_Intrinsics_add_carry_u64(c10, t1, t2, res_i););
88
12.6M
    uint64_t c0 = c10;
89
12.6M
    uint64_t tmp[6U] = { 0U };
90
12.6M
    uint64_t c1 = 0ULL;
91
12.6M
    {
92
12.6M
        uint64_t t1 = a[4U * 0U];
93
12.6M
        uint64_t t20 = b[4U * 0U];
94
12.6M
        uint64_t *res_i0 = tmp + 4U * 0U;
95
12.6M
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t20, res_i0);
96
12.6M
        uint64_t t10 = a[4U * 0U + 1U];
97
12.6M
        uint64_t t21 = b[4U * 0U + 1U];
98
12.6M
        uint64_t *res_i1 = tmp + 4U * 0U + 1U;
99
12.6M
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t10, t21, res_i1);
100
12.6M
        uint64_t t11 = a[4U * 0U + 2U];
101
12.6M
        uint64_t t22 = b[4U * 0U + 2U];
102
12.6M
        uint64_t *res_i2 = tmp + 4U * 0U + 2U;
103
12.6M
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t11, t22, res_i2);
104
12.6M
        uint64_t t12 = a[4U * 0U + 3U];
105
12.6M
        uint64_t t2 = b[4U * 0U + 3U];
106
12.6M
        uint64_t *res_i = tmp + 4U * 0U + 3U;
107
12.6M
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t12, t2, res_i);
108
12.6M
    }
109
12.6M
    KRML_MAYBE_FOR2(i,
110
12.6M
                    4U,
111
12.6M
                    6U,
112
12.6M
                    1U,
113
12.6M
                    uint64_t t1 = a[i];
114
12.6M
                    uint64_t t2 = b[i];
115
12.6M
                    uint64_t *res_i = tmp + i;
116
12.6M
                    c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t2, res_i););
117
12.6M
    uint64_t c11 = c1;
118
12.6M
    uint64_t c2 = c0 - c11;
119
12.6M
    KRML_MAYBE_FOR6(i,
120
12.6M
                    0U,
121
12.6M
                    6U,
122
12.6M
                    1U,
123
12.6M
                    uint64_t *os = a;
124
12.6M
                    uint64_t x = (c2 & a[i]) | (~c2 & tmp[i]);
125
12.6M
                    os[i] = x;);
126
12.6M
}
127
128
static inline uint64_t
129
bn_sub(uint64_t *a, uint64_t *b, uint64_t *c)
130
6.17k
{
131
6.17k
    uint64_t c1 = 0ULL;
132
6.17k
    {
133
6.17k
        uint64_t t1 = b[4U * 0U];
134
6.17k
        uint64_t t20 = c[4U * 0U];
135
6.17k
        uint64_t *res_i0 = a + 4U * 0U;
136
6.17k
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t20, res_i0);
137
6.17k
        uint64_t t10 = b[4U * 0U + 1U];
138
6.17k
        uint64_t t21 = c[4U * 0U + 1U];
139
6.17k
        uint64_t *res_i1 = a + 4U * 0U + 1U;
140
6.17k
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t10, t21, res_i1);
141
6.17k
        uint64_t t11 = b[4U * 0U + 2U];
142
6.17k
        uint64_t t22 = c[4U * 0U + 2U];
143
6.17k
        uint64_t *res_i2 = a + 4U * 0U + 2U;
144
6.17k
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t11, t22, res_i2);
145
6.17k
        uint64_t t12 = b[4U * 0U + 3U];
146
6.17k
        uint64_t t2 = c[4U * 0U + 3U];
147
6.17k
        uint64_t *res_i = a + 4U * 0U + 3U;
148
6.17k
        c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t12, t2, res_i);
149
6.17k
    }
150
6.17k
    KRML_MAYBE_FOR2(i,
151
6.17k
                    4U,
152
6.17k
                    6U,
153
6.17k
                    1U,
154
6.17k
                    uint64_t t1 = b[i];
155
6.17k
                    uint64_t t2 = c[i];
156
6.17k
                    uint64_t *res_i = a + i;
157
6.17k
                    c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t2, res_i););
158
6.17k
    uint64_t c10 = c1;
159
6.17k
    return c10;
160
6.17k
}
161
162
static inline void
163
bn_sub_mod(uint64_t *a, uint64_t *b, uint64_t *c, uint64_t *d)
164
5.22M
{
165
5.22M
    uint64_t c10 = 0ULL;
166
5.22M
    {
167
5.22M
        uint64_t t1 = c[4U * 0U];
168
5.22M
        uint64_t t20 = d[4U * 0U];
169
5.22M
        uint64_t *res_i0 = a + 4U * 0U;
170
5.22M
        c10 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c10, t1, t20, res_i0);
171
5.22M
        uint64_t t10 = c[4U * 0U + 1U];
172
5.22M
        uint64_t t21 = d[4U * 0U + 1U];
173
5.22M
        uint64_t *res_i1 = a + 4U * 0U + 1U;
174
5.22M
        c10 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c10, t10, t21, res_i1);
175
5.22M
        uint64_t t11 = c[4U * 0U + 2U];
176
5.22M
        uint64_t t22 = d[4U * 0U + 2U];
177
5.22M
        uint64_t *res_i2 = a + 4U * 0U + 2U;
178
5.22M
        c10 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c10, t11, t22, res_i2);
179
5.22M
        uint64_t t12 = c[4U * 0U + 3U];
180
5.22M
        uint64_t t2 = d[4U * 0U + 3U];
181
5.22M
        uint64_t *res_i = a + 4U * 0U + 3U;
182
5.22M
        c10 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c10, t12, t2, res_i);
183
5.22M
    }
184
5.22M
    KRML_MAYBE_FOR2(i,
185
5.22M
                    4U,
186
5.22M
                    6U,
187
5.22M
                    1U,
188
5.22M
                    uint64_t t1 = c[i];
189
5.22M
                    uint64_t t2 = d[i];
190
5.22M
                    uint64_t *res_i = a + i;
191
5.22M
                    c10 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c10, t1, t2, res_i););
192
5.22M
    uint64_t c0 = c10;
193
5.22M
    uint64_t tmp[6U] = { 0U };
194
5.22M
    uint64_t c1 = 0ULL;
195
5.22M
    {
196
5.22M
        uint64_t t1 = a[4U * 0U];
197
5.22M
        uint64_t t20 = b[4U * 0U];
198
5.22M
        uint64_t *res_i0 = tmp + 4U * 0U;
199
5.22M
        c1 = Lib_IntTypes_Intrinsics_add_carry_u64(c1, t1, t20, res_i0);
200
5.22M
        uint64_t t10 = a[4U * 0U + 1U];
201
5.22M
        uint64_t t21 = b[4U * 0U + 1U];
202
5.22M
        uint64_t *res_i1 = tmp + 4U * 0U + 1U;
203
5.22M
        c1 = Lib_IntTypes_Intrinsics_add_carry_u64(c1, t10, t21, res_i1);
204
5.22M
        uint64_t t11 = a[4U * 0U + 2U];
205
5.22M
        uint64_t t22 = b[4U * 0U + 2U];
206
5.22M
        uint64_t *res_i2 = tmp + 4U * 0U + 2U;
207
5.22M
        c1 = Lib_IntTypes_Intrinsics_add_carry_u64(c1, t11, t22, res_i2);
208
5.22M
        uint64_t t12 = a[4U * 0U + 3U];
209
5.22M
        uint64_t t2 = b[4U * 0U + 3U];
210
5.22M
        uint64_t *res_i = tmp + 4U * 0U + 3U;
211
5.22M
        c1 = Lib_IntTypes_Intrinsics_add_carry_u64(c1, t12, t2, res_i);
212
5.22M
    }
213
5.22M
    KRML_MAYBE_FOR2(i,
214
5.22M
                    4U,
215
5.22M
                    6U,
216
5.22M
                    1U,
217
5.22M
                    uint64_t t1 = a[i];
218
5.22M
                    uint64_t t2 = b[i];
219
5.22M
                    uint64_t *res_i = tmp + i;
220
5.22M
                    c1 = Lib_IntTypes_Intrinsics_add_carry_u64(c1, t1, t2, res_i););
221
5.22M
    uint64_t c11 = c1;
222
5.22M
    KRML_MAYBE_UNUSED_VAR(c11);
223
5.22M
    uint64_t c2 = 0ULL - c0;
224
5.22M
    KRML_MAYBE_FOR6(i,
225
5.22M
                    0U,
226
5.22M
                    6U,
227
5.22M
                    1U,
228
5.22M
                    uint64_t *os = a;
229
5.22M
                    uint64_t x = (c2 & tmp[i]) | (~c2 & a[i]);
230
5.22M
                    os[i] = x;);
231
5.22M
}
232
233
static inline void
234
bn_mul(uint64_t *a, uint64_t *b, uint64_t *c)
235
8.71M
{
236
8.71M
    memset(a, 0U, 12U * sizeof(uint64_t));
237
8.71M
    KRML_MAYBE_FOR6(
238
8.71M
        i0,
239
8.71M
        0U,
240
8.71M
        6U,
241
8.71M
        1U,
242
8.71M
        uint64_t bj = c[i0];
243
8.71M
        uint64_t *res_j = a + i0;
244
8.71M
        uint64_t c1 = 0ULL;
245
8.71M
        {
246
8.71M
            uint64_t a_i = b[4U * 0U];
247
8.71M
            uint64_t *res_i0 = res_j + 4U * 0U;
248
8.71M
            c1 = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, bj, c1, res_i0);
249
8.71M
            uint64_t a_i0 = b[4U * 0U + 1U];
250
8.71M
            uint64_t *res_i1 = res_j + 4U * 0U + 1U;
251
8.71M
            c1 = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, bj, c1, res_i1);
252
8.71M
            uint64_t a_i1 = b[4U * 0U + 2U];
253
8.71M
            uint64_t *res_i2 = res_j + 4U * 0U + 2U;
254
8.71M
            c1 = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, bj, c1, res_i2);
255
8.71M
            uint64_t a_i2 = b[4U * 0U + 3U];
256
8.71M
            uint64_t *res_i = res_j + 4U * 0U + 3U;
257
8.71M
            c1 = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, bj, c1, res_i);
258
8.71M
        } KRML_MAYBE_FOR2(i,
259
8.71M
                          4U,
260
8.71M
                          6U,
261
8.71M
                          1U,
262
8.71M
                          uint64_t a_i = b[i];
263
8.71M
                          uint64_t *res_i = res_j + i;
264
8.71M
                          c1 = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, bj, c1, res_i););
265
8.71M
        uint64_t r = c1;
266
8.71M
        a[6U + i0] = r;);
267
8.71M
}
268
269
static inline void
270
bn_sqr(uint64_t *a, uint64_t *b)
271
2.53M
{
272
2.53M
    memset(a, 0U, 12U * sizeof(uint64_t));
273
2.53M
    KRML_MAYBE_FOR6(
274
2.53M
        i0,
275
2.53M
        0U,
276
2.53M
        6U,
277
2.53M
        1U,
278
2.53M
        uint64_t *ab = b;
279
2.53M
        uint64_t a_j = b[i0];
280
2.53M
        uint64_t *res_j = a + i0;
281
2.53M
        uint64_t c = 0ULL;
282
2.53M
        for (uint32_t i = 0U; i < i0 / 4U; i++) {
283
2.53M
            uint64_t a_i = ab[4U * i];
284
2.53M
            uint64_t *res_i0 = res_j + 4U * i;
285
2.53M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, a_j, c, res_i0);
286
2.53M
            uint64_t a_i0 = ab[4U * i + 1U];
287
2.53M
            uint64_t *res_i1 = res_j + 4U * i + 1U;
288
2.53M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, a_j, c, res_i1);
289
2.53M
            uint64_t a_i1 = ab[4U * i + 2U];
290
2.53M
            uint64_t *res_i2 = res_j + 4U * i + 2U;
291
2.53M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, a_j, c, res_i2);
292
2.53M
            uint64_t a_i2 = ab[4U * i + 3U];
293
2.53M
            uint64_t *res_i = res_j + 4U * i + 3U;
294
2.53M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, a_j, c, res_i);
295
2.53M
        } for (uint32_t i = i0 / 4U * 4U; i < i0; i++) {
296
2.53M
            uint64_t a_i = ab[i];
297
2.53M
            uint64_t *res_i = res_j + i;
298
2.53M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, a_j, c, res_i);
299
2.53M
        } uint64_t r = c;
300
2.53M
        a[i0 + i0] = r;);
301
2.53M
    uint64_t c0 = Hacl_Bignum_Addition_bn_add_eq_len_u64(12U, a, a, a);
302
2.53M
    KRML_MAYBE_UNUSED_VAR(c0);
303
2.53M
    uint64_t tmp[12U] = { 0U };
304
2.53M
    KRML_MAYBE_FOR6(i,
305
2.53M
                    0U,
306
2.53M
                    6U,
307
2.53M
                    1U,
308
2.53M
                    FStar_UInt128_uint128 res = FStar_UInt128_mul_wide(b[i], b[i]);
309
2.53M
                    uint64_t hi = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(res, 64U));
310
2.53M
                    uint64_t lo = FStar_UInt128_uint128_to_uint64(res);
311
2.53M
                    tmp[2U * i] = lo;
312
2.53M
                    tmp[2U * i + 1U] = hi;);
313
2.53M
    uint64_t c1 = Hacl_Bignum_Addition_bn_add_eq_len_u64(12U, a, tmp, a);
314
2.53M
    KRML_MAYBE_UNUSED_VAR(c1);
315
2.53M
}
316
317
static inline void
318
bn_to_bytes_be(uint8_t *a, uint64_t *b)
319
2.79k
{
320
2.79k
    uint8_t tmp[48U] = { 0U };
321
2.79k
    KRML_MAYBE_UNUSED_VAR(tmp);
322
2.79k
    KRML_MAYBE_FOR6(i, 0U, 6U, 1U, store64_be(a + i * 8U, b[6U - i - 1U]););
323
2.79k
}
324
325
static inline void
326
bn_from_bytes_be(uint64_t *a, uint8_t *b)
327
6.01k
{
328
6.01k
    KRML_MAYBE_FOR6(i,
329
6.01k
                    0U,
330
6.01k
                    6U,
331
6.01k
                    1U,
332
6.01k
                    uint64_t *os = a;
333
6.01k
                    uint64_t u = load64_be(b + (6U - i - 1U) * 8U);
334
6.01k
                    uint64_t x = u;
335
6.01k
                    os[i] = x;);
336
6.01k
}
337
338
static inline void
339
p384_make_prime(uint64_t *n)
340
29.0M
{
341
29.0M
    n[0U] = 0x00000000ffffffffULL;
342
29.0M
    n[1U] = 0xffffffff00000000ULL;
343
29.0M
    n[2U] = 0xfffffffffffffffeULL;
344
29.0M
    n[3U] = 0xffffffffffffffffULL;
345
29.0M
    n[4U] = 0xffffffffffffffffULL;
346
29.0M
    n[5U] = 0xffffffffffffffffULL;
347
29.0M
}
348
349
static inline void
350
p384_make_order(uint64_t *n)
351
84.4k
{
352
84.4k
    n[0U] = 0xecec196accc52973ULL;
353
84.4k
    n[1U] = 0x581a0db248b0a77aULL;
354
84.4k
    n[2U] = 0xc7634d81f4372ddfULL;
355
84.4k
    n[3U] = 0xffffffffffffffffULL;
356
84.4k
    n[4U] = 0xffffffffffffffffULL;
357
84.4k
    n[5U] = 0xffffffffffffffffULL;
358
84.4k
}
359
360
static inline void
361
p384_make_a_coeff(uint64_t *a)
362
1.72k
{
363
1.72k
    a[0U] = 0x00000003fffffffcULL;
364
1.72k
    a[1U] = 0xfffffffc00000000ULL;
365
1.72k
    a[2U] = 0xfffffffffffffffbULL;
366
1.72k
    a[3U] = 0xffffffffffffffffULL;
367
1.72k
    a[4U] = 0xffffffffffffffffULL;
368
1.72k
    a[5U] = 0xffffffffffffffffULL;
369
1.72k
}
370
371
static inline void
372
p384_make_b_coeff(uint64_t *b)
373
1.57M
{
374
1.57M
    b[0U] = 0x081188719d412dccULL;
375
1.57M
    b[1U] = 0xf729add87a4c32ecULL;
376
1.57M
    b[2U] = 0x77f2209b1920022eULL;
377
1.57M
    b[3U] = 0xe3374bee94938ae2ULL;
378
1.57M
    b[4U] = 0xb62b21f41f022094ULL;
379
1.57M
    b[5U] = 0xcd08114b604fbff9ULL;
380
1.57M
}
381
382
static inline void
383
p384_make_g_x(uint64_t *n)
384
1.10k
{
385
1.10k
    n[0U] = 0x3dd0756649c0b528ULL;
386
1.10k
    n[1U] = 0x20e378e2a0d6ce38ULL;
387
1.10k
    n[2U] = 0x879c3afc541b4d6eULL;
388
1.10k
    n[3U] = 0x6454868459a30effULL;
389
1.10k
    n[4U] = 0x812ff723614ede2bULL;
390
1.10k
    n[5U] = 0x4d3aadc2299e1513ULL;
391
1.10k
}
392
393
static inline void
394
p384_make_g_y(uint64_t *n)
395
1.10k
{
396
1.10k
    n[0U] = 0x23043dad4b03a4feULL;
397
1.10k
    n[1U] = 0xa1bfa8bf7bb4a9acULL;
398
1.10k
    n[2U] = 0x8bade7562e83b050ULL;
399
1.10k
    n[3U] = 0xc6c3521968f4ffd9ULL;
400
1.10k
    n[4U] = 0xdd8002263969a840ULL;
401
1.10k
    n[5U] = 0x2b78abc25a15c5e9ULL;
402
1.10k
}
403
404
static inline void
405
p384_make_fmont_R2(uint64_t *n)
406
6.69k
{
407
6.69k
    n[0U] = 0xfffffffe00000001ULL;
408
6.69k
    n[1U] = 0x0000000200000000ULL;
409
6.69k
    n[2U] = 0xfffffffe00000000ULL;
410
6.69k
    n[3U] = 0x0000000200000000ULL;
411
6.69k
    n[4U] = 0x0000000000000001ULL;
412
6.69k
    n[5U] = 0x0ULL;
413
6.69k
}
414
415
static inline void
416
p384_make_fzero(uint64_t *n)
417
6.38k
{
418
6.38k
    memset(n, 0U, 6U * sizeof(uint64_t));
419
6.38k
    n[0U] = 0ULL;
420
6.38k
}
421
422
static inline void
423
p384_make_fone(uint64_t *n)
424
7.41k
{
425
7.41k
    n[0U] = 0xffffffff00000001ULL;
426
7.41k
    n[1U] = 0x00000000ffffffffULL;
427
7.41k
    n[2U] = 0x1ULL;
428
7.41k
    n[3U] = 0x0ULL;
429
7.41k
    n[4U] = 0x0ULL;
430
7.41k
    n[5U] = 0x0ULL;
431
7.41k
}
432
433
static inline void
434
p384_make_qone(uint64_t *f)
435
167
{
436
167
    f[0U] = 0x1313e695333ad68dULL;
437
167
    f[1U] = 0xa7e5f24db74f5885ULL;
438
167
    f[2U] = 0x389cb27e0bc8d220ULL;
439
167
    f[3U] = 0x0ULL;
440
167
    f[4U] = 0x0ULL;
441
167
    f[5U] = 0x0ULL;
442
167
}
443
444
static inline void
445
fmont_reduction(uint64_t *res, uint64_t *x)
446
11.1M
{
447
11.1M
    uint64_t n[6U] = { 0U };
448
11.1M
    p384_make_prime(n);
449
11.1M
    uint64_t c0 = 0ULL;
450
11.1M
    KRML_MAYBE_FOR6(
451
11.1M
        i0,
452
11.1M
        0U,
453
11.1M
        6U,
454
11.1M
        1U,
455
11.1M
        uint64_t qj = 4294967297ULL * x[i0];
456
11.1M
        uint64_t *res_j0 = x + i0;
457
11.1M
        uint64_t c = 0ULL;
458
11.1M
        {
459
11.1M
            uint64_t a_i = n[4U * 0U];
460
11.1M
            uint64_t *res_i0 = res_j0 + 4U * 0U;
461
11.1M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, qj, c, res_i0);
462
11.1M
            uint64_t a_i0 = n[4U * 0U + 1U];
463
11.1M
            uint64_t *res_i1 = res_j0 + 4U * 0U + 1U;
464
11.1M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, qj, c, res_i1);
465
11.1M
            uint64_t a_i1 = n[4U * 0U + 2U];
466
11.1M
            uint64_t *res_i2 = res_j0 + 4U * 0U + 2U;
467
11.1M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, qj, c, res_i2);
468
11.1M
            uint64_t a_i2 = n[4U * 0U + 3U];
469
11.1M
            uint64_t *res_i = res_j0 + 4U * 0U + 3U;
470
11.1M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, qj, c, res_i);
471
11.1M
        } KRML_MAYBE_FOR2(i,
472
11.1M
                          4U,
473
11.1M
                          6U,
474
11.1M
                          1U,
475
11.1M
                          uint64_t a_i = n[i];
476
11.1M
                          uint64_t *res_i = res_j0 + i;
477
11.1M
                          c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, qj, c, res_i););
478
11.1M
        uint64_t r = c;
479
11.1M
        uint64_t c1 = r;
480
11.1M
        uint64_t *resb = x + 6U + i0;
481
11.1M
        uint64_t res_j = x[6U + i0];
482
11.1M
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, c1, res_j, resb););
483
11.1M
    memcpy(res, x + 6U, 6U * sizeof(uint64_t));
484
11.1M
    uint64_t c00 = c0;
485
11.1M
    uint64_t tmp[6U] = { 0U };
486
11.1M
    uint64_t c = 0ULL;
487
11.1M
    {
488
11.1M
        uint64_t t1 = res[4U * 0U];
489
11.1M
        uint64_t t20 = n[4U * 0U];
490
11.1M
        uint64_t *res_i0 = tmp + 4U * 0U;
491
11.1M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t20, res_i0);
492
11.1M
        uint64_t t10 = res[4U * 0U + 1U];
493
11.1M
        uint64_t t21 = n[4U * 0U + 1U];
494
11.1M
        uint64_t *res_i1 = tmp + 4U * 0U + 1U;
495
11.1M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t10, t21, res_i1);
496
11.1M
        uint64_t t11 = res[4U * 0U + 2U];
497
11.1M
        uint64_t t22 = n[4U * 0U + 2U];
498
11.1M
        uint64_t *res_i2 = tmp + 4U * 0U + 2U;
499
11.1M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t11, t22, res_i2);
500
11.1M
        uint64_t t12 = res[4U * 0U + 3U];
501
11.1M
        uint64_t t2 = n[4U * 0U + 3U];
502
11.1M
        uint64_t *res_i = tmp + 4U * 0U + 3U;
503
11.1M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t12, t2, res_i);
504
11.1M
    }
505
11.1M
    KRML_MAYBE_FOR2(i,
506
11.1M
                    4U,
507
11.1M
                    6U,
508
11.1M
                    1U,
509
11.1M
                    uint64_t t1 = res[i];
510
11.1M
                    uint64_t t2 = n[i];
511
11.1M
                    uint64_t *res_i = tmp + i;
512
11.1M
                    c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t2, res_i););
513
11.1M
    uint64_t c1 = c;
514
11.1M
    uint64_t c2 = c00 - c1;
515
11.1M
    KRML_MAYBE_FOR6(i,
516
11.1M
                    0U,
517
11.1M
                    6U,
518
11.1M
                    1U,
519
11.1M
                    uint64_t *os = res;
520
11.1M
                    uint64_t x1 = (c2 & res[i]) | (~c2 & tmp[i]);
521
11.1M
                    os[i] = x1;);
522
11.1M
}
523
524
static inline void
525
qmont_reduction(uint64_t *res, uint64_t *x)
526
81.7k
{
527
81.7k
    uint64_t n[6U] = { 0U };
528
81.7k
    p384_make_order(n);
529
81.7k
    uint64_t c0 = 0ULL;
530
81.7k
    KRML_MAYBE_FOR6(
531
81.7k
        i0,
532
81.7k
        0U,
533
81.7k
        6U,
534
81.7k
        1U,
535
81.7k
        uint64_t qj = 7986114184663260229ULL * x[i0];
536
81.7k
        uint64_t *res_j0 = x + i0;
537
81.7k
        uint64_t c = 0ULL;
538
81.7k
        {
539
81.7k
            uint64_t a_i = n[4U * 0U];
540
81.7k
            uint64_t *res_i0 = res_j0 + 4U * 0U;
541
81.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, qj, c, res_i0);
542
81.7k
            uint64_t a_i0 = n[4U * 0U + 1U];
543
81.7k
            uint64_t *res_i1 = res_j0 + 4U * 0U + 1U;
544
81.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, qj, c, res_i1);
545
81.7k
            uint64_t a_i1 = n[4U * 0U + 2U];
546
81.7k
            uint64_t *res_i2 = res_j0 + 4U * 0U + 2U;
547
81.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, qj, c, res_i2);
548
81.7k
            uint64_t a_i2 = n[4U * 0U + 3U];
549
81.7k
            uint64_t *res_i = res_j0 + 4U * 0U + 3U;
550
81.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, qj, c, res_i);
551
81.7k
        } KRML_MAYBE_FOR2(i,
552
81.7k
                          4U,
553
81.7k
                          6U,
554
81.7k
                          1U,
555
81.7k
                          uint64_t a_i = n[i];
556
81.7k
                          uint64_t *res_i = res_j0 + i;
557
81.7k
                          c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, qj, c, res_i););
558
81.7k
        uint64_t r = c;
559
81.7k
        uint64_t c1 = r;
560
81.7k
        uint64_t *resb = x + 6U + i0;
561
81.7k
        uint64_t res_j = x[6U + i0];
562
81.7k
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, c1, res_j, resb););
563
81.7k
    memcpy(res, x + 6U, 6U * sizeof(uint64_t));
564
81.7k
    uint64_t c00 = c0;
565
81.7k
    uint64_t tmp[6U] = { 0U };
566
81.7k
    uint64_t c = 0ULL;
567
81.7k
    {
568
81.7k
        uint64_t t1 = res[4U * 0U];
569
81.7k
        uint64_t t20 = n[4U * 0U];
570
81.7k
        uint64_t *res_i0 = tmp + 4U * 0U;
571
81.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t20, res_i0);
572
81.7k
        uint64_t t10 = res[4U * 0U + 1U];
573
81.7k
        uint64_t t21 = n[4U * 0U + 1U];
574
81.7k
        uint64_t *res_i1 = tmp + 4U * 0U + 1U;
575
81.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t10, t21, res_i1);
576
81.7k
        uint64_t t11 = res[4U * 0U + 2U];
577
81.7k
        uint64_t t22 = n[4U * 0U + 2U];
578
81.7k
        uint64_t *res_i2 = tmp + 4U * 0U + 2U;
579
81.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t11, t22, res_i2);
580
81.7k
        uint64_t t12 = res[4U * 0U + 3U];
581
81.7k
        uint64_t t2 = n[4U * 0U + 3U];
582
81.7k
        uint64_t *res_i = tmp + 4U * 0U + 3U;
583
81.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t12, t2, res_i);
584
81.7k
    }
585
81.7k
    KRML_MAYBE_FOR2(i,
586
81.7k
                    4U,
587
81.7k
                    6U,
588
81.7k
                    1U,
589
81.7k
                    uint64_t t1 = res[i];
590
81.7k
                    uint64_t t2 = n[i];
591
81.7k
                    uint64_t *res_i = tmp + i;
592
81.7k
                    c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t2, res_i););
593
81.7k
    uint64_t c1 = c;
594
81.7k
    uint64_t c2 = c00 - c1;
595
81.7k
    KRML_MAYBE_FOR6(i,
596
81.7k
                    0U,
597
81.7k
                    6U,
598
81.7k
                    1U,
599
81.7k
                    uint64_t *os = res;
600
81.7k
                    uint64_t x1 = (c2 & res[i]) | (~c2 & tmp[i]);
601
81.7k
                    os[i] = x1;);
602
81.7k
}
603
604
static inline uint64_t
605
bn_is_lt_prime_mask(uint64_t *f)
606
3.51k
{
607
3.51k
    uint64_t tmp[6U] = { 0U };
608
3.51k
    p384_make_prime(tmp);
609
3.51k
    uint64_t c = bn_sub(tmp, f, tmp);
610
3.51k
    uint64_t m = FStar_UInt64_gte_mask(c, 0ULL) & ~FStar_UInt64_eq_mask(c, 0ULL);
611
3.51k
    return m;
612
3.51k
}
613
614
static inline void
615
fadd0(uint64_t *a, uint64_t *b, uint64_t *c)
616
12.6M
{
617
12.6M
    uint64_t n[6U] = { 0U };
618
12.6M
    p384_make_prime(n);
619
12.6M
    bn_add_mod(a, n, b, c);
620
12.6M
}
621
622
static inline void
623
fsub0(uint64_t *a, uint64_t *b, uint64_t *c)
624
5.22M
{
625
5.22M
    uint64_t n[6U] = { 0U };
626
5.22M
    p384_make_prime(n);
627
5.22M
    bn_sub_mod(a, n, b, c);
628
5.22M
}
629
630
static inline void
631
fmul0(uint64_t *a, uint64_t *b, uint64_t *c)
632
8.69M
{
633
8.69M
    uint64_t tmp[12U] = { 0U };
634
8.69M
    bn_mul(tmp, b, c);
635
8.69M
    fmont_reduction(a, tmp);
636
8.69M
}
637
638
static inline void
639
fsqr0(uint64_t *a, uint64_t *b)
640
2.46M
{
641
2.46M
    uint64_t tmp[12U] = { 0U };
642
2.46M
    bn_sqr(tmp, b);
643
2.46M
    fmont_reduction(a, tmp);
644
2.46M
}
645
646
static inline void
647
from_mont(uint64_t *a, uint64_t *b)
648
2.82k
{
649
2.82k
    uint64_t tmp[12U] = { 0U };
650
2.82k
    memcpy(tmp, b, 6U * sizeof(uint64_t));
651
2.82k
    fmont_reduction(a, tmp);
652
2.82k
}
653
654
static inline void
655
to_mont(uint64_t *a, uint64_t *b)
656
6.69k
{
657
6.69k
    uint64_t r2modn[6U] = { 0U };
658
6.69k
    p384_make_fmont_R2(r2modn);
659
6.69k
    uint64_t tmp[12U] = { 0U };
660
6.69k
    bn_mul(tmp, b, r2modn);
661
6.69k
    fmont_reduction(a, tmp);
662
6.69k
}
663
664
static inline void
665
fexp_consttime(uint64_t *out, uint64_t *a, uint64_t *b)
666
1.49k
{
667
1.49k
    uint64_t table[192U] = { 0U };
668
1.49k
    uint64_t tmp[6U] = { 0U };
669
1.49k
    uint64_t *t0 = table;
670
1.49k
    uint64_t *t1 = table + 6U;
671
1.49k
    p384_make_fone(t0);
672
1.49k
    memcpy(t1, a, 6U * sizeof(uint64_t));
673
1.49k
    KRML_MAYBE_FOR15(i,
674
1.49k
                     0U,
675
1.49k
                     15U,
676
1.49k
                     1U,
677
1.49k
                     uint64_t *t11 = table + (i + 1U) * 6U;
678
1.49k
                     fsqr0(tmp, t11);
679
1.49k
                     memcpy(table + (2U * i + 2U) * 6U, tmp, 6U * sizeof(uint64_t));
680
1.49k
                     uint64_t *t2 = table + (2U * i + 2U) * 6U;
681
1.49k
                     fmul0(tmp, a, t2);
682
1.49k
                     memcpy(table + (2U * i + 3U) * 6U, tmp, 6U * sizeof(uint64_t)););
683
1.49k
    uint32_t i0 = 380U;
684
1.49k
    uint64_t bits_c = Hacl_Bignum_Lib_bn_get_bits_u64(6U, b, i0, 5U);
685
1.49k
    memcpy(out, (uint64_t *)table, 6U * sizeof(uint64_t));
686
47.9k
    for (uint32_t i1 = 0U; i1 < 31U; i1++) {
687
46.4k
        uint64_t c = FStar_UInt64_eq_mask(bits_c, (uint64_t)(i1 + 1U));
688
46.4k
        const uint64_t *res_j = table + (i1 + 1U) * 6U;
689
46.4k
        KRML_MAYBE_FOR6(i,
690
46.4k
                        0U,
691
46.4k
                        6U,
692
46.4k
                        1U,
693
46.4k
                        uint64_t *os = out;
694
46.4k
                        uint64_t x = (c & res_j[i]) | (~c & out[i]);
695
46.4k
                        os[i] = x;);
696
46.4k
    }
697
1.49k
    uint64_t tmp0[6U] = { 0U };
698
115k
    for (uint32_t i1 = 0U; i1 < 76U; i1++) {
699
113k
        KRML_MAYBE_FOR5(i, 0U, 5U, 1U, fsqr0(out, out););
700
113k
        uint32_t k = 380U - 5U * i1 - 5U;
701
113k
        uint64_t bits_l = Hacl_Bignum_Lib_bn_get_bits_u64(6U, b, k, 5U);
702
113k
        memcpy(tmp0, (uint64_t *)table, 6U * sizeof(uint64_t));
703
3.64M
        for (uint32_t i2 = 0U; i2 < 31U; i2++) {
704
3.52M
            uint64_t c = FStar_UInt64_eq_mask(bits_l, (uint64_t)(i2 + 1U));
705
3.52M
            const uint64_t *res_j = table + (i2 + 1U) * 6U;
706
3.52M
            KRML_MAYBE_FOR6(i,
707
3.52M
                            0U,
708
3.52M
                            6U,
709
3.52M
                            1U,
710
3.52M
                            uint64_t *os = tmp0;
711
3.52M
                            uint64_t x = (c & res_j[i]) | (~c & tmp0[i]);
712
3.52M
                            os[i] = x;);
713
3.52M
        }
714
113k
        fmul0(out, out, tmp0);
715
113k
    }
716
1.49k
}
717
718
static inline void
719
p384_finv(uint64_t *res, uint64_t *a)
720
1.49k
{
721
1.49k
    uint64_t b[6U] = { 0U };
722
1.49k
    b[0U] = 0x00000000fffffffdULL;
723
1.49k
    b[1U] = 0xffffffff00000000ULL;
724
1.49k
    b[2U] = 0xfffffffffffffffeULL;
725
1.49k
    b[3U] = 0xffffffffffffffffULL;
726
1.49k
    b[4U] = 0xffffffffffffffffULL;
727
1.49k
    b[5U] = 0xffffffffffffffffULL;
728
1.49k
    fexp_consttime(res, a, b);
729
1.49k
}
730
731
static inline void
732
p384_fsqrt(uint64_t *res, uint64_t *a)
733
0
{
734
0
    uint64_t b[6U] = { 0U };
735
0
    b[0U] = 0x0000000040000000ULL;
736
0
    b[1U] = 0xbfffffffc0000000ULL;
737
0
    b[2U] = 0xffffffffffffffffULL;
738
0
    b[3U] = 0xffffffffffffffffULL;
739
0
    b[4U] = 0xffffffffffffffffULL;
740
0
    b[5U] = 0x3fffffffffffffffULL;
741
0
    fexp_consttime(res, a, b);
742
0
}
743
744
static inline uint64_t
745
load_qelem_conditional(uint64_t *a, uint8_t *b)
746
1.46k
{
747
1.46k
    bn_from_bytes_be(a, b);
748
1.46k
    uint64_t tmp[6U] = { 0U };
749
1.46k
    p384_make_order(tmp);
750
1.46k
    uint64_t c = bn_sub(tmp, a, tmp);
751
1.46k
    uint64_t is_lt_order = FStar_UInt64_gte_mask(c, 0ULL) & ~FStar_UInt64_eq_mask(c, 0ULL);
752
1.46k
    uint64_t bn_zero[6U] = { 0U };
753
1.46k
    uint64_t res = bn_is_eq_mask(a, bn_zero);
754
1.46k
    uint64_t is_eq_zero = res;
755
1.46k
    uint64_t is_b_valid = is_lt_order & ~is_eq_zero;
756
1.46k
    uint64_t oneq[6U] = { 0U };
757
1.46k
    memset(oneq, 0U, 6U * sizeof(uint64_t));
758
1.46k
    oneq[0U] = 1ULL;
759
1.46k
    KRML_MAYBE_FOR6(i,
760
1.46k
                    0U,
761
1.46k
                    6U,
762
1.46k
                    1U,
763
1.46k
                    uint64_t *os = a;
764
1.46k
                    uint64_t uu____0 = oneq[i];
765
1.46k
                    uint64_t x = uu____0 ^ (is_b_valid & (a[i] ^ uu____0));
766
1.46k
                    os[i] = x;);
767
1.46k
    return is_b_valid;
768
1.46k
}
769
770
static inline void
771
qmod_short(uint64_t *a, uint64_t *b)
772
353
{
773
353
    uint64_t tmp[6U] = { 0U };
774
353
    p384_make_order(tmp);
775
353
    uint64_t c = bn_sub(tmp, b, tmp);
776
353
    bn_cmovznz(a, c, tmp, b);
777
353
}
778
779
static inline void
780
qadd(uint64_t *a, uint64_t *b, uint64_t *c)
781
67
{
782
67
    uint64_t n[6U] = { 0U };
783
67
    p384_make_order(n);
784
67
    bn_add_mod(a, n, b, c);
785
67
}
786
787
static inline void
788
qmul(uint64_t *a, uint64_t *b, uint64_t *c)
789
15.5k
{
790
15.5k
    uint64_t tmp[12U] = { 0U };
791
15.5k
    bn_mul(tmp, b, c);
792
15.5k
    qmont_reduction(a, tmp);
793
15.5k
}
794
795
static inline void
796
qsqr(uint64_t *a, uint64_t *b)
797
65.9k
{
798
65.9k
    uint64_t tmp[12U] = { 0U };
799
65.9k
    bn_sqr(tmp, b);
800
65.9k
    qmont_reduction(a, tmp);
801
65.9k
}
802
803
static inline void
804
from_qmont(uint64_t *a, uint64_t *b)
805
267
{
806
267
    uint64_t tmp[12U] = { 0U };
807
267
    memcpy(tmp, b, 6U * sizeof(uint64_t));
808
267
    qmont_reduction(a, tmp);
809
267
}
810
811
static inline void
812
qexp_consttime(uint64_t *out, uint64_t *a, uint64_t *b)
813
167
{
814
167
    uint64_t table[192U] = { 0U };
815
167
    uint64_t tmp[6U] = { 0U };
816
167
    uint64_t *t0 = table;
817
167
    uint64_t *t1 = table + 6U;
818
167
    p384_make_qone(t0);
819
167
    memcpy(t1, a, 6U * sizeof(uint64_t));
820
167
    KRML_MAYBE_FOR15(i,
821
167
                     0U,
822
167
                     15U,
823
167
                     1U,
824
167
                     uint64_t *t11 = table + (i + 1U) * 6U;
825
167
                     qsqr(tmp, t11);
826
167
                     memcpy(table + (2U * i + 2U) * 6U, tmp, 6U * sizeof(uint64_t));
827
167
                     uint64_t *t2 = table + (2U * i + 2U) * 6U;
828
167
                     qmul(tmp, a, t2);
829
167
                     memcpy(table + (2U * i + 3U) * 6U, tmp, 6U * sizeof(uint64_t)););
830
167
    uint32_t i0 = 380U;
831
167
    uint64_t bits_c = Hacl_Bignum_Lib_bn_get_bits_u64(6U, b, i0, 5U);
832
167
    memcpy(out, (uint64_t *)table, 6U * sizeof(uint64_t));
833
5.34k
    for (uint32_t i1 = 0U; i1 < 31U; i1++) {
834
5.17k
        uint64_t c = FStar_UInt64_eq_mask(bits_c, (uint64_t)(i1 + 1U));
835
5.17k
        const uint64_t *res_j = table + (i1 + 1U) * 6U;
836
5.17k
        KRML_MAYBE_FOR6(i,
837
5.17k
                        0U,
838
5.17k
                        6U,
839
5.17k
                        1U,
840
5.17k
                        uint64_t *os = out;
841
5.17k
                        uint64_t x = (c & res_j[i]) | (~c & out[i]);
842
5.17k
                        os[i] = x;);
843
5.17k
    }
844
167
    uint64_t tmp0[6U] = { 0U };
845
12.8k
    for (uint32_t i1 = 0U; i1 < 76U; i1++) {
846
12.6k
        KRML_MAYBE_FOR5(i, 0U, 5U, 1U, qsqr(out, out););
847
12.6k
        uint32_t k = 380U - 5U * i1 - 5U;
848
12.6k
        uint64_t bits_l = Hacl_Bignum_Lib_bn_get_bits_u64(6U, b, k, 5U);
849
12.6k
        memcpy(tmp0, (uint64_t *)table, 6U * sizeof(uint64_t));
850
406k
        for (uint32_t i2 = 0U; i2 < 31U; i2++) {
851
393k
            uint64_t c = FStar_UInt64_eq_mask(bits_l, (uint64_t)(i2 + 1U));
852
393k
            const uint64_t *res_j = table + (i2 + 1U) * 6U;
853
393k
            KRML_MAYBE_FOR6(i,
854
393k
                            0U,
855
393k
                            6U,
856
393k
                            1U,
857
393k
                            uint64_t *os = tmp0;
858
393k
                            uint64_t x = (c & res_j[i]) | (~c & tmp0[i]);
859
393k
                            os[i] = x;);
860
393k
        }
861
12.6k
        qmul(out, out, tmp0);
862
12.6k
    }
863
167
}
864
865
static inline void
866
p384_qinv(uint64_t *res, uint64_t *a)
867
167
{
868
167
    uint64_t b[6U] = { 0U };
869
167
    b[0U] = 0xecec196accc52971ULL;
870
167
    b[1U] = 0x581a0db248b0a77aULL;
871
167
    b[2U] = 0xc7634d81f4372ddfULL;
872
167
    b[3U] = 0xffffffffffffffffULL;
873
167
    b[4U] = 0xffffffffffffffffULL;
874
167
    b[5U] = 0xffffffffffffffffULL;
875
167
    qexp_consttime(res, a, b);
876
167
}
877
878
static inline void
879
point_add(uint64_t *x, uint64_t *y, uint64_t *xy)
880
164k
{
881
164k
    uint64_t tmp[54U] = { 0U };
882
164k
    uint64_t *t0 = tmp;
883
164k
    uint64_t *t1 = tmp + 36U;
884
164k
    uint64_t *x3 = t1;
885
164k
    uint64_t *y3 = t1 + 6U;
886
164k
    uint64_t *z3 = t1 + 12U;
887
164k
    uint64_t *t01 = t0;
888
164k
    uint64_t *t11 = t0 + 6U;
889
164k
    uint64_t *t2 = t0 + 12U;
890
164k
    uint64_t *t3 = t0 + 18U;
891
164k
    uint64_t *t4 = t0 + 24U;
892
164k
    uint64_t *t5 = t0 + 30U;
893
164k
    uint64_t *x1 = x;
894
164k
    uint64_t *y1 = x + 6U;
895
164k
    uint64_t *z10 = x + 12U;
896
164k
    uint64_t *x20 = y;
897
164k
    uint64_t *y20 = y + 6U;
898
164k
    uint64_t *z20 = y + 12U;
899
164k
    fmul0(t01, x1, x20);
900
164k
    fmul0(t11, y1, y20);
901
164k
    fmul0(t2, z10, z20);
902
164k
    fadd0(t3, x1, y1);
903
164k
    fadd0(t4, x20, y20);
904
164k
    fmul0(t3, t3, t4);
905
164k
    fadd0(t4, t01, t11);
906
164k
    uint64_t *y10 = x + 6U;
907
164k
    uint64_t *z11 = x + 12U;
908
164k
    uint64_t *y2 = y + 6U;
909
164k
    uint64_t *z21 = y + 12U;
910
164k
    fsub0(t3, t3, t4);
911
164k
    fadd0(t4, y10, z11);
912
164k
    fadd0(t5, y2, z21);
913
164k
    fmul0(t4, t4, t5);
914
164k
    fadd0(t5, t11, t2);
915
164k
    fsub0(t4, t4, t5);
916
164k
    uint64_t *x10 = x;
917
164k
    uint64_t *z1 = x + 12U;
918
164k
    uint64_t *x2 = y;
919
164k
    uint64_t *z2 = y + 12U;
920
164k
    fadd0(x3, x10, z1);
921
164k
    fadd0(y3, x2, z2);
922
164k
    fmul0(x3, x3, y3);
923
164k
    fadd0(y3, t01, t2);
924
164k
    fsub0(y3, x3, y3);
925
164k
    uint64_t b_coeff[6U] = { 0U };
926
164k
    p384_make_b_coeff(b_coeff);
927
164k
    fmul0(z3, b_coeff, t2);
928
164k
    fsub0(x3, y3, z3);
929
164k
    fadd0(z3, x3, x3);
930
164k
    fadd0(x3, x3, z3);
931
164k
    fsub0(z3, t11, x3);
932
164k
    fadd0(x3, t11, x3);
933
164k
    uint64_t b_coeff0[6U] = { 0U };
934
164k
    p384_make_b_coeff(b_coeff0);
935
164k
    fmul0(y3, b_coeff0, y3);
936
164k
    fadd0(t11, t2, t2);
937
164k
    fadd0(t2, t11, t2);
938
164k
    fsub0(y3, y3, t2);
939
164k
    fsub0(y3, y3, t01);
940
164k
    fadd0(t11, y3, y3);
941
164k
    fadd0(y3, t11, y3);
942
164k
    fadd0(t11, t01, t01);
943
164k
    fadd0(t01, t11, t01);
944
164k
    fsub0(t01, t01, t2);
945
164k
    fmul0(t11, t4, y3);
946
164k
    fmul0(t2, t01, y3);
947
164k
    fmul0(y3, x3, z3);
948
164k
    fadd0(y3, y3, t2);
949
164k
    fmul0(x3, t3, x3);
950
164k
    fsub0(x3, x3, t11);
951
164k
    fmul0(z3, t4, z3);
952
164k
    fmul0(t11, t3, t01);
953
164k
    fadd0(z3, z3, t11);
954
164k
    memcpy(xy, t1, 18U * sizeof(uint64_t));
955
164k
}
956
957
static inline void
958
point_double(uint64_t *x, uint64_t *xx)
959
624k
{
960
624k
    uint64_t tmp[30U] = { 0U };
961
624k
    uint64_t *x1 = x;
962
624k
    uint64_t *z = x + 12U;
963
624k
    uint64_t *x3 = xx;
964
624k
    uint64_t *y3 = xx + 6U;
965
624k
    uint64_t *z3 = xx + 12U;
966
624k
    uint64_t *t0 = tmp;
967
624k
    uint64_t *t1 = tmp + 6U;
968
624k
    uint64_t *t2 = tmp + 12U;
969
624k
    uint64_t *t3 = tmp + 18U;
970
624k
    uint64_t *t4 = tmp + 24U;
971
624k
    uint64_t *x2 = x;
972
624k
    uint64_t *y = x + 6U;
973
624k
    uint64_t *z1 = x + 12U;
974
624k
    fsqr0(t0, x2);
975
624k
    fsqr0(t1, y);
976
624k
    fsqr0(t2, z1);
977
624k
    fmul0(t3, x2, y);
978
624k
    fadd0(t3, t3, t3);
979
624k
    fmul0(t4, y, z1);
980
624k
    fmul0(z3, x1, z);
981
624k
    fadd0(z3, z3, z3);
982
624k
    uint64_t b_coeff[6U] = { 0U };
983
624k
    p384_make_b_coeff(b_coeff);
984
624k
    fmul0(y3, b_coeff, t2);
985
624k
    fsub0(y3, y3, z3);
986
624k
    fadd0(x3, y3, y3);
987
624k
    fadd0(y3, x3, y3);
988
624k
    fsub0(x3, t1, y3);
989
624k
    fadd0(y3, t1, y3);
990
624k
    fmul0(y3, x3, y3);
991
624k
    fmul0(x3, x3, t3);
992
624k
    fadd0(t3, t2, t2);
993
624k
    fadd0(t2, t2, t3);
994
624k
    uint64_t b_coeff0[6U] = { 0U };
995
624k
    p384_make_b_coeff(b_coeff0);
996
624k
    fmul0(z3, b_coeff0, z3);
997
624k
    fsub0(z3, z3, t2);
998
624k
    fsub0(z3, z3, t0);
999
624k
    fadd0(t3, z3, z3);
1000
624k
    fadd0(z3, z3, t3);
1001
624k
    fadd0(t3, t0, t0);
1002
624k
    fadd0(t0, t3, t0);
1003
624k
    fsub0(t0, t0, t2);
1004
624k
    fmul0(t0, t0, z3);
1005
624k
    fadd0(y3, y3, t0);
1006
624k
    fadd0(t0, t4, t4);
1007
624k
    fmul0(z3, t0, z3);
1008
624k
    fsub0(x3, x3, z3);
1009
624k
    fmul0(z3, t0, t1);
1010
624k
    fadd0(z3, z3, z3);
1011
624k
    fadd0(z3, z3, z3);
1012
624k
}
1013
1014
static inline void
1015
point_zero(uint64_t *one)
1016
3.19k
{
1017
3.19k
    uint64_t *x = one;
1018
3.19k
    uint64_t *y = one + 6U;
1019
3.19k
    uint64_t *z = one + 12U;
1020
3.19k
    p384_make_fzero(x);
1021
3.19k
    p384_make_fone(y);
1022
3.19k
    p384_make_fzero(z);
1023
3.19k
}
1024
1025
static inline void
1026
point_mul(uint64_t *res, uint64_t *scalar, uint64_t *p)
1027
1.59k
{
1028
1.59k
    uint64_t table[288U] = { 0U };
1029
1.59k
    uint64_t tmp[18U] = { 0U };
1030
1.59k
    uint64_t *t0 = table;
1031
1.59k
    uint64_t *t1 = table + 18U;
1032
1.59k
    point_zero(t0);
1033
1.59k
    memcpy(t1, p, 18U * sizeof(uint64_t));
1034
1.59k
    KRML_MAYBE_FOR7(i,
1035
1.59k
                    0U,
1036
1.59k
                    7U,
1037
1.59k
                    1U,
1038
1.59k
                    uint64_t *t11 = table + (i + 1U) * 18U;
1039
1.59k
                    point_double(t11, tmp);
1040
1.59k
                    memcpy(table + (2U * i + 2U) * 18U, tmp, 18U * sizeof(uint64_t));
1041
1.59k
                    uint64_t *t2 = table + (2U * i + 2U) * 18U;
1042
1.59k
                    point_add(p, t2, tmp);
1043
1.59k
                    memcpy(table + (2U * i + 3U) * 18U, tmp, 18U * sizeof(uint64_t)););
1044
1.59k
    point_zero(res);
1045
1.59k
    uint64_t tmp0[18U] = { 0U };
1046
154k
    for (uint32_t i0 = 0U; i0 < 96U; i0++) {
1047
153k
        KRML_MAYBE_FOR4(i, 0U, 4U, 1U, point_double(res, res););
1048
153k
        uint32_t k = 384U - 4U * i0 - 4U;
1049
153k
        uint64_t bits_l = Hacl_Bignum_Lib_bn_get_bits_u64(6U, scalar, k, 4U);
1050
153k
        memcpy(tmp0, (uint64_t *)table, 18U * sizeof(uint64_t));
1051
153k
        KRML_MAYBE_FOR15(
1052
153k
            i1,
1053
153k
            0U,
1054
153k
            15U,
1055
153k
            1U,
1056
153k
            uint64_t c = FStar_UInt64_eq_mask(bits_l, (uint64_t)(i1 + 1U));
1057
153k
            const uint64_t *res_j = table + (i1 + 1U) * 18U;
1058
153k
            for (uint32_t i = 0U; i < 18U; i++) {
1059
153k
                uint64_t *os = tmp0;
1060
153k
                uint64_t x = (c & res_j[i]) | (~c & tmp0[i]);
1061
153k
                os[i] = x;
1062
153k
            });
1063
153k
        point_add(res, tmp0, res);
1064
153k
    }
1065
1.59k
}
1066
1067
static inline void
1068
point_mul_g(uint64_t *res, uint64_t *scalar)
1069
1.10k
{
1070
1.10k
    uint64_t g[18U] = { 0U };
1071
1.10k
    uint64_t *x = g;
1072
1.10k
    uint64_t *y = g + 6U;
1073
1.10k
    uint64_t *z = g + 12U;
1074
1.10k
    p384_make_g_x(x);
1075
1.10k
    p384_make_g_y(y);
1076
1.10k
    p384_make_fone(z);
1077
1.10k
    point_mul(res, scalar, g);
1078
1.10k
}
1079
1080
static inline void
1081
point_mul_double_g(uint64_t *res, uint64_t *scalar1, uint64_t *scalar2, uint64_t *p)
1082
100
{
1083
100
    uint64_t tmp[18U] = { 0U };
1084
100
    point_mul_g(tmp, scalar1);
1085
100
    point_mul(res, scalar2, p);
1086
100
    point_add(res, tmp, res);
1087
100
}
1088
1089
static inline bool
1090
ecdsa_sign_msg_as_qelem(
1091
    uint8_t *signature,
1092
    uint64_t *m_q,
1093
    uint8_t *private_key,
1094
    uint8_t *nonce)
1095
67
{
1096
67
    uint64_t rsdk_q[24U] = { 0U };
1097
67
    uint64_t *r_q = rsdk_q;
1098
67
    uint64_t *s_q = rsdk_q + 6U;
1099
67
    uint64_t *d_a = rsdk_q + 12U;
1100
67
    uint64_t *k_q = rsdk_q + 18U;
1101
67
    uint64_t is_sk_valid = load_qelem_conditional(d_a, private_key);
1102
67
    uint64_t is_nonce_valid = load_qelem_conditional(k_q, nonce);
1103
67
    uint64_t are_sk_nonce_valid = is_sk_valid & is_nonce_valid;
1104
67
    uint64_t p[18U] = { 0U };
1105
67
    point_mul_g(p, k_q);
1106
67
    uint64_t zinv[6U] = { 0U };
1107
67
    uint64_t *px = p;
1108
67
    uint64_t *pz = p + 12U;
1109
67
    p384_finv(zinv, pz);
1110
67
    fmul0(r_q, px, zinv);
1111
67
    from_mont(r_q, r_q);
1112
67
    qmod_short(r_q, r_q);
1113
67
    uint64_t kinv[6U] = { 0U };
1114
67
    p384_qinv(kinv, k_q);
1115
67
    qmul(s_q, r_q, d_a);
1116
67
    from_qmont(m_q, m_q);
1117
67
    qadd(s_q, m_q, s_q);
1118
67
    qmul(s_q, kinv, s_q);
1119
67
    bn_to_bytes_be(signature, r_q);
1120
67
    bn_to_bytes_be(signature + 48U, s_q);
1121
67
    uint64_t bn_zero0[6U] = { 0U };
1122
67
    uint64_t res = bn_is_eq_mask(r_q, bn_zero0);
1123
67
    uint64_t is_r_zero = res;
1124
67
    uint64_t bn_zero[6U] = { 0U };
1125
67
    uint64_t res0 = bn_is_eq_mask(s_q, bn_zero);
1126
67
    uint64_t is_s_zero = res0;
1127
67
    uint64_t m = are_sk_nonce_valid & (~is_r_zero & ~is_s_zero);
1128
67
    bool res1 = m == 0xFFFFFFFFFFFFFFFFULL;
1129
67
    return res1;
1130
67
}
1131
1132
static inline bool
1133
ecdsa_verify_msg_as_qelem(
1134
    uint64_t *m_q,
1135
    uint8_t *public_key,
1136
    uint8_t *signature_r,
1137
    uint8_t *signature_s)
1138
119
{
1139
119
    uint64_t tmp[42U] = { 0U };
1140
119
    uint64_t *pk = tmp;
1141
119
    uint64_t *r_q = tmp + 18U;
1142
119
    uint64_t *s_q = tmp + 24U;
1143
119
    uint64_t *u1 = tmp + 30U;
1144
119
    uint64_t *u2 = tmp + 36U;
1145
119
    uint64_t p_aff[12U] = { 0U };
1146
119
    uint8_t *p_x = public_key;
1147
119
    uint8_t *p_y = public_key + 48U;
1148
119
    uint64_t *bn_p_x = p_aff;
1149
119
    uint64_t *bn_p_y = p_aff + 6U;
1150
119
    bn_from_bytes_be(bn_p_x, p_x);
1151
119
    bn_from_bytes_be(bn_p_y, p_y);
1152
119
    uint64_t *px0 = p_aff;
1153
119
    uint64_t *py0 = p_aff + 6U;
1154
119
    uint64_t lessX = bn_is_lt_prime_mask(px0);
1155
119
    uint64_t lessY = bn_is_lt_prime_mask(py0);
1156
119
    uint64_t res0 = lessX & lessY;
1157
119
    bool is_xy_valid = res0 == 0xFFFFFFFFFFFFFFFFULL;
1158
119
    bool res;
1159
119
    if (!is_xy_valid) {
1160
0
        res = false;
1161
119
    } else {
1162
119
        uint64_t rp[6U] = { 0U };
1163
119
        uint64_t tx[6U] = { 0U };
1164
119
        uint64_t ty[6U] = { 0U };
1165
119
        uint64_t *px = p_aff;
1166
119
        uint64_t *py = p_aff + 6U;
1167
119
        to_mont(tx, px);
1168
119
        to_mont(ty, py);
1169
119
        uint64_t tmp1[6U] = { 0U };
1170
119
        fsqr0(rp, tx);
1171
119
        fmul0(rp, rp, tx);
1172
119
        p384_make_a_coeff(tmp1);
1173
119
        fmul0(tmp1, tmp1, tx);
1174
119
        fadd0(rp, tmp1, rp);
1175
119
        p384_make_b_coeff(tmp1);
1176
119
        fadd0(rp, tmp1, rp);
1177
119
        fsqr0(ty, ty);
1178
119
        uint64_t r = bn_is_eq_mask(ty, rp);
1179
119
        uint64_t r0 = r;
1180
119
        bool r1 = r0 == 0xFFFFFFFFFFFFFFFFULL;
1181
119
        res = r1;
1182
119
    }
1183
119
    if (res) {
1184
119
        uint64_t *px = p_aff;
1185
119
        uint64_t *py = p_aff + 6U;
1186
119
        uint64_t *rx = pk;
1187
119
        uint64_t *ry = pk + 6U;
1188
119
        uint64_t *rz = pk + 12U;
1189
119
        to_mont(rx, px);
1190
119
        to_mont(ry, py);
1191
119
        p384_make_fone(rz);
1192
119
    }
1193
119
    bool is_pk_valid = res;
1194
119
    bn_from_bytes_be(r_q, signature_r);
1195
119
    bn_from_bytes_be(s_q, signature_s);
1196
119
    uint64_t tmp10[6U] = { 0U };
1197
119
    p384_make_order(tmp10);
1198
119
    uint64_t c = bn_sub(tmp10, r_q, tmp10);
1199
119
    uint64_t is_lt_order = FStar_UInt64_gte_mask(c, 0ULL) & ~FStar_UInt64_eq_mask(c, 0ULL);
1200
119
    uint64_t bn_zero0[6U] = { 0U };
1201
119
    uint64_t res1 = bn_is_eq_mask(r_q, bn_zero0);
1202
119
    uint64_t is_eq_zero = res1;
1203
119
    uint64_t is_r_valid = is_lt_order & ~is_eq_zero;
1204
119
    uint64_t tmp11[6U] = { 0U };
1205
119
    p384_make_order(tmp11);
1206
119
    uint64_t c0 = bn_sub(tmp11, s_q, tmp11);
1207
119
    uint64_t is_lt_order0 = FStar_UInt64_gte_mask(c0, 0ULL) & ~FStar_UInt64_eq_mask(c0, 0ULL);
1208
119
    uint64_t bn_zero1[6U] = { 0U };
1209
119
    uint64_t res2 = bn_is_eq_mask(s_q, bn_zero1);
1210
119
    uint64_t is_eq_zero0 = res2;
1211
119
    uint64_t is_s_valid = is_lt_order0 & ~is_eq_zero0;
1212
119
    bool is_rs_valid = is_r_valid == 0xFFFFFFFFFFFFFFFFULL && is_s_valid == 0xFFFFFFFFFFFFFFFFULL;
1213
119
    if (!(is_pk_valid && is_rs_valid)) {
1214
19
        return false;
1215
19
    }
1216
100
    uint64_t sinv[6U] = { 0U };
1217
100
    p384_qinv(sinv, s_q);
1218
100
    uint64_t tmp1[6U] = { 0U };
1219
100
    from_qmont(tmp1, m_q);
1220
100
    qmul(u1, sinv, tmp1);
1221
100
    uint64_t tmp12[6U] = { 0U };
1222
100
    from_qmont(tmp12, r_q);
1223
100
    qmul(u2, sinv, tmp12);
1224
100
    uint64_t res3[18U] = { 0U };
1225
100
    point_mul_double_g(res3, u1, u2, pk);
1226
100
    uint64_t *pz0 = res3 + 12U;
1227
100
    uint64_t bn_zero[6U] = { 0U };
1228
100
    uint64_t res10 = bn_is_eq_mask(pz0, bn_zero);
1229
100
    uint64_t m = res10;
1230
100
    if (m == 0xFFFFFFFFFFFFFFFFULL) {
1231
0
        return false;
1232
0
    }
1233
100
    uint64_t x[6U] = { 0U };
1234
100
    uint64_t zinv[6U] = { 0U };
1235
100
    uint64_t *px = res3;
1236
100
    uint64_t *pz = res3 + 12U;
1237
100
    p384_finv(zinv, pz);
1238
100
    fmul0(x, px, zinv);
1239
100
    from_mont(x, x);
1240
100
    qmod_short(x, x);
1241
100
    uint64_t m0 = bn_is_eq_mask(x, r_q);
1242
100
    bool res11 = m0 == 0xFFFFFFFFFFFFFFFFULL;
1243
100
    return res11;
1244
100
}
1245
1246
/*******************************************************************************
1247
1248
 Verified C library for ECDSA and ECDH functions over the P-384 NIST curve.
1249
1250
 This module implements signing and verification, key validation, conversions
1251
 between various point representations, and ECDH key agreement.
1252
1253
*******************************************************************************/
1254
1255
/*****************/
1256
/* ECDSA signing */
1257
/*****************/
1258
1259
/**
1260
Create an ECDSA signature WITHOUT hashing first.
1261
1262
  This function is intended to receive a hash of the input.
1263
  For convenience, we recommend using one of the hash-and-sign combined functions above.
1264
1265
  The argument `msg` MUST be at least 48 bytes (i.e. `msg_len >= 48`).
1266
1267
  NOTE: The equivalent functions in OpenSSL and Fiat-Crypto both accept inputs
1268
  smaller than 48 bytes. These libraries left-pad the input with enough zeroes to
1269
  reach the minimum 48 byte size. Clients who need behavior identical to OpenSSL
1270
  need to perform the left-padding themselves.
1271
1272
  The function returns `true` for successful creation of an ECDSA signature and `false` otherwise.
1273
1274
  The outparam `signature` (R || S) points to 96 bytes of valid memory, i.e., uint8_t[96].
1275
  The argument `msg` points to `msg_len` bytes of valid memory, i.e., uint8_t[msg_len].
1276
  The arguments `private_key` and `nonce` point to 48 bytes of valid memory, i.e., uint8_t[48].
1277
1278
  The function also checks whether `private_key` and `nonce` are valid values:
1279
    • 0 < `private_key` < the order of the curve
1280
    • 0 < `nonce` < the order of the curve
1281
*/
1282
bool
1283
Hacl_P384_ecdsa_sign_p384_without_hash(
1284
    uint8_t *signature,
1285
    uint32_t msg_len,
1286
    uint8_t *msg,
1287
    uint8_t *private_key,
1288
    uint8_t *nonce)
1289
67
{
1290
67
    uint64_t m_q[6U] = { 0U };
1291
67
    uint8_t mHash[48U] = { 0U };
1292
67
    memcpy(mHash, msg, 48U * sizeof(uint8_t));
1293
67
    KRML_MAYBE_UNUSED_VAR(msg_len);
1294
67
    uint8_t *mHash48 = mHash;
1295
67
    bn_from_bytes_be(m_q, mHash48);
1296
67
    qmod_short(m_q, m_q);
1297
67
    bool res = ecdsa_sign_msg_as_qelem(signature, m_q, private_key, nonce);
1298
67
    return res;
1299
67
}
1300
1301
/**********************/
1302
/* ECDSA verification */
1303
/**********************/
1304
1305
/**
1306
Verify an ECDSA signature WITHOUT hashing first.
1307
1308
  This function is intended to receive a hash of the input.
1309
  For convenience, we recommend using one of the hash-and-verify combined functions above.
1310
1311
  The argument `msg` MUST be at least 48 bytes (i.e. `msg_len >= 48`).
1312
1313
  The function returns `true` if the signature is valid and `false` otherwise.
1314
1315
  The argument `msg` points to `msg_len` bytes of valid memory, i.e., uint8_t[msg_len].
1316
  The argument `public_key` (x || y) points to 96 bytes of valid memory, i.e., uint8_t[96].
1317
  The arguments `signature_r` and `signature_s` point to 48 bytes of valid memory, i.e., uint8_t[48].
1318
1319
  The function also checks whether `public_key` is valid
1320
*/
1321
bool
1322
Hacl_P384_ecdsa_verif_without_hash(
1323
    uint32_t msg_len,
1324
    uint8_t *msg,
1325
    uint8_t *public_key,
1326
    uint8_t *signature_r,
1327
    uint8_t *signature_s)
1328
119
{
1329
119
    uint64_t m_q[6U] = { 0U };
1330
119
    uint8_t mHash[48U] = { 0U };
1331
119
    memcpy(mHash, msg, 48U * sizeof(uint8_t));
1332
119
    KRML_MAYBE_UNUSED_VAR(msg_len);
1333
119
    uint8_t *mHash48 = mHash;
1334
119
    bn_from_bytes_be(m_q, mHash48);
1335
119
    qmod_short(m_q, m_q);
1336
119
    bool res = ecdsa_verify_msg_as_qelem(m_q, public_key, signature_r, signature_s);
1337
119
    return res;
1338
119
}
1339
1340
/******************/
1341
/* Key validation */
1342
/******************/
1343
1344
/**
1345
Public key validation.
1346
1347
  The function returns `true` if a public key is valid and `false` otherwise.
1348
1349
  The argument `public_key` points to 96 bytes of valid memory, i.e., uint8_t[96].
1350
1351
  The public key (x || y) is valid (with respect to SP 800-56A):
1352
    • the public key is not the “point at infinity”, represented as O.
1353
    • the affine x and y coordinates of the point represented by the public key are
1354
      in the range [0, p – 1] where p is the prime defining the finite field.
1355
    • y^2 = x^3 + ax + b where a and b are the coefficients of the curve equation.
1356
  The last extract is taken from: https://neilmadden.blog/2017/05/17/so-how-do-you-validate-nist-ecdh-public-keys/
1357
*/
1358
bool
1359
Hacl_P384_validate_public_key(uint8_t *public_key)
1360
1.24k
{
1361
1.24k
    uint64_t point_jac[18U] = { 0U };
1362
1.24k
    uint64_t p_aff[12U] = { 0U };
1363
1.24k
    uint8_t *p_x = public_key;
1364
1.24k
    uint8_t *p_y = public_key + 48U;
1365
1.24k
    uint64_t *bn_p_x = p_aff;
1366
1.24k
    uint64_t *bn_p_y = p_aff + 6U;
1367
1.24k
    bn_from_bytes_be(bn_p_x, p_x);
1368
1.24k
    bn_from_bytes_be(bn_p_y, p_y);
1369
1.24k
    uint64_t *px0 = p_aff;
1370
1.24k
    uint64_t *py0 = p_aff + 6U;
1371
1.24k
    uint64_t lessX = bn_is_lt_prime_mask(px0);
1372
1.24k
    uint64_t lessY = bn_is_lt_prime_mask(py0);
1373
1.24k
    uint64_t res0 = lessX & lessY;
1374
1.24k
    bool is_xy_valid = res0 == 0xFFFFFFFFFFFFFFFFULL;
1375
1.24k
    bool res;
1376
1.24k
    if (!is_xy_valid) {
1377
32
        res = false;
1378
1.21k
    } else {
1379
1.21k
        uint64_t rp[6U] = { 0U };
1380
1.21k
        uint64_t tx[6U] = { 0U };
1381
1.21k
        uint64_t ty[6U] = { 0U };
1382
1.21k
        uint64_t *px = p_aff;
1383
1.21k
        uint64_t *py = p_aff + 6U;
1384
1.21k
        to_mont(tx, px);
1385
1.21k
        to_mont(ty, py);
1386
1.21k
        uint64_t tmp[6U] = { 0U };
1387
1.21k
        fsqr0(rp, tx);
1388
1.21k
        fmul0(rp, rp, tx);
1389
1.21k
        p384_make_a_coeff(tmp);
1390
1.21k
        fmul0(tmp, tmp, tx);
1391
1.21k
        fadd0(rp, tmp, rp);
1392
1.21k
        p384_make_b_coeff(tmp);
1393
1.21k
        fadd0(rp, tmp, rp);
1394
1.21k
        fsqr0(ty, ty);
1395
1.21k
        uint64_t r = bn_is_eq_mask(ty, rp);
1396
1.21k
        uint64_t r0 = r;
1397
1.21k
        bool r1 = r0 == 0xFFFFFFFFFFFFFFFFULL;
1398
1.21k
        res = r1;
1399
1.21k
    }
1400
1.24k
    if (res) {
1401
1.11k
        uint64_t *px = p_aff;
1402
1.11k
        uint64_t *py = p_aff + 6U;
1403
1.11k
        uint64_t *rx = point_jac;
1404
1.11k
        uint64_t *ry = point_jac + 6U;
1405
1.11k
        uint64_t *rz = point_jac + 12U;
1406
1.11k
        to_mont(rx, px);
1407
1.11k
        to_mont(ry, py);
1408
1.11k
        p384_make_fone(rz);
1409
1.11k
    }
1410
1.24k
    bool res1 = res;
1411
1.24k
    return res1;
1412
1.24k
}
1413
1414
/**
1415
Private key validation.
1416
1417
  The function returns `true` if a private key is valid and `false` otherwise.
1418
1419
  The argument `private_key` points to 48 bytes of valid memory, i.e., uint8_t[48].
1420
1421
  The private key is valid:
1422
    • 0 < `private_key` < the order of the curve
1423
*/
1424
bool
1425
Hacl_P384_validate_private_key(uint8_t *private_key)
1426
604
{
1427
604
    uint64_t bn_sk[6U] = { 0U };
1428
604
    bn_from_bytes_be(bn_sk, private_key);
1429
604
    uint64_t tmp[6U] = { 0U };
1430
604
    p384_make_order(tmp);
1431
604
    uint64_t c = bn_sub(tmp, bn_sk, tmp);
1432
604
    uint64_t is_lt_order = FStar_UInt64_gte_mask(c, 0ULL) & ~FStar_UInt64_eq_mask(c, 0ULL);
1433
604
    uint64_t bn_zero[6U] = { 0U };
1434
604
    uint64_t res = bn_is_eq_mask(bn_sk, bn_zero);
1435
604
    uint64_t is_eq_zero = res;
1436
604
    uint64_t res0 = is_lt_order & ~is_eq_zero;
1437
604
    return res0 == 0xFFFFFFFFFFFFFFFFULL;
1438
604
}
1439
1440
/*******************************************************************************
1441
  Parsing and Serializing public keys.
1442
1443
  A public key is a point (x, y) on the P-384 NIST curve.
1444
1445
  The point can be represented in the following three ways.
1446
    • raw          = [ x || y ], 96 bytes
1447
    • uncompressed = [ 0x04 || x || y ], 97 bytes
1448
    • compressed   = [ (0x02 for even `y` and 0x03 for odd `y`) || x ], 33 bytes
1449
1450
*******************************************************************************/
1451
1452
/**
1453
Convert a public key from uncompressed to its raw form.
1454
1455
  The function returns `true` for successful conversion of a public key and `false` otherwise.
1456
1457
  The outparam `pk_raw` points to 96 bytes of valid memory, i.e., uint8_t[96].
1458
  The argument `pk` points to 97 bytes of valid memory, i.e., uint8_t[97].
1459
1460
  The function DOESN'T check whether (x, y) is a valid point.
1461
*/
1462
bool
1463
Hacl_P384_uncompressed_to_raw(uint8_t *pk, uint8_t *pk_raw)
1464
0
{
1465
0
    uint8_t pk0 = pk[0U];
1466
0
    if (pk0 != 0x04U) {
1467
0
        return false;
1468
0
    }
1469
0
    memcpy(pk_raw, pk + 1U, 96U * sizeof(uint8_t));
1470
0
    return true;
1471
0
}
1472
1473
/**
1474
Convert a public key from compressed to its raw form.
1475
1476
  The function returns `true` for successful conversion of a public key and `false` otherwise.
1477
1478
  The outparam `pk_raw` points to 96 bytes of valid memory, i.e., uint8_t[96].
1479
  The argument `pk` points to 33 bytes of valid memory, i.e., uint8_t[33].
1480
1481
  The function also checks whether (x, y) is a valid point.
1482
*/
1483
bool
1484
Hacl_P384_compressed_to_raw(uint8_t *pk, uint8_t *pk_raw)
1485
0
{
1486
0
    uint64_t xa[6U] = { 0U };
1487
0
    uint64_t ya[6U] = { 0U };
1488
0
    uint8_t *pk_xb = pk + 1U;
1489
0
    uint8_t s0 = pk[0U];
1490
0
    uint8_t s01 = s0;
1491
0
    bool b;
1492
0
    if (!(s01 == 0x02U || s01 == 0x03U)) {
1493
0
        b = false;
1494
0
    } else {
1495
0
        uint8_t *xb = pk + 1U;
1496
0
        bn_from_bytes_be(xa, xb);
1497
0
        uint64_t is_x_valid = bn_is_lt_prime_mask(xa);
1498
0
        bool is_x_valid1 = is_x_valid == 0xFFFFFFFFFFFFFFFFULL;
1499
0
        bool is_y_odd = s01 == 0x03U;
1500
0
        if (!is_x_valid1) {
1501
0
            b = false;
1502
0
        } else {
1503
0
            uint64_t y2M[6U] = { 0U };
1504
0
            uint64_t xM[6U] = { 0U };
1505
0
            uint64_t yM[6U] = { 0U };
1506
0
            to_mont(xM, xa);
1507
0
            uint64_t tmp[6U] = { 0U };
1508
0
            fsqr0(y2M, xM);
1509
0
            fmul0(y2M, y2M, xM);
1510
0
            p384_make_a_coeff(tmp);
1511
0
            fmul0(tmp, tmp, xM);
1512
0
            fadd0(y2M, tmp, y2M);
1513
0
            p384_make_b_coeff(tmp);
1514
0
            fadd0(y2M, tmp, y2M);
1515
0
            p384_fsqrt(yM, y2M);
1516
0
            from_mont(ya, yM);
1517
0
            fsqr0(yM, yM);
1518
0
            uint64_t r = bn_is_eq_mask(yM, y2M);
1519
0
            uint64_t r0 = r;
1520
0
            bool is_y_valid = r0 == 0xFFFFFFFFFFFFFFFFULL;
1521
0
            bool is_y_valid0 = is_y_valid;
1522
0
            if (!is_y_valid0) {
1523
0
                b = false;
1524
0
            } else {
1525
0
                uint64_t is_y_odd1 = ya[0U] & 1ULL;
1526
0
                bool is_y_odd2 = is_y_odd1 == 1ULL;
1527
0
                uint64_t zero[6U] = { 0U };
1528
0
                if (is_y_odd2 != is_y_odd) {
1529
0
                    fsub0(ya, zero, ya);
1530
0
                }
1531
0
                b = true;
1532
0
            }
1533
0
        }
1534
0
    }
1535
0
    if (b) {
1536
0
        memcpy(pk_raw, pk_xb, 48U * sizeof(uint8_t));
1537
0
        bn_to_bytes_be(pk_raw + 48U, ya);
1538
0
    }
1539
0
    return b;
1540
0
}
1541
1542
/**
1543
Convert a public key from raw to its uncompressed form.
1544
1545
  The outparam `pk` points to 97 bytes of valid memory, i.e., uint8_t[97].
1546
  The argument `pk_raw` points to 96 bytes of valid memory, i.e., uint8_t[96].
1547
1548
  The function DOESN'T check whether (x, y) is a valid point.
1549
*/
1550
void
1551
Hacl_P384_raw_to_uncompressed(uint8_t *pk_raw, uint8_t *pk)
1552
0
{
1553
0
    pk[0U] = 0x04U;
1554
0
    memcpy(pk + 1U, pk_raw, 96U * sizeof(uint8_t));
1555
0
}
1556
1557
/**
1558
Convert a public key from raw to its compressed form.
1559
1560
  The outparam `pk` points to 33 bytes of valid memory, i.e., uint8_t[33].
1561
  The argument `pk_raw` points to 96 bytes of valid memory, i.e., uint8_t[96].
1562
1563
  The function DOESN'T check whether (x, y) is a valid point.
1564
*/
1565
void
1566
Hacl_P384_raw_to_compressed(uint8_t *pk_raw, uint8_t *pk)
1567
0
{
1568
0
    uint8_t *pk_x = pk_raw;
1569
0
    uint8_t *pk_y = pk_raw + 48U;
1570
0
    uint64_t bn_f[6U] = { 0U };
1571
0
    bn_from_bytes_be(bn_f, pk_y);
1572
0
    uint64_t is_odd_f = bn_f[0U] & 1ULL;
1573
0
    pk[0U] = (uint32_t)(uint8_t)is_odd_f + 0x02U;
1574
0
    memcpy(pk + 1U, pk_x, 48U * sizeof(uint8_t));
1575
0
}
1576
1577
/******************/
1578
/* ECDH agreement */
1579
/******************/
1580
1581
/**
1582
Compute the public key from the private key.
1583
1584
  The function returns `true` if a private key is valid and `false` otherwise.
1585
1586
  The outparam `public_key`  points to 96 bytes of valid memory, i.e., uint8_t[96].
1587
  The argument `private_key` points to 48 bytes of valid memory, i.e., uint8_t[48].
1588
1589
  The private key is valid:
1590
    • 0 < `private_key` < the order of the curve.
1591
*/
1592
bool
1593
Hacl_P384_dh_initiator(uint8_t *public_key, uint8_t *private_key)
1594
938
{
1595
938
    uint64_t tmp[24U] = { 0U };
1596
938
    uint64_t *sk = tmp;
1597
938
    uint64_t *pk = tmp + 6U;
1598
938
    uint64_t is_sk_valid = load_qelem_conditional(sk, private_key);
1599
938
    point_mul_g(pk, sk);
1600
938
    uint64_t aff_p[12U] = { 0U };
1601
938
    uint64_t zinv[6U] = { 0U };
1602
938
    uint64_t *px = pk;
1603
938
    uint64_t *py0 = pk + 6U;
1604
938
    uint64_t *pz = pk + 12U;
1605
938
    uint64_t *x = aff_p;
1606
938
    uint64_t *y = aff_p + 6U;
1607
938
    p384_finv(zinv, pz);
1608
938
    fmul0(x, px, zinv);
1609
938
    fmul0(y, py0, zinv);
1610
938
    from_mont(x, x);
1611
938
    from_mont(y, y);
1612
938
    uint64_t *px0 = aff_p;
1613
938
    uint64_t *py = aff_p + 6U;
1614
938
    bn_to_bytes_be(public_key, px0);
1615
938
    bn_to_bytes_be(public_key + 48U, py);
1616
938
    return is_sk_valid == 0xFFFFFFFFFFFFFFFFULL;
1617
938
}
1618
1619
/**
1620
Execute the diffie-hellmann key exchange.
1621
1622
  The function returns `true` for successful creation of an ECDH shared secret and
1623
  `false` otherwise.
1624
1625
  The outparam `shared_secret` points to 96 bytes of valid memory, i.e., uint8_t[96].
1626
  The argument `their_pubkey` points to 96 bytes of valid memory, i.e., uint8_t[96].
1627
  The argument `private_key` points to 48 bytes of valid memory, i.e., uint8_t[48].
1628
1629
  The function also checks whether `private_key` and `their_pubkey` are valid.
1630
*/
1631
bool
1632
Hacl_P384_dh_responder(uint8_t *shared_secret, uint8_t *their_pubkey, uint8_t *private_key)
1633
392
{
1634
392
    uint64_t tmp[192U] = { 0U };
1635
392
    uint64_t *sk = tmp;
1636
392
    uint64_t *pk = tmp + 6U;
1637
392
    uint64_t p_aff[12U] = { 0U };
1638
392
    uint8_t *p_x = their_pubkey;
1639
392
    uint8_t *p_y = their_pubkey + 48U;
1640
392
    uint64_t *bn_p_x = p_aff;
1641
392
    uint64_t *bn_p_y = p_aff + 6U;
1642
392
    bn_from_bytes_be(bn_p_x, p_x);
1643
392
    bn_from_bytes_be(bn_p_y, p_y);
1644
392
    uint64_t *px0 = p_aff;
1645
392
    uint64_t *py0 = p_aff + 6U;
1646
392
    uint64_t lessX = bn_is_lt_prime_mask(px0);
1647
392
    uint64_t lessY = bn_is_lt_prime_mask(py0);
1648
392
    uint64_t res0 = lessX & lessY;
1649
392
    bool is_xy_valid = res0 == 0xFFFFFFFFFFFFFFFFULL;
1650
392
    bool res;
1651
392
    if (!is_xy_valid) {
1652
0
        res = false;
1653
392
    } else {
1654
392
        uint64_t rp[6U] = { 0U };
1655
392
        uint64_t tx[6U] = { 0U };
1656
392
        uint64_t ty[6U] = { 0U };
1657
392
        uint64_t *px = p_aff;
1658
392
        uint64_t *py = p_aff + 6U;
1659
392
        to_mont(tx, px);
1660
392
        to_mont(ty, py);
1661
392
        uint64_t tmp1[6U] = { 0U };
1662
392
        fsqr0(rp, tx);
1663
392
        fmul0(rp, rp, tx);
1664
392
        p384_make_a_coeff(tmp1);
1665
392
        fmul0(tmp1, tmp1, tx);
1666
392
        fadd0(rp, tmp1, rp);
1667
392
        p384_make_b_coeff(tmp1);
1668
392
        fadd0(rp, tmp1, rp);
1669
392
        fsqr0(ty, ty);
1670
392
        uint64_t r = bn_is_eq_mask(ty, rp);
1671
392
        uint64_t r0 = r;
1672
392
        bool r1 = r0 == 0xFFFFFFFFFFFFFFFFULL;
1673
392
        res = r1;
1674
392
    }
1675
392
    if (res) {
1676
392
        uint64_t *px = p_aff;
1677
392
        uint64_t *py = p_aff + 6U;
1678
392
        uint64_t *rx = pk;
1679
392
        uint64_t *ry = pk + 6U;
1680
392
        uint64_t *rz = pk + 12U;
1681
392
        to_mont(rx, px);
1682
392
        to_mont(ry, py);
1683
392
        p384_make_fone(rz);
1684
392
    }
1685
392
    bool is_pk_valid = res;
1686
392
    uint64_t is_sk_valid = load_qelem_conditional(sk, private_key);
1687
392
    uint64_t ss_proj[18U] = { 0U };
1688
392
    if (is_pk_valid) {
1689
392
        point_mul(ss_proj, sk, pk);
1690
392
        uint64_t aff_p[12U] = { 0U };
1691
392
        uint64_t zinv[6U] = { 0U };
1692
392
        uint64_t *px = ss_proj;
1693
392
        uint64_t *py1 = ss_proj + 6U;
1694
392
        uint64_t *pz = ss_proj + 12U;
1695
392
        uint64_t *x = aff_p;
1696
392
        uint64_t *y = aff_p + 6U;
1697
392
        p384_finv(zinv, pz);
1698
392
        fmul0(x, px, zinv);
1699
392
        fmul0(y, py1, zinv);
1700
392
        from_mont(x, x);
1701
392
        from_mont(y, y);
1702
392
        uint64_t *px1 = aff_p;
1703
392
        uint64_t *py = aff_p + 6U;
1704
392
        bn_to_bytes_be(shared_secret, px1);
1705
392
        bn_to_bytes_be(shared_secret + 48U, py);
1706
392
    }
1707
392
    return is_sk_valid == 0xFFFFFFFFFFFFFFFFULL && is_pk_valid;
1708
392
}