Coverage Report

Created: 2025-04-22 06:15

/src/nss/lib/freebl/verified/Hacl_P256.c
Line
Count
Source (jump to first uncovered line)
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 "internal/Hacl_P256.h"
26
27
#include "internal/Hacl_P256_PrecompTable.h"
28
#include "internal/Hacl_Krmllib.h"
29
#include "internal/Hacl_Bignum_Base.h"
30
#include "lib_intrinsics.h"
31
32
static inline uint64_t
33
bn_is_zero_mask4(uint64_t *f)
34
67.9k
{
35
67.9k
    uint64_t bn_zero[4U] = { 0U };
36
67.9k
    uint64_t mask = (uint64_t)0xFFFFFFFFFFFFFFFFU;
37
67.9k
    KRML_MAYBE_FOR4(i,
38
67.9k
                    (uint32_t)0U,
39
67.9k
                    (uint32_t)4U,
40
67.9k
                    (uint32_t)1U,
41
67.9k
                    uint64_t uu____0 = FStar_UInt64_eq_mask(f[i], bn_zero[i]);
42
67.9k
                    mask = uu____0 & mask;);
43
67.9k
    uint64_t mask1 = mask;
44
67.9k
    uint64_t res = mask1;
45
67.9k
    return res;
46
67.9k
}
47
48
static inline bool
49
bn_is_zero_vartime4(uint64_t *f)
50
104
{
51
104
    uint64_t m = bn_is_zero_mask4(f);
52
104
    return m == (uint64_t)0xFFFFFFFFFFFFFFFFU;
53
104
}
54
55
static inline uint64_t
56
bn_is_eq_mask4(uint64_t *a, uint64_t *b)
57
68.1k
{
58
68.1k
    uint64_t mask = (uint64_t)0xFFFFFFFFFFFFFFFFU;
59
68.1k
    KRML_MAYBE_FOR4(i,
60
68.1k
                    (uint32_t)0U,
61
68.1k
                    (uint32_t)4U,
62
68.1k
                    (uint32_t)1U,
63
68.1k
                    uint64_t uu____0 = FStar_UInt64_eq_mask(a[i], b[i]);
64
68.1k
                    mask = uu____0 & mask;);
65
68.1k
    uint64_t mask1 = mask;
66
68.1k
    return mask1;
67
68.1k
}
68
69
static inline bool
70
bn_is_eq_vartime4(uint64_t *a, uint64_t *b)
71
104
{
72
104
    uint64_t m = bn_is_eq_mask4(a, b);
73
104
    return m == (uint64_t)0xFFFFFFFFFFFFFFFFU;
74
104
}
75
76
static inline void
77
bn_cmovznz4(uint64_t *res, uint64_t cin, uint64_t *x, uint64_t *y)
78
212
{
79
212
    uint64_t mask = ~FStar_UInt64_eq_mask(cin, (uint64_t)0U);
80
212
    KRML_MAYBE_FOR4(i,
81
212
                    (uint32_t)0U,
82
212
                    (uint32_t)4U,
83
212
                    (uint32_t)1U,
84
212
                    uint64_t *os = res;
85
212
                    uint64_t uu____0 = x[i];
86
212
                    uint64_t x1 = uu____0 ^ (mask & (y[i] ^ uu____0));
87
212
                    os[i] = x1;);
88
212
}
89
90
static inline void
91
bn_add_mod4(uint64_t *res, uint64_t *n, uint64_t *x, uint64_t *y)
92
172M
{
93
172M
    uint64_t c0 = (uint64_t)0U;
94
172M
    {
95
172M
        uint64_t t1 = x[(uint32_t)4U * (uint32_t)0U];
96
172M
        uint64_t t20 = y[(uint32_t)4U * (uint32_t)0U];
97
172M
        uint64_t *res_i0 = res + (uint32_t)4U * (uint32_t)0U;
98
172M
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, t1, t20, res_i0);
99
172M
        uint64_t t10 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
100
172M
        uint64_t t21 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
101
172M
        uint64_t *res_i1 = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
102
172M
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, t10, t21, res_i1);
103
172M
        uint64_t t11 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
104
172M
        uint64_t t22 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
105
172M
        uint64_t *res_i2 = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
106
172M
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, t11, t22, res_i2);
107
172M
        uint64_t t12 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
108
172M
        uint64_t t2 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
109
172M
        uint64_t *res_i = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
110
172M
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, t12, t2, res_i);
111
172M
    }
112
172M
    uint64_t c00 = c0;
113
172M
    uint64_t tmp[4U] = { 0U };
114
172M
    uint64_t c = (uint64_t)0U;
115
172M
    {
116
172M
        uint64_t t1 = res[(uint32_t)4U * (uint32_t)0U];
117
172M
        uint64_t t20 = n[(uint32_t)4U * (uint32_t)0U];
118
172M
        uint64_t *res_i0 = tmp + (uint32_t)4U * (uint32_t)0U;
119
172M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t20, res_i0);
120
172M
        uint64_t t10 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
121
172M
        uint64_t t21 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
122
172M
        uint64_t *res_i1 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
123
172M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t10, t21, res_i1);
124
172M
        uint64_t t11 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
125
172M
        uint64_t t22 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
126
172M
        uint64_t *res_i2 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
127
172M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t11, t22, res_i2);
128
172M
        uint64_t t12 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
129
172M
        uint64_t t2 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
130
172M
        uint64_t *res_i = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
131
172M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t12, t2, res_i);
132
172M
    }
133
172M
    uint64_t c1 = c;
134
172M
    uint64_t c2 = c00 - c1;
135
172M
    KRML_MAYBE_FOR4(i,
136
172M
                    (uint32_t)0U,
137
172M
                    (uint32_t)4U,
138
172M
                    (uint32_t)1U,
139
172M
                    uint64_t *os = res;
140
172M
                    uint64_t x1 = (c2 & res[i]) | (~c2 & tmp[i]);
141
172M
                    os[i] = x1;);
142
172M
}
143
144
static inline uint64_t
145
bn_sub4(uint64_t *res, uint64_t *x, uint64_t *y)
146
204k
{
147
204k
    uint64_t c = (uint64_t)0U;
148
204k
    {
149
204k
        uint64_t t1 = x[(uint32_t)4U * (uint32_t)0U];
150
204k
        uint64_t t20 = y[(uint32_t)4U * (uint32_t)0U];
151
204k
        uint64_t *res_i0 = res + (uint32_t)4U * (uint32_t)0U;
152
204k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t20, res_i0);
153
204k
        uint64_t t10 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
154
204k
        uint64_t t21 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
155
204k
        uint64_t *res_i1 = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
156
204k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t10, t21, res_i1);
157
204k
        uint64_t t11 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
158
204k
        uint64_t t22 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
159
204k
        uint64_t *res_i2 = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
160
204k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t11, t22, res_i2);
161
204k
        uint64_t t12 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
162
204k
        uint64_t t2 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
163
204k
        uint64_t *res_i = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
164
204k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t12, t2, res_i);
165
204k
    }
166
204k
    uint64_t c0 = c;
167
204k
    return c0;
168
204k
}
169
170
static inline void
171
bn_sub_mod4(uint64_t *res, uint64_t *n, uint64_t *x, uint64_t *y)
172
71.8M
{
173
71.8M
    uint64_t c0 = (uint64_t)0U;
174
71.8M
    {
175
71.8M
        uint64_t t1 = x[(uint32_t)4U * (uint32_t)0U];
176
71.8M
        uint64_t t20 = y[(uint32_t)4U * (uint32_t)0U];
177
71.8M
        uint64_t *res_i0 = res + (uint32_t)4U * (uint32_t)0U;
178
71.8M
        c0 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c0, t1, t20, res_i0);
179
71.8M
        uint64_t t10 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
180
71.8M
        uint64_t t21 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
181
71.8M
        uint64_t *res_i1 = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
182
71.8M
        c0 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c0, t10, t21, res_i1);
183
71.8M
        uint64_t t11 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
184
71.8M
        uint64_t t22 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
185
71.8M
        uint64_t *res_i2 = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
186
71.8M
        c0 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c0, t11, t22, res_i2);
187
71.8M
        uint64_t t12 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
188
71.8M
        uint64_t t2 = y[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
189
71.8M
        uint64_t *res_i = res + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
190
71.8M
        c0 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c0, t12, t2, res_i);
191
71.8M
    }
192
71.8M
    uint64_t c00 = c0;
193
71.8M
    uint64_t tmp[4U] = { 0U };
194
71.8M
    uint64_t c = (uint64_t)0U;
195
71.8M
    {
196
71.8M
        uint64_t t1 = res[(uint32_t)4U * (uint32_t)0U];
197
71.8M
        uint64_t t20 = n[(uint32_t)4U * (uint32_t)0U];
198
71.8M
        uint64_t *res_i0 = tmp + (uint32_t)4U * (uint32_t)0U;
199
71.8M
        c = Lib_IntTypes_Intrinsics_add_carry_u64(c, t1, t20, res_i0);
200
71.8M
        uint64_t t10 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
201
71.8M
        uint64_t t21 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
202
71.8M
        uint64_t *res_i1 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
203
71.8M
        c = Lib_IntTypes_Intrinsics_add_carry_u64(c, t10, t21, res_i1);
204
71.8M
        uint64_t t11 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
205
71.8M
        uint64_t t22 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
206
71.8M
        uint64_t *res_i2 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
207
71.8M
        c = Lib_IntTypes_Intrinsics_add_carry_u64(c, t11, t22, res_i2);
208
71.8M
        uint64_t t12 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
209
71.8M
        uint64_t t2 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
210
71.8M
        uint64_t *res_i = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
211
71.8M
        c = Lib_IntTypes_Intrinsics_add_carry_u64(c, t12, t2, res_i);
212
71.8M
    }
213
71.8M
    uint64_t c1 = c;
214
71.8M
    KRML_HOST_IGNORE(c1);
215
71.8M
    uint64_t c2 = (uint64_t)0U - c00;
216
71.8M
    KRML_MAYBE_FOR4(i,
217
71.8M
                    (uint32_t)0U,
218
71.8M
                    (uint32_t)4U,
219
71.8M
                    (uint32_t)1U,
220
71.8M
                    uint64_t *os = res;
221
71.8M
                    uint64_t x1 = (c2 & tmp[i]) | (~c2 & res[i]);
222
71.8M
                    os[i] = x1;);
223
71.8M
}
224
225
static inline void
226
bn_mul4(uint64_t *res, uint64_t *x, uint64_t *y)
227
117M
{
228
117M
    memset(res, 0U, (uint32_t)8U * sizeof(uint64_t));
229
117M
    KRML_MAYBE_FOR4(
230
117M
        i0,
231
117M
        (uint32_t)0U,
232
117M
        (uint32_t)4U,
233
117M
        (uint32_t)1U,
234
117M
        uint64_t bj = y[i0];
235
117M
        uint64_t *res_j = res + i0;
236
117M
        uint64_t c = (uint64_t)0U;
237
117M
        {
238
117M
            uint64_t a_i = x[(uint32_t)4U * (uint32_t)0U];
239
117M
            uint64_t *res_i0 = res_j + (uint32_t)4U * (uint32_t)0U;
240
117M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, bj, c, res_i0);
241
117M
            uint64_t a_i0 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
242
117M
            uint64_t *res_i1 = res_j + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
243
117M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, bj, c, res_i1);
244
117M
            uint64_t a_i1 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
245
117M
            uint64_t *res_i2 = res_j + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
246
117M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, bj, c, res_i2);
247
117M
            uint64_t a_i2 = x[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
248
117M
            uint64_t *res_i = res_j + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
249
117M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, bj, c, res_i);
250
117M
        } uint64_t r = c;
251
117M
        res[(uint32_t)4U + i0] = r;);
252
117M
}
253
254
static inline void
255
bn_sqr4(uint64_t *res, uint64_t *x)
256
33.8M
{
257
33.8M
    memset(res, 0U, (uint32_t)8U * sizeof(uint64_t));
258
33.8M
    KRML_MAYBE_FOR4(
259
33.8M
        i0,
260
33.8M
        (uint32_t)0U,
261
33.8M
        (uint32_t)4U,
262
33.8M
        (uint32_t)1U,
263
33.8M
        uint64_t *ab = x;
264
33.8M
        uint64_t a_j = x[i0];
265
33.8M
        uint64_t *res_j = res + i0;
266
33.8M
        uint64_t c = (uint64_t)0U;
267
33.8M
        for (uint32_t i = (uint32_t)0U; i < i0 / (uint32_t)4U; i++) {
268
33.8M
            uint64_t a_i = ab[(uint32_t)4U * i];
269
33.8M
            uint64_t *res_i0 = res_j + (uint32_t)4U * i;
270
33.8M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, a_j, c, res_i0);
271
33.8M
            uint64_t a_i0 = ab[(uint32_t)4U * i + (uint32_t)1U];
272
33.8M
            uint64_t *res_i1 = res_j + (uint32_t)4U * i + (uint32_t)1U;
273
33.8M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, a_j, c, res_i1);
274
33.8M
            uint64_t a_i1 = ab[(uint32_t)4U * i + (uint32_t)2U];
275
33.8M
            uint64_t *res_i2 = res_j + (uint32_t)4U * i + (uint32_t)2U;
276
33.8M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, a_j, c, res_i2);
277
33.8M
            uint64_t a_i2 = ab[(uint32_t)4U * i + (uint32_t)3U];
278
33.8M
            uint64_t *res_i = res_j + (uint32_t)4U * i + (uint32_t)3U;
279
33.8M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, a_j, c, res_i);
280
33.8M
        } for (uint32_t i = i0 / (uint32_t)4U * (uint32_t)4U; i < i0; i++) {
281
33.8M
            uint64_t a_i = ab[i];
282
33.8M
            uint64_t *res_i = res_j + i;
283
33.8M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, a_j, c, res_i);
284
33.8M
        } uint64_t r = c;
285
33.8M
        res[i0 + i0] = r;);
286
33.8M
    uint64_t c0 = Hacl_Bignum_Addition_bn_add_eq_len_u64((uint32_t)8U, res, res, res);
287
33.8M
    KRML_HOST_IGNORE(c0);
288
33.8M
    uint64_t tmp[8U] = { 0U };
289
33.8M
    KRML_MAYBE_FOR4(i,
290
33.8M
                    (uint32_t)0U,
291
33.8M
                    (uint32_t)4U,
292
33.8M
                    (uint32_t)1U,
293
33.8M
                    FStar_UInt128_uint128 res1 = FStar_UInt128_mul_wide(x[i], x[i]);
294
33.8M
                    uint64_t hi = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(res1, (uint32_t)64U));
295
33.8M
                    uint64_t lo = FStar_UInt128_uint128_to_uint64(res1);
296
33.8M
                    tmp[(uint32_t)2U * i] = lo;
297
33.8M
                    tmp[(uint32_t)2U * i + (uint32_t)1U] = hi;);
298
33.8M
    uint64_t c1 = Hacl_Bignum_Addition_bn_add_eq_len_u64((uint32_t)8U, res, tmp, res);
299
33.8M
    KRML_HOST_IGNORE(c1);
300
33.8M
}
301
302
static inline void
303
bn_to_bytes_be4(uint8_t *res, uint64_t *f)
304
90.1k
{
305
90.1k
    uint8_t tmp[32U] = { 0U };
306
90.1k
    KRML_HOST_IGNORE(tmp);
307
90.1k
    KRML_MAYBE_FOR4(i,
308
90.1k
                    (uint32_t)0U,
309
90.1k
                    (uint32_t)4U,
310
90.1k
                    (uint32_t)1U,
311
90.1k
                    store64_be(res + i * (uint32_t)8U, f[(uint32_t)4U - i - (uint32_t)1U]););
312
90.1k
}
313
314
static inline void
315
bn_from_bytes_be4(uint64_t *res, uint8_t *b)
316
204k
{
317
204k
    KRML_MAYBE_FOR4(i,
318
204k
                    (uint32_t)0U,
319
204k
                    (uint32_t)4U,
320
204k
                    (uint32_t)1U,
321
204k
                    uint64_t *os = res;
322
204k
                    uint64_t u = load64_be(b + ((uint32_t)4U - i - (uint32_t)1U) * (uint32_t)8U);
323
204k
                    uint64_t x = u;
324
204k
                    os[i] = x;);
325
204k
}
326
327
static inline void
328
bn2_to_bytes_be4(uint8_t *res, uint64_t *x, uint64_t *y)
329
45.0k
{
330
45.0k
    bn_to_bytes_be4(res, x);
331
45.0k
    bn_to_bytes_be4(res + (uint32_t)32U, y);
332
45.0k
}
333
334
static inline void
335
make_prime(uint64_t *n)
336
395M
{
337
395M
    n[0U] = (uint64_t)0xffffffffffffffffU;
338
395M
    n[1U] = (uint64_t)0xffffffffU;
339
395M
    n[2U] = (uint64_t)0x0U;
340
395M
    n[3U] = (uint64_t)0xffffffff00000001U;
341
395M
}
342
343
static inline void
344
make_order(uint64_t *n)
345
98.8k
{
346
98.8k
    n[0U] = (uint64_t)0xf3b9cac2fc632551U;
347
98.8k
    n[1U] = (uint64_t)0xbce6faada7179e84U;
348
98.8k
    n[2U] = (uint64_t)0xffffffffffffffffU;
349
98.8k
    n[3U] = (uint64_t)0xffffffff00000000U;
350
98.8k
}
351
352
static inline void
353
make_a_coeff(uint64_t *a)
354
68.0k
{
355
68.0k
    a[0U] = (uint64_t)0xfffffffffffffffcU;
356
68.0k
    a[1U] = (uint64_t)0x3ffffffffU;
357
68.0k
    a[2U] = (uint64_t)0x0U;
358
68.0k
    a[3U] = (uint64_t)0xfffffffc00000004U;
359
68.0k
}
360
361
static inline void
362
make_b_coeff(uint64_t *b)
363
20.9M
{
364
20.9M
    b[0U] = (uint64_t)0xd89cdf6229c4bddfU;
365
20.9M
    b[1U] = (uint64_t)0xacf005cd78843090U;
366
20.9M
    b[2U] = (uint64_t)0xe5a220abf7212ed6U;
367
20.9M
    b[3U] = (uint64_t)0xdc30061d04874834U;
368
20.9M
}
369
370
static inline void
371
make_g_x(uint64_t *n)
372
22.6k
{
373
22.6k
    n[0U] = (uint64_t)0x79e730d418a9143cU;
374
22.6k
    n[1U] = (uint64_t)0x75ba95fc5fedb601U;
375
22.6k
    n[2U] = (uint64_t)0x79fb732b77622510U;
376
22.6k
    n[3U] = (uint64_t)0x18905f76a53755c6U;
377
22.6k
}
378
379
static inline void
380
make_g_y(uint64_t *n)
381
22.6k
{
382
22.6k
    n[0U] = (uint64_t)0xddf25357ce95560aU;
383
22.6k
    n[1U] = (uint64_t)0x8b4ab8e4ba19e45cU;
384
22.6k
    n[2U] = (uint64_t)0xd2e88688dd21f325U;
385
22.6k
    n[3U] = (uint64_t)0x8571ff1825885d85U;
386
22.6k
}
387
388
static inline void
389
make_fmont_R2(uint64_t *n)
390
271k
{
391
271k
    n[0U] = (uint64_t)0x3U;
392
271k
    n[1U] = (uint64_t)0xfffffffbffffffffU;
393
271k
    n[2U] = (uint64_t)0xfffffffffffffffeU;
394
271k
    n[3U] = (uint64_t)0x4fffffffdU;
395
271k
}
396
397
static inline void
398
make_fzero(uint64_t *n)
399
135k
{
400
135k
    n[0U] = (uint64_t)0U;
401
135k
    n[1U] = (uint64_t)0U;
402
135k
    n[2U] = (uint64_t)0U;
403
135k
    n[3U] = (uint64_t)0U;
404
135k
}
405
406
static inline void
407
make_fone(uint64_t *n)
408
158k
{
409
158k
    n[0U] = (uint64_t)0x1U;
410
158k
    n[1U] = (uint64_t)0xffffffff00000000U;
411
158k
    n[2U] = (uint64_t)0xffffffffffffffffU;
412
158k
    n[3U] = (uint64_t)0xfffffffeU;
413
158k
}
414
415
static inline uint64_t
416
bn_is_lt_prime_mask4(uint64_t *f)
417
136k
{
418
136k
    uint64_t tmp[4U] = { 0U };
419
136k
    make_prime(tmp);
420
136k
    uint64_t c = bn_sub4(tmp, f, tmp);
421
136k
    return (uint64_t)0U - c;
422
136k
}
423
424
static inline uint64_t
425
feq_mask(uint64_t *a, uint64_t *b)
426
68.0k
{
427
68.0k
    uint64_t r = bn_is_eq_mask4(a, b);
428
68.0k
    return r;
429
68.0k
}
430
431
static inline void
432
fadd0(uint64_t *res, uint64_t *x, uint64_t *y)
433
172M
{
434
172M
    uint64_t n[4U] = { 0U };
435
172M
    make_prime(n);
436
172M
    bn_add_mod4(res, n, x, y);
437
172M
}
438
439
static inline void
440
fsub0(uint64_t *res, uint64_t *x, uint64_t *y)
441
71.8M
{
442
71.8M
    uint64_t n[4U] = { 0U };
443
71.8M
    make_prime(n);
444
71.8M
    bn_sub_mod4(res, n, x, y);
445
71.8M
}
446
447
static inline void
448
fnegate_conditional_vartime(uint64_t *f, bool is_negate)
449
0
{
450
0
    uint64_t zero[4U] = { 0U };
451
0
    if (is_negate) {
452
0
        fsub0(f, zero, f);
453
0
    }
454
0
}
455
456
static inline void
457
mont_reduction(uint64_t *res, uint64_t *x)
458
151M
{
459
151M
    uint64_t n[4U] = { 0U };
460
151M
    make_prime(n);
461
151M
    uint64_t c0 = (uint64_t)0U;
462
151M
    KRML_MAYBE_FOR4(
463
151M
        i0,
464
151M
        (uint32_t)0U,
465
151M
        (uint32_t)4U,
466
151M
        (uint32_t)1U,
467
151M
        uint64_t qj = (uint64_t)1U * x[i0];
468
151M
        uint64_t *res_j0 = x + i0;
469
151M
        uint64_t c = (uint64_t)0U;
470
151M
        {
471
151M
            uint64_t a_i = n[(uint32_t)4U * (uint32_t)0U];
472
151M
            uint64_t *res_i0 = res_j0 + (uint32_t)4U * (uint32_t)0U;
473
151M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, qj, c, res_i0);
474
151M
            uint64_t a_i0 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
475
151M
            uint64_t *res_i1 = res_j0 + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
476
151M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, qj, c, res_i1);
477
151M
            uint64_t a_i1 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
478
151M
            uint64_t *res_i2 = res_j0 + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
479
151M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, qj, c, res_i2);
480
151M
            uint64_t a_i2 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
481
151M
            uint64_t *res_i = res_j0 + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
482
151M
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, qj, c, res_i);
483
151M
        } uint64_t r = c;
484
151M
        uint64_t c1 = r;
485
151M
        uint64_t *resb = x + (uint32_t)4U + i0;
486
151M
        uint64_t res_j = x[(uint32_t)4U + i0];
487
151M
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, c1, res_j, resb););
488
151M
    memcpy(res, x + (uint32_t)4U, (uint32_t)4U * sizeof(uint64_t));
489
151M
    uint64_t c00 = c0;
490
151M
    uint64_t tmp[4U] = { 0U };
491
151M
    uint64_t c = (uint64_t)0U;
492
151M
    {
493
151M
        uint64_t t1 = res[(uint32_t)4U * (uint32_t)0U];
494
151M
        uint64_t t20 = n[(uint32_t)4U * (uint32_t)0U];
495
151M
        uint64_t *res_i0 = tmp + (uint32_t)4U * (uint32_t)0U;
496
151M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t20, res_i0);
497
151M
        uint64_t t10 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
498
151M
        uint64_t t21 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
499
151M
        uint64_t *res_i1 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
500
151M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t10, t21, res_i1);
501
151M
        uint64_t t11 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
502
151M
        uint64_t t22 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
503
151M
        uint64_t *res_i2 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
504
151M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t11, t22, res_i2);
505
151M
        uint64_t t12 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
506
151M
        uint64_t t2 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
507
151M
        uint64_t *res_i = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
508
151M
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t12, t2, res_i);
509
151M
    }
510
151M
    uint64_t c1 = c;
511
151M
    uint64_t c2 = c00 - c1;
512
151M
    KRML_MAYBE_FOR4(i,
513
151M
                    (uint32_t)0U,
514
151M
                    (uint32_t)4U,
515
151M
                    (uint32_t)1U,
516
151M
                    uint64_t *os = res;
517
151M
                    uint64_t x1 = (c2 & res[i]) | (~c2 & tmp[i]);
518
151M
                    os[i] = x1;);
519
151M
}
520
521
static inline void
522
fmul0(uint64_t *res, uint64_t *x, uint64_t *y)
523
117M
{
524
117M
    uint64_t tmp[8U] = { 0U };
525
117M
    bn_mul4(tmp, x, y);
526
117M
    mont_reduction(res, tmp);
527
117M
}
528
529
static inline void
530
fsqr0(uint64_t *res, uint64_t *x)
531
33.8M
{
532
33.8M
    uint64_t tmp[8U] = { 0U };
533
33.8M
    bn_sqr4(tmp, x);
534
33.8M
    mont_reduction(res, tmp);
535
33.8M
}
536
537
static inline void
538
from_mont(uint64_t *res, uint64_t *a)
539
90.2k
{
540
90.2k
    uint64_t tmp[8U] = { 0U };
541
90.2k
    memcpy(tmp, a, (uint32_t)4U * sizeof(uint64_t));
542
90.2k
    mont_reduction(res, tmp);
543
90.2k
}
544
545
static inline void
546
to_mont(uint64_t *res, uint64_t *a)
547
271k
{
548
271k
    uint64_t r2modn[4U] = { 0U };
549
271k
    make_fmont_R2(r2modn);
550
271k
    fmul0(res, a, r2modn);
551
271k
}
552
553
static inline void
554
fmul_by_b_coeff(uint64_t *res, uint64_t *x)
555
20.8M
{
556
20.8M
    uint64_t b_coeff[4U] = { 0U };
557
20.8M
    make_b_coeff(b_coeff);
558
20.8M
    fmul0(res, b_coeff, x);
559
20.8M
}
560
561
static inline void
562
fcube(uint64_t *res, uint64_t *x)
563
68.0k
{
564
68.0k
    fsqr0(res, x);
565
68.0k
    fmul0(res, res, x);
566
68.0k
}
567
568
static inline void
569
finv(uint64_t *res, uint64_t *a)
570
45.1k
{
571
45.1k
    uint64_t tmp[16U] = { 0U };
572
45.1k
    uint64_t *x30 = tmp;
573
45.1k
    uint64_t *x2 = tmp + (uint32_t)4U;
574
45.1k
    uint64_t *tmp1 = tmp + (uint32_t)8U;
575
45.1k
    uint64_t *tmp2 = tmp + (uint32_t)12U;
576
45.1k
    memcpy(x2, a, (uint32_t)4U * sizeof(uint64_t));
577
45.1k
    {
578
45.1k
        fsqr0(x2, x2);
579
45.1k
    }
580
45.1k
    fmul0(x2, x2, a);
581
45.1k
    memcpy(x30, x2, (uint32_t)4U * sizeof(uint64_t));
582
45.1k
    {
583
45.1k
        fsqr0(x30, x30);
584
45.1k
    }
585
45.1k
    fmul0(x30, x30, a);
586
45.1k
    memcpy(tmp1, x30, (uint32_t)4U * sizeof(uint64_t));
587
45.1k
    KRML_MAYBE_FOR3(i, (uint32_t)0U, (uint32_t)3U, (uint32_t)1U, fsqr0(tmp1, tmp1););
588
45.1k
    fmul0(tmp1, tmp1, x30);
589
45.1k
    memcpy(tmp2, tmp1, (uint32_t)4U * sizeof(uint64_t));
590
45.1k
    KRML_MAYBE_FOR6(i, (uint32_t)0U, (uint32_t)6U, (uint32_t)1U, fsqr0(tmp2, tmp2););
591
45.1k
    fmul0(tmp2, tmp2, tmp1);
592
45.1k
    memcpy(tmp1, tmp2, (uint32_t)4U * sizeof(uint64_t));
593
45.1k
    KRML_MAYBE_FOR3(i, (uint32_t)0U, (uint32_t)3U, (uint32_t)1U, fsqr0(tmp1, tmp1););
594
45.1k
    fmul0(tmp1, tmp1, x30);
595
45.1k
    memcpy(x30, tmp1, (uint32_t)4U * sizeof(uint64_t));
596
45.1k
    KRML_MAYBE_FOR15(i, (uint32_t)0U, (uint32_t)15U, (uint32_t)1U, fsqr0(x30, x30););
597
45.1k
    fmul0(x30, x30, tmp1);
598
45.1k
    memcpy(tmp1, x30, (uint32_t)4U * sizeof(uint64_t));
599
45.1k
    KRML_MAYBE_FOR2(i, (uint32_t)0U, (uint32_t)2U, (uint32_t)1U, fsqr0(tmp1, tmp1););
600
45.1k
    fmul0(tmp1, tmp1, x2);
601
45.1k
    memcpy(x2, tmp1, (uint32_t)4U * sizeof(uint64_t));
602
1.49M
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)32U; i++) {
603
1.44M
        fsqr0(x2, x2);
604
1.44M
    }
605
45.1k
    fmul0(x2, x2, a);
606
5.82M
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)128U; i++) {
607
5.78M
        fsqr0(x2, x2);
608
5.78M
    }
609
45.1k
    fmul0(x2, x2, tmp1);
610
1.49M
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)32U; i++) {
611
1.44M
        fsqr0(x2, x2);
612
1.44M
    }
613
45.1k
    fmul0(x2, x2, tmp1);
614
1.40M
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)30U; i++) {
615
1.35M
        fsqr0(x2, x2);
616
1.35M
    }
617
45.1k
    fmul0(x2, x2, x30);
618
45.1k
    KRML_MAYBE_FOR2(i, (uint32_t)0U, (uint32_t)2U, (uint32_t)1U, fsqr0(x2, x2););
619
45.1k
    fmul0(tmp1, x2, a);
620
45.1k
    memcpy(res, tmp1, (uint32_t)4U * sizeof(uint64_t));
621
45.1k
}
622
623
static inline void
624
fsqrt(uint64_t *res, uint64_t *a)
625
0
{
626
0
    uint64_t tmp[8U] = { 0U };
627
0
    uint64_t *tmp1 = tmp;
628
0
    uint64_t *tmp2 = tmp + (uint32_t)4U;
629
0
    memcpy(tmp1, a, (uint32_t)4U * sizeof(uint64_t));
630
0
    {
631
0
        fsqr0(tmp1, tmp1);
632
0
    }
633
0
    fmul0(tmp1, tmp1, a);
634
0
    memcpy(tmp2, tmp1, (uint32_t)4U * sizeof(uint64_t));
635
0
    KRML_MAYBE_FOR2(i, (uint32_t)0U, (uint32_t)2U, (uint32_t)1U, fsqr0(tmp2, tmp2););
636
0
    fmul0(tmp2, tmp2, tmp1);
637
0
    memcpy(tmp1, tmp2, (uint32_t)4U * sizeof(uint64_t));
638
0
    KRML_MAYBE_FOR4(i, (uint32_t)0U, (uint32_t)4U, (uint32_t)1U, fsqr0(tmp1, tmp1););
639
0
    fmul0(tmp1, tmp1, tmp2);
640
0
    memcpy(tmp2, tmp1, (uint32_t)4U * sizeof(uint64_t));
641
0
    KRML_MAYBE_FOR8(i, (uint32_t)0U, (uint32_t)8U, (uint32_t)1U, fsqr0(tmp2, tmp2););
642
0
    fmul0(tmp2, tmp2, tmp1);
643
0
    memcpy(tmp1, tmp2, (uint32_t)4U * sizeof(uint64_t));
644
0
    KRML_MAYBE_FOR16(i, (uint32_t)0U, (uint32_t)16U, (uint32_t)1U, fsqr0(tmp1, tmp1););
645
0
    fmul0(tmp1, tmp1, tmp2);
646
0
    memcpy(tmp2, tmp1, (uint32_t)4U * sizeof(uint64_t));
647
0
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)32U; i++) {
648
0
        fsqr0(tmp2, tmp2);
649
0
    }
650
0
    fmul0(tmp2, tmp2, a);
651
0
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)96U; i++) {
652
0
        fsqr0(tmp2, tmp2);
653
0
    }
654
0
    fmul0(tmp2, tmp2, a);
655
0
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)94U; i++) {
656
0
        fsqr0(tmp2, tmp2);
657
0
    }
658
0
    memcpy(res, tmp2, (uint32_t)4U * sizeof(uint64_t));
659
0
}
660
661
static inline void
662
make_base_point(uint64_t *p)
663
22.6k
{
664
22.6k
    uint64_t *x = p;
665
22.6k
    uint64_t *y = p + (uint32_t)4U;
666
22.6k
    uint64_t *z = p + (uint32_t)8U;
667
22.6k
    make_g_x(x);
668
22.6k
    make_g_y(y);
669
22.6k
    make_fone(z);
670
22.6k
}
671
672
static inline void
673
make_point_at_inf(uint64_t *p)
674
67.6k
{
675
67.6k
    uint64_t *x = p;
676
67.6k
    uint64_t *y = p + (uint32_t)4U;
677
67.6k
    uint64_t *z = p + (uint32_t)8U;
678
67.6k
    make_fzero(x);
679
67.6k
    make_fone(y);
680
67.6k
    make_fzero(z);
681
67.6k
}
682
683
static inline bool
684
is_point_at_inf_vartime(uint64_t *p)
685
104
{
686
104
    uint64_t *pz = p + (uint32_t)8U;
687
104
    return bn_is_zero_vartime4(pz);
688
104
}
689
690
static inline void
691
to_aff_point(uint64_t *res, uint64_t *p)
692
45.0k
{
693
45.0k
    uint64_t zinv[4U] = { 0U };
694
45.0k
    uint64_t *px = p;
695
45.0k
    uint64_t *py = p + (uint32_t)4U;
696
45.0k
    uint64_t *pz = p + (uint32_t)8U;
697
45.0k
    uint64_t *x = res;
698
45.0k
    uint64_t *y = res + (uint32_t)4U;
699
45.0k
    finv(zinv, pz);
700
45.0k
    fmul0(x, px, zinv);
701
45.0k
    fmul0(y, py, zinv);
702
45.0k
    from_mont(x, x);
703
45.0k
    from_mont(y, y);
704
45.0k
}
705
706
static inline void
707
to_aff_point_x(uint64_t *res, uint64_t *p)
708
104
{
709
104
    uint64_t zinv[4U] = { 0U };
710
104
    uint64_t *px = p;
711
104
    uint64_t *pz = p + (uint32_t)8U;
712
104
    finv(zinv, pz);
713
104
    fmul0(res, px, zinv);
714
104
    from_mont(res, res);
715
104
}
716
717
static inline void
718
to_proj_point(uint64_t *res, uint64_t *p)
719
67.7k
{
720
67.7k
    uint64_t *px = p;
721
67.7k
    uint64_t *py = p + (uint32_t)4U;
722
67.7k
    uint64_t *rx = res;
723
67.7k
    uint64_t *ry = res + (uint32_t)4U;
724
67.7k
    uint64_t *rz = res + (uint32_t)8U;
725
67.7k
    to_mont(rx, px);
726
67.7k
    to_mont(ry, py);
727
67.7k
    make_fone(rz);
728
67.7k
}
729
730
static inline bool
731
is_on_curve_vartime(uint64_t *p)
732
68.0k
{
733
68.0k
    uint64_t rp[4U] = { 0U };
734
68.0k
    uint64_t tx[4U] = { 0U };
735
68.0k
    uint64_t ty[4U] = { 0U };
736
68.0k
    uint64_t *px = p;
737
68.0k
    uint64_t *py = p + (uint32_t)4U;
738
68.0k
    to_mont(tx, px);
739
68.0k
    to_mont(ty, py);
740
68.0k
    uint64_t tmp[4U] = { 0U };
741
68.0k
    fcube(rp, tx);
742
68.0k
    make_a_coeff(tmp);
743
68.0k
    fmul0(tmp, tmp, tx);
744
68.0k
    fadd0(rp, tmp, rp);
745
68.0k
    make_b_coeff(tmp);
746
68.0k
    fadd0(rp, tmp, rp);
747
68.0k
    fsqr0(ty, ty);
748
68.0k
    uint64_t r = feq_mask(ty, rp);
749
68.0k
    bool r0 = r == (uint64_t)0xFFFFFFFFFFFFFFFFU;
750
68.0k
    return r0;
751
68.0k
}
752
753
static inline void
754
aff_point_store(uint8_t *res, uint64_t *p)
755
45.0k
{
756
45.0k
    uint64_t *px = p;
757
45.0k
    uint64_t *py = p + (uint32_t)4U;
758
45.0k
    bn2_to_bytes_be4(res, px, py);
759
45.0k
}
760
761
static inline void
762
point_store(uint8_t *res, uint64_t *p)
763
45.0k
{
764
45.0k
    uint64_t aff_p[8U] = { 0U };
765
45.0k
    to_aff_point(aff_p, p);
766
45.0k
    aff_point_store(res, aff_p);
767
45.0k
}
768
769
static inline bool
770
aff_point_load_vartime(uint64_t *p, uint8_t *b)
771
68.1k
{
772
68.1k
    uint8_t *p_x = b;
773
68.1k
    uint8_t *p_y = b + (uint32_t)32U;
774
68.1k
    uint64_t *bn_p_x = p;
775
68.1k
    uint64_t *bn_p_y = p + (uint32_t)4U;
776
68.1k
    bn_from_bytes_be4(bn_p_x, p_x);
777
68.1k
    bn_from_bytes_be4(bn_p_y, p_y);
778
68.1k
    uint64_t *px = p;
779
68.1k
    uint64_t *py = p + (uint32_t)4U;
780
68.1k
    uint64_t lessX = bn_is_lt_prime_mask4(px);
781
68.1k
    uint64_t lessY = bn_is_lt_prime_mask4(py);
782
68.1k
    uint64_t res = lessX & lessY;
783
68.1k
    bool is_xy_valid = res == (uint64_t)0xFFFFFFFFFFFFFFFFU;
784
68.1k
    if (!is_xy_valid) {
785
25
        return false;
786
25
    }
787
68.0k
    return is_on_curve_vartime(p);
788
68.1k
}
789
790
static inline bool
791
load_point_vartime(uint64_t *p, uint8_t *b)
792
68.1k
{
793
68.1k
    uint64_t p_aff[8U] = { 0U };
794
68.1k
    bool res = aff_point_load_vartime(p_aff, b);
795
68.1k
    if (res) {
796
67.7k
        to_proj_point(p, p_aff);
797
67.7k
    }
798
68.1k
    return res;
799
68.1k
}
800
801
static inline bool
802
aff_point_decompress_vartime(uint64_t *x, uint64_t *y, uint8_t *s)
803
0
{
804
0
    uint8_t s0 = s[0U];
805
0
    uint8_t s01 = s0;
806
0
    if (!(s01 == (uint8_t)0x02U || s01 == (uint8_t)0x03U)) {
807
0
        return false;
808
0
    }
809
0
    uint8_t *xb = s + (uint32_t)1U;
810
0
    bn_from_bytes_be4(x, xb);
811
0
    uint64_t is_x_valid = bn_is_lt_prime_mask4(x);
812
0
    bool is_x_valid1 = is_x_valid == (uint64_t)0xFFFFFFFFFFFFFFFFU;
813
0
    bool is_y_odd = s01 == (uint8_t)0x03U;
814
0
    if (!is_x_valid1) {
815
0
        return false;
816
0
    }
817
0
    uint64_t y2M[4U] = { 0U };
818
0
    uint64_t xM[4U] = { 0U };
819
0
    uint64_t yM[4U] = { 0U };
820
0
    to_mont(xM, x);
821
0
    uint64_t tmp[4U] = { 0U };
822
0
    fcube(y2M, xM);
823
0
    make_a_coeff(tmp);
824
0
    fmul0(tmp, tmp, xM);
825
0
    fadd0(y2M, tmp, y2M);
826
0
    make_b_coeff(tmp);
827
0
    fadd0(y2M, tmp, y2M);
828
0
    fsqrt(yM, y2M);
829
0
    from_mont(y, yM);
830
0
    fsqr0(yM, yM);
831
0
    uint64_t r = feq_mask(yM, y2M);
832
0
    bool is_y_valid = r == (uint64_t)0xFFFFFFFFFFFFFFFFU;
833
0
    bool is_y_valid0 = is_y_valid;
834
0
    if (!is_y_valid0) {
835
0
        return false;
836
0
    }
837
0
    uint64_t is_y_odd1 = y[0U] & (uint64_t)1U;
838
0
    bool is_y_odd2 = is_y_odd1 == (uint64_t)1U;
839
0
    fnegate_conditional_vartime(y, is_y_odd2 != is_y_odd);
840
0
    return true;
841
0
}
842
843
static inline void
844
point_double(uint64_t *res, uint64_t *p)
845
7.38M
{
846
7.38M
    uint64_t tmp[20U] = { 0U };
847
7.38M
    uint64_t *x = p;
848
7.38M
    uint64_t *z = p + (uint32_t)8U;
849
7.38M
    uint64_t *x3 = res;
850
7.38M
    uint64_t *y3 = res + (uint32_t)4U;
851
7.38M
    uint64_t *z3 = res + (uint32_t)8U;
852
7.38M
    uint64_t *t0 = tmp;
853
7.38M
    uint64_t *t1 = tmp + (uint32_t)4U;
854
7.38M
    uint64_t *t2 = tmp + (uint32_t)8U;
855
7.38M
    uint64_t *t3 = tmp + (uint32_t)12U;
856
7.38M
    uint64_t *t4 = tmp + (uint32_t)16U;
857
7.38M
    uint64_t *x1 = p;
858
7.38M
    uint64_t *y = p + (uint32_t)4U;
859
7.38M
    uint64_t *z1 = p + (uint32_t)8U;
860
7.38M
    fsqr0(t0, x1);
861
7.38M
    fsqr0(t1, y);
862
7.38M
    fsqr0(t2, z1);
863
7.38M
    fmul0(t3, x1, y);
864
7.38M
    fadd0(t3, t3, t3);
865
7.38M
    fmul0(t4, y, z1);
866
7.38M
    fmul0(z3, x, z);
867
7.38M
    fadd0(z3, z3, z3);
868
7.38M
    fmul_by_b_coeff(y3, t2);
869
7.38M
    fsub0(y3, y3, z3);
870
7.38M
    fadd0(x3, y3, y3);
871
7.38M
    fadd0(y3, x3, y3);
872
7.38M
    fsub0(x3, t1, y3);
873
7.38M
    fadd0(y3, t1, y3);
874
7.38M
    fmul0(y3, x3, y3);
875
7.38M
    fmul0(x3, x3, t3);
876
7.38M
    fadd0(t3, t2, t2);
877
7.38M
    fadd0(t2, t2, t3);
878
7.38M
    fmul_by_b_coeff(z3, z3);
879
7.38M
    fsub0(z3, z3, t2);
880
7.38M
    fsub0(z3, z3, t0);
881
7.38M
    fadd0(t3, z3, z3);
882
7.38M
    fadd0(z3, z3, t3);
883
7.38M
    fadd0(t3, t0, t0);
884
7.38M
    fadd0(t0, t3, t0);
885
7.38M
    fsub0(t0, t0, t2);
886
7.38M
    fmul0(t0, t0, z3);
887
7.38M
    fadd0(y3, y3, t0);
888
7.38M
    fadd0(t0, t4, t4);
889
7.38M
    fmul0(z3, t0, z3);
890
7.38M
    fsub0(x3, x3, z3);
891
7.38M
    fmul0(z3, t0, t1);
892
7.38M
    fadd0(z3, z3, z3);
893
7.38M
    fadd0(z3, z3, z3);
894
7.38M
}
895
896
static inline void
897
point_add(uint64_t *res, uint64_t *p, uint64_t *q)
898
3.05M
{
899
3.05M
    uint64_t tmp[36U] = { 0U };
900
3.05M
    uint64_t *t0 = tmp;
901
3.05M
    uint64_t *t1 = tmp + (uint32_t)24U;
902
3.05M
    uint64_t *x3 = t1;
903
3.05M
    uint64_t *y3 = t1 + (uint32_t)4U;
904
3.05M
    uint64_t *z3 = t1 + (uint32_t)8U;
905
3.05M
    uint64_t *t01 = t0;
906
3.05M
    uint64_t *t11 = t0 + (uint32_t)4U;
907
3.05M
    uint64_t *t2 = t0 + (uint32_t)8U;
908
3.05M
    uint64_t *t3 = t0 + (uint32_t)12U;
909
3.05M
    uint64_t *t4 = t0 + (uint32_t)16U;
910
3.05M
    uint64_t *t5 = t0 + (uint32_t)20U;
911
3.05M
    uint64_t *x1 = p;
912
3.05M
    uint64_t *y1 = p + (uint32_t)4U;
913
3.05M
    uint64_t *z10 = p + (uint32_t)8U;
914
3.05M
    uint64_t *x20 = q;
915
3.05M
    uint64_t *y20 = q + (uint32_t)4U;
916
3.05M
    uint64_t *z20 = q + (uint32_t)8U;
917
3.05M
    fmul0(t01, x1, x20);
918
3.05M
    fmul0(t11, y1, y20);
919
3.05M
    fmul0(t2, z10, z20);
920
3.05M
    fadd0(t3, x1, y1);
921
3.05M
    fadd0(t4, x20, y20);
922
3.05M
    fmul0(t3, t3, t4);
923
3.05M
    fadd0(t4, t01, t11);
924
3.05M
    uint64_t *y10 = p + (uint32_t)4U;
925
3.05M
    uint64_t *z11 = p + (uint32_t)8U;
926
3.05M
    uint64_t *y2 = q + (uint32_t)4U;
927
3.05M
    uint64_t *z21 = q + (uint32_t)8U;
928
3.05M
    fsub0(t3, t3, t4);
929
3.05M
    fadd0(t4, y10, z11);
930
3.05M
    fadd0(t5, y2, z21);
931
3.05M
    fmul0(t4, t4, t5);
932
3.05M
    fadd0(t5, t11, t2);
933
3.05M
    fsub0(t4, t4, t5);
934
3.05M
    uint64_t *x10 = p;
935
3.05M
    uint64_t *z1 = p + (uint32_t)8U;
936
3.05M
    uint64_t *x2 = q;
937
3.05M
    uint64_t *z2 = q + (uint32_t)8U;
938
3.05M
    fadd0(x3, x10, z1);
939
3.05M
    fadd0(y3, x2, z2);
940
3.05M
    fmul0(x3, x3, y3);
941
3.05M
    fadd0(y3, t01, t2);
942
3.05M
    fsub0(y3, x3, y3);
943
3.05M
    fmul_by_b_coeff(z3, t2);
944
3.05M
    fsub0(x3, y3, z3);
945
3.05M
    fadd0(z3, x3, x3);
946
3.05M
    fadd0(x3, x3, z3);
947
3.05M
    fsub0(z3, t11, x3);
948
3.05M
    fadd0(x3, t11, x3);
949
3.05M
    fmul_by_b_coeff(y3, y3);
950
3.05M
    fadd0(t11, t2, t2);
951
3.05M
    fadd0(t2, t11, t2);
952
3.05M
    fsub0(y3, y3, t2);
953
3.05M
    fsub0(y3, y3, t01);
954
3.05M
    fadd0(t11, y3, y3);
955
3.05M
    fadd0(y3, t11, y3);
956
3.05M
    fadd0(t11, t01, t01);
957
3.05M
    fadd0(t01, t11, t01);
958
3.05M
    fsub0(t01, t01, t2);
959
3.05M
    fmul0(t11, t4, y3);
960
3.05M
    fmul0(t2, t01, y3);
961
3.05M
    fmul0(y3, x3, z3);
962
3.05M
    fadd0(y3, y3, t2);
963
3.05M
    fmul0(x3, t3, x3);
964
3.05M
    fsub0(x3, x3, t11);
965
3.05M
    fmul0(z3, t4, z3);
966
3.05M
    fmul0(t11, t3, t01);
967
3.05M
    fadd0(z3, z3, t11);
968
3.05M
    memcpy(res, t1, (uint32_t)12U * sizeof(uint64_t));
969
3.05M
}
970
971
static inline void
972
point_mul(uint64_t *res, uint64_t *scalar, uint64_t *p)
973
22.4k
{
974
22.4k
    uint64_t table[192U] = { 0U };
975
22.4k
    uint64_t tmp[12U] = { 0U };
976
22.4k
    uint64_t *t0 = table;
977
22.4k
    uint64_t *t1 = table + (uint32_t)12U;
978
22.4k
    make_point_at_inf(t0);
979
22.4k
    memcpy(t1, p, (uint32_t)12U * sizeof(uint64_t));
980
22.4k
    KRML_MAYBE_FOR7(i,
981
22.4k
                    (uint32_t)0U,
982
22.4k
                    (uint32_t)7U,
983
22.4k
                    (uint32_t)1U,
984
22.4k
                    uint64_t *t11 = table + (i + (uint32_t)1U) * (uint32_t)12U;
985
22.4k
                    point_double(tmp, t11);
986
22.4k
                    memcpy(table + ((uint32_t)2U * i + (uint32_t)2U) * (uint32_t)12U,
987
22.4k
                           tmp,
988
22.4k
                           (uint32_t)12U * sizeof(uint64_t));
989
22.4k
                    uint64_t *t2 = table + ((uint32_t)2U * i + (uint32_t)2U) * (uint32_t)12U;
990
22.4k
                    point_add(tmp, p, t2);
991
22.4k
                    memcpy(table + ((uint32_t)2U * i + (uint32_t)3U) * (uint32_t)12U,
992
22.4k
                           tmp,
993
22.4k
                           (uint32_t)12U * sizeof(uint64_t)););
994
22.4k
    make_point_at_inf(res);
995
22.4k
    uint64_t tmp0[12U] = { 0U };
996
1.46M
    for (uint32_t i0 = (uint32_t)0U; i0 < (uint32_t)64U; i0++) {
997
1.43M
        KRML_MAYBE_FOR4(i, (uint32_t)0U, (uint32_t)4U, (uint32_t)1U, point_double(res, res););
998
1.43M
        uint32_t k = (uint32_t)256U - (uint32_t)4U * i0 - (uint32_t)4U;
999
1.43M
        uint64_t bits_l = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)4U, scalar, k, (uint32_t)4U);
1000
1.43M
        memcpy(tmp0, (uint64_t *)table, (uint32_t)12U * sizeof(uint64_t));
1001
1.43M
        KRML_MAYBE_FOR15(i1,
1002
1.43M
                         (uint32_t)0U,
1003
1.43M
                         (uint32_t)15U,
1004
1.43M
                         (uint32_t)1U,
1005
1.43M
                         uint64_t c = FStar_UInt64_eq_mask(bits_l, (uint64_t)(i1 + (uint32_t)1U));
1006
1.43M
                         const uint64_t *res_j = table + (i1 + (uint32_t)1U) * (uint32_t)12U;
1007
1.43M
                         KRML_MAYBE_FOR12(i,
1008
1.43M
                                          (uint32_t)0U,
1009
1.43M
                                          (uint32_t)12U,
1010
1.43M
                                          (uint32_t)1U,
1011
1.43M
                                          uint64_t *os = tmp0;
1012
1.43M
                                          uint64_t x = (c & res_j[i]) | (~c & tmp0[i]);
1013
1.43M
                                          os[i] = x;););
1014
1.43M
        point_add(res, res, tmp0);
1015
1.43M
    }
1016
22.4k
}
1017
1018
static inline void
1019
precomp_get_consttime(const uint64_t *table, uint64_t bits_l, uint64_t *tmp)
1020
1.44M
{
1021
1.44M
    memcpy(tmp, (uint64_t *)table, (uint32_t)12U * sizeof(uint64_t));
1022
1.44M
    KRML_MAYBE_FOR15(i0,
1023
1.44M
                     (uint32_t)0U,
1024
1.44M
                     (uint32_t)15U,
1025
1.44M
                     (uint32_t)1U,
1026
1.44M
                     uint64_t c = FStar_UInt64_eq_mask(bits_l, (uint64_t)(i0 + (uint32_t)1U));
1027
1.44M
                     const uint64_t *res_j = table + (i0 + (uint32_t)1U) * (uint32_t)12U;
1028
1.44M
                     KRML_MAYBE_FOR12(i,
1029
1.44M
                                      (uint32_t)0U,
1030
1.44M
                                      (uint32_t)12U,
1031
1.44M
                                      (uint32_t)1U,
1032
1.44M
                                      uint64_t *os = tmp;
1033
1.44M
                                      uint64_t x = (c & res_j[i]) | (~c & tmp[i]);
1034
1.44M
                                      os[i] = x;););
1035
1.44M
}
1036
1037
static inline void
1038
point_mul_g(uint64_t *res, uint64_t *scalar)
1039
22.5k
{
1040
22.5k
    uint64_t q1[12U] = { 0U };
1041
22.5k
    make_base_point(q1);
1042
22.5k
    uint64_t
1043
22.5k
        q2[12U] = {
1044
22.5k
            (uint64_t)1499621593102562565U, (uint64_t)16692369783039433128U,
1045
22.5k
            (uint64_t)15337520135922861848U, (uint64_t)5455737214495366228U,
1046
22.5k
            (uint64_t)17827017231032529600U, (uint64_t)12413621606240782649U,
1047
22.5k
            (uint64_t)2290483008028286132U, (uint64_t)15752017553340844820U,
1048
22.5k
            (uint64_t)4846430910634234874U, (uint64_t)10861682798464583253U,
1049
22.5k
            (uint64_t)15404737222404363049U, (uint64_t)363586619281562022U
1050
22.5k
        };
1051
22.5k
    uint64_t
1052
22.5k
        q3[12U] = {
1053
22.5k
            (uint64_t)14619254753077084366U, (uint64_t)13913835116514008593U,
1054
22.5k
            (uint64_t)15060744674088488145U, (uint64_t)17668414598203068685U,
1055
22.5k
            (uint64_t)10761169236902342334U, (uint64_t)15467027479157446221U,
1056
22.5k
            (uint64_t)14989185522423469618U, (uint64_t)14354539272510107003U,
1057
22.5k
            (uint64_t)14298211796392133693U, (uint64_t)13270323784253711450U,
1058
22.5k
            (uint64_t)13380964971965046957U, (uint64_t)8686204248456909699U
1059
22.5k
        };
1060
22.5k
    uint64_t
1061
22.5k
        q4[12U] = {
1062
22.5k
            (uint64_t)7870395003430845958U, (uint64_t)18001862936410067720U,
1063
22.5k
            (uint64_t)8006461232116967215U, (uint64_t)5921313779532424762U,
1064
22.5k
            (uint64_t)10702113371959864307U, (uint64_t)8070517410642379879U,
1065
22.5k
            (uint64_t)7139806720777708306U, (uint64_t)8253938546650739833U,
1066
22.5k
            (uint64_t)17490482834545705718U, (uint64_t)1065249776797037500U,
1067
22.5k
            (uint64_t)5018258455937968775U, (uint64_t)14100621120178668337U
1068
22.5k
        };
1069
22.5k
    uint64_t *r1 = scalar;
1070
22.5k
    uint64_t *r2 = scalar + (uint32_t)1U;
1071
22.5k
    uint64_t *r3 = scalar + (uint32_t)2U;
1072
22.5k
    uint64_t *r4 = scalar + (uint32_t)3U;
1073
22.5k
    make_point_at_inf(res);
1074
22.5k
    uint64_t tmp[12U] = { 0U };
1075
22.5k
    KRML_MAYBE_FOR16(i,
1076
22.5k
                     (uint32_t)0U,
1077
22.5k
                     (uint32_t)16U,
1078
22.5k
                     (uint32_t)1U,
1079
22.5k
                     KRML_MAYBE_FOR4(i0, (uint32_t)0U, (uint32_t)4U, (uint32_t)1U, point_double(res, res););
1080
22.5k
                     uint32_t k = (uint32_t)64U - (uint32_t)4U * i - (uint32_t)4U;
1081
22.5k
                     uint64_t bits_l = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)1U, r4, k, (uint32_t)4U);
1082
22.5k
                     precomp_get_consttime(Hacl_P256_PrecompTable_precomp_g_pow2_192_table_w4, bits_l, tmp);
1083
22.5k
                     point_add(res, res, tmp);
1084
22.5k
                     uint32_t k0 = (uint32_t)64U - (uint32_t)4U * i - (uint32_t)4U;
1085
22.5k
                     uint64_t bits_l0 = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)1U, r3, k0, (uint32_t)4U);
1086
22.5k
                     precomp_get_consttime(Hacl_P256_PrecompTable_precomp_g_pow2_128_table_w4, bits_l0, tmp);
1087
22.5k
                     point_add(res, res, tmp);
1088
22.5k
                     uint32_t k1 = (uint32_t)64U - (uint32_t)4U * i - (uint32_t)4U;
1089
22.5k
                     uint64_t bits_l1 = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)1U, r2, k1, (uint32_t)4U);
1090
22.5k
                     precomp_get_consttime(Hacl_P256_PrecompTable_precomp_g_pow2_64_table_w4, bits_l1, tmp);
1091
22.5k
                     point_add(res, res, tmp);
1092
22.5k
                     uint32_t k2 = (uint32_t)64U - (uint32_t)4U * i - (uint32_t)4U;
1093
22.5k
                     uint64_t bits_l2 = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)1U, r1, k2, (uint32_t)4U);
1094
22.5k
                     precomp_get_consttime(Hacl_P256_PrecompTable_precomp_basepoint_table_w4, bits_l2, tmp);
1095
22.5k
                     point_add(res, res, tmp););
1096
22.5k
    KRML_HOST_IGNORE(q1);
1097
22.5k
    KRML_HOST_IGNORE(q2);
1098
22.5k
    KRML_HOST_IGNORE(q3);
1099
22.5k
    KRML_HOST_IGNORE(q4);
1100
22.5k
}
1101
1102
static inline void
1103
point_mul_double_g(uint64_t *res, uint64_t *scalar1, uint64_t *scalar2, uint64_t *q2)
1104
104
{
1105
104
    uint64_t q1[12U] = { 0U };
1106
104
    make_base_point(q1);
1107
104
    uint64_t table2[384U] = { 0U };
1108
104
    uint64_t tmp[12U] = { 0U };
1109
104
    uint64_t *t0 = table2;
1110
104
    uint64_t *t1 = table2 + (uint32_t)12U;
1111
104
    make_point_at_inf(t0);
1112
104
    memcpy(t1, q2, (uint32_t)12U * sizeof(uint64_t));
1113
104
    KRML_MAYBE_FOR15(i,
1114
104
                     (uint32_t)0U,
1115
104
                     (uint32_t)15U,
1116
104
                     (uint32_t)1U,
1117
104
                     uint64_t *t11 = table2 + (i + (uint32_t)1U) * (uint32_t)12U;
1118
104
                     point_double(tmp, t11);
1119
104
                     memcpy(table2 + ((uint32_t)2U * i + (uint32_t)2U) * (uint32_t)12U,
1120
104
                            tmp,
1121
104
                            (uint32_t)12U * sizeof(uint64_t));
1122
104
                     uint64_t *t2 = table2 + ((uint32_t)2U * i + (uint32_t)2U) * (uint32_t)12U;
1123
104
                     point_add(tmp, q2, t2);
1124
104
                     memcpy(table2 + ((uint32_t)2U * i + (uint32_t)3U) * (uint32_t)12U,
1125
104
                            tmp,
1126
104
                            (uint32_t)12U * sizeof(uint64_t)););
1127
104
    uint64_t tmp0[12U] = { 0U };
1128
104
    uint32_t i0 = (uint32_t)255U;
1129
104
    uint64_t bits_c = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)4U, scalar1, i0, (uint32_t)5U);
1130
104
    uint32_t bits_l32 = (uint32_t)bits_c;
1131
104
    const uint64_t
1132
104
        *a_bits_l = Hacl_P256_PrecompTable_precomp_basepoint_table_w5 + bits_l32 * (uint32_t)12U;
1133
104
    memcpy(res, (uint64_t *)a_bits_l, (uint32_t)12U * sizeof(uint64_t));
1134
104
    uint32_t i1 = (uint32_t)255U;
1135
104
    uint64_t bits_c0 = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)4U, scalar2, i1, (uint32_t)5U);
1136
104
    uint32_t bits_l320 = (uint32_t)bits_c0;
1137
104
    const uint64_t *a_bits_l0 = table2 + bits_l320 * (uint32_t)12U;
1138
104
    memcpy(tmp0, (uint64_t *)a_bits_l0, (uint32_t)12U * sizeof(uint64_t));
1139
104
    point_add(res, res, tmp0);
1140
104
    uint64_t tmp1[12U] = { 0U };
1141
5.40k
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)51U; i++) {
1142
5.30k
        KRML_MAYBE_FOR5(i2, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, point_double(res, res););
1143
5.30k
        uint32_t k = (uint32_t)255U - (uint32_t)5U * i - (uint32_t)5U;
1144
5.30k
        uint64_t bits_l = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)4U, scalar2, k, (uint32_t)5U);
1145
5.30k
        uint32_t bits_l321 = (uint32_t)bits_l;
1146
5.30k
        const uint64_t *a_bits_l1 = table2 + bits_l321 * (uint32_t)12U;
1147
5.30k
        memcpy(tmp1, (uint64_t *)a_bits_l1, (uint32_t)12U * sizeof(uint64_t));
1148
5.30k
        point_add(res, res, tmp1);
1149
5.30k
        uint32_t k0 = (uint32_t)255U - (uint32_t)5U * i - (uint32_t)5U;
1150
5.30k
        uint64_t bits_l0 = Hacl_Bignum_Lib_bn_get_bits_u64((uint32_t)4U, scalar1, k0, (uint32_t)5U);
1151
5.30k
        uint32_t bits_l322 = (uint32_t)bits_l0;
1152
5.30k
        const uint64_t
1153
5.30k
            *a_bits_l2 = Hacl_P256_PrecompTable_precomp_basepoint_table_w5 + bits_l322 * (uint32_t)12U;
1154
5.30k
        memcpy(tmp1, (uint64_t *)a_bits_l2, (uint32_t)12U * sizeof(uint64_t));
1155
5.30k
        point_add(res, res, tmp1);
1156
5.30k
    }
1157
104
}
1158
1159
static inline uint64_t
1160
bn_is_lt_order_mask4(uint64_t *f)
1161
67.8k
{
1162
67.8k
    uint64_t tmp[4U] = { 0U };
1163
67.8k
    make_order(tmp);
1164
67.8k
    uint64_t c = bn_sub4(tmp, f, tmp);
1165
67.8k
    return (uint64_t)0U - c;
1166
67.8k
}
1167
1168
static inline uint64_t
1169
bn_is_lt_order_and_gt_zero_mask4(uint64_t *f)
1170
67.8k
{
1171
67.8k
    uint64_t is_lt_order = bn_is_lt_order_mask4(f);
1172
67.8k
    uint64_t is_eq_zero = bn_is_zero_mask4(f);
1173
67.8k
    return is_lt_order & ~is_eq_zero;
1174
67.8k
}
1175
1176
static inline void
1177
qmod_short(uint64_t *res, uint64_t *x)
1178
212
{
1179
212
    uint64_t tmp[4U] = { 0U };
1180
212
    make_order(tmp);
1181
212
    uint64_t c = bn_sub4(tmp, x, tmp);
1182
212
    bn_cmovznz4(res, c, tmp, x);
1183
212
}
1184
1185
static inline void
1186
qadd(uint64_t *res, uint64_t *x, uint64_t *y)
1187
0
{
1188
0
    uint64_t n[4U] = { 0U };
1189
0
    make_order(n);
1190
0
    bn_add_mod4(res, n, x, y);
1191
0
}
1192
1193
static inline void
1194
qmont_reduction(uint64_t *res, uint64_t *x)
1195
30.7k
{
1196
30.7k
    uint64_t n[4U] = { 0U };
1197
30.7k
    make_order(n);
1198
30.7k
    uint64_t c0 = (uint64_t)0U;
1199
30.7k
    KRML_MAYBE_FOR4(
1200
30.7k
        i0,
1201
30.7k
        (uint32_t)0U,
1202
30.7k
        (uint32_t)4U,
1203
30.7k
        (uint32_t)1U,
1204
30.7k
        uint64_t qj = (uint64_t)0xccd1c8aaee00bc4fU * x[i0];
1205
30.7k
        uint64_t *res_j0 = x + i0;
1206
30.7k
        uint64_t c = (uint64_t)0U;
1207
30.7k
        {
1208
30.7k
            uint64_t a_i = n[(uint32_t)4U * (uint32_t)0U];
1209
30.7k
            uint64_t *res_i0 = res_j0 + (uint32_t)4U * (uint32_t)0U;
1210
30.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i, qj, c, res_i0);
1211
30.7k
            uint64_t a_i0 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
1212
30.7k
            uint64_t *res_i1 = res_j0 + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
1213
30.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i0, qj, c, res_i1);
1214
30.7k
            uint64_t a_i1 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
1215
30.7k
            uint64_t *res_i2 = res_j0 + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
1216
30.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i1, qj, c, res_i2);
1217
30.7k
            uint64_t a_i2 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
1218
30.7k
            uint64_t *res_i = res_j0 + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
1219
30.7k
            c = Hacl_Bignum_Base_mul_wide_add2_u64(a_i2, qj, c, res_i);
1220
30.7k
        } uint64_t r = c;
1221
30.7k
        uint64_t c1 = r;
1222
30.7k
        uint64_t *resb = x + (uint32_t)4U + i0;
1223
30.7k
        uint64_t res_j = x[(uint32_t)4U + i0];
1224
30.7k
        c0 = Lib_IntTypes_Intrinsics_add_carry_u64(c0, c1, res_j, resb););
1225
30.7k
    memcpy(res, x + (uint32_t)4U, (uint32_t)4U * sizeof(uint64_t));
1226
30.7k
    uint64_t c00 = c0;
1227
30.7k
    uint64_t tmp[4U] = { 0U };
1228
30.7k
    uint64_t c = (uint64_t)0U;
1229
30.7k
    {
1230
30.7k
        uint64_t t1 = res[(uint32_t)4U * (uint32_t)0U];
1231
30.7k
        uint64_t t20 = n[(uint32_t)4U * (uint32_t)0U];
1232
30.7k
        uint64_t *res_i0 = tmp + (uint32_t)4U * (uint32_t)0U;
1233
30.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t1, t20, res_i0);
1234
30.7k
        uint64_t t10 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
1235
30.7k
        uint64_t t21 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)1U];
1236
30.7k
        uint64_t *res_i1 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)1U;
1237
30.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t10, t21, res_i1);
1238
30.7k
        uint64_t t11 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
1239
30.7k
        uint64_t t22 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)2U];
1240
30.7k
        uint64_t *res_i2 = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)2U;
1241
30.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t11, t22, res_i2);
1242
30.7k
        uint64_t t12 = res[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
1243
30.7k
        uint64_t t2 = n[(uint32_t)4U * (uint32_t)0U + (uint32_t)3U];
1244
30.7k
        uint64_t *res_i = tmp + (uint32_t)4U * (uint32_t)0U + (uint32_t)3U;
1245
30.7k
        c = Lib_IntTypes_Intrinsics_sub_borrow_u64(c, t12, t2, res_i);
1246
30.7k
    }
1247
30.7k
    uint64_t c1 = c;
1248
30.7k
    uint64_t c2 = c00 - c1;
1249
30.7k
    KRML_MAYBE_FOR4(i,
1250
30.7k
                    (uint32_t)0U,
1251
30.7k
                    (uint32_t)4U,
1252
30.7k
                    (uint32_t)1U,
1253
30.7k
                    uint64_t *os = res;
1254
30.7k
                    uint64_t x1 = (c2 & res[i]) | (~c2 & tmp[i]);
1255
30.7k
                    os[i] = x1;);
1256
30.7k
}
1257
1258
static inline void
1259
from_qmont(uint64_t *res, uint64_t *x)
1260
208
{
1261
208
    uint64_t tmp[8U] = { 0U };
1262
208
    memcpy(tmp, x, (uint32_t)4U * sizeof(uint64_t));
1263
208
    qmont_reduction(res, tmp);
1264
208
}
1265
1266
static inline void
1267
qmul(uint64_t *res, uint64_t *x, uint64_t *y)
1268
4.16k
{
1269
4.16k
    uint64_t tmp[8U] = { 0U };
1270
4.16k
    bn_mul4(tmp, x, y);
1271
4.16k
    qmont_reduction(res, tmp);
1272
4.16k
}
1273
1274
static inline void
1275
qsqr(uint64_t *res, uint64_t *x)
1276
26.4k
{
1277
26.4k
    uint64_t tmp[8U] = { 0U };
1278
26.4k
    bn_sqr4(tmp, x);
1279
26.4k
    qmont_reduction(res, tmp);
1280
26.4k
}
1281
1282
bool
1283
Hacl_Impl_P256_DH_ecp256dh_i(uint8_t *public_key, uint8_t *private_key)
1284
22.5k
{
1285
22.5k
    uint64_t tmp[16U] = { 0U };
1286
22.5k
    uint64_t *sk = tmp;
1287
22.5k
    uint64_t *pk = tmp + (uint32_t)4U;
1288
22.5k
    bn_from_bytes_be4(sk, private_key);
1289
22.5k
    uint64_t is_b_valid = bn_is_lt_order_and_gt_zero_mask4(sk);
1290
22.5k
    uint64_t oneq[4U] = { 0U };
1291
22.5k
    oneq[0U] = (uint64_t)1U;
1292
22.5k
    oneq[1U] = (uint64_t)0U;
1293
22.5k
    oneq[2U] = (uint64_t)0U;
1294
22.5k
    oneq[3U] = (uint64_t)0U;
1295
22.5k
    KRML_MAYBE_FOR4(i,
1296
22.5k
                    (uint32_t)0U,
1297
22.5k
                    (uint32_t)4U,
1298
22.5k
                    (uint32_t)1U,
1299
22.5k
                    uint64_t *os = sk;
1300
22.5k
                    uint64_t uu____0 = oneq[i];
1301
22.5k
                    uint64_t x = uu____0 ^ (is_b_valid & (sk[i] ^ uu____0));
1302
22.5k
                    os[i] = x;);
1303
22.5k
    uint64_t is_sk_valid = is_b_valid;
1304
22.5k
    point_mul_g(pk, sk);
1305
22.5k
    point_store(public_key, pk);
1306
22.5k
    return is_sk_valid == (uint64_t)0xFFFFFFFFFFFFFFFFU;
1307
22.5k
}
1308
1309
bool
1310
Hacl_Impl_P256_DH_ecp256dh_r(
1311
    uint8_t *shared_secret,
1312
    uint8_t *their_pubkey,
1313
    uint8_t *private_key)
1314
22.4k
{
1315
22.4k
    uint64_t tmp[16U] = { 0U };
1316
22.4k
    uint64_t *sk = tmp;
1317
22.4k
    uint64_t *pk = tmp + (uint32_t)4U;
1318
22.4k
    bool is_pk_valid = load_point_vartime(pk, their_pubkey);
1319
22.4k
    bn_from_bytes_be4(sk, private_key);
1320
22.4k
    uint64_t is_b_valid = bn_is_lt_order_and_gt_zero_mask4(sk);
1321
22.4k
    uint64_t oneq[4U] = { 0U };
1322
22.4k
    oneq[0U] = (uint64_t)1U;
1323
22.4k
    oneq[1U] = (uint64_t)0U;
1324
22.4k
    oneq[2U] = (uint64_t)0U;
1325
22.4k
    oneq[3U] = (uint64_t)0U;
1326
22.4k
    KRML_MAYBE_FOR4(i,
1327
22.4k
                    (uint32_t)0U,
1328
22.4k
                    (uint32_t)4U,
1329
22.4k
                    (uint32_t)1U,
1330
22.4k
                    uint64_t *os = sk;
1331
22.4k
                    uint64_t uu____0 = oneq[i];
1332
22.4k
                    uint64_t x = uu____0 ^ (is_b_valid & (sk[i] ^ uu____0));
1333
22.4k
                    os[i] = x;);
1334
22.4k
    uint64_t is_sk_valid = is_b_valid;
1335
22.4k
    uint64_t ss_proj[12U] = { 0U };
1336
22.4k
    if (is_pk_valid) {
1337
22.4k
        point_mul(ss_proj, sk, pk);
1338
22.4k
        point_store(shared_secret, ss_proj);
1339
22.4k
    }
1340
22.4k
    return is_sk_valid == (uint64_t)0xFFFFFFFFFFFFFFFFU && is_pk_valid;
1341
22.4k
}
1342
1343
static inline void
1344
qinv(uint64_t *res, uint64_t *r)
1345
104
{
1346
104
    uint64_t tmp[28U] = { 0U };
1347
104
    uint64_t *x6 = tmp;
1348
104
    uint64_t *x_11 = tmp + (uint32_t)4U;
1349
104
    uint64_t *x_101 = tmp + (uint32_t)8U;
1350
104
    uint64_t *x_111 = tmp + (uint32_t)12U;
1351
104
    uint64_t *x_1111 = tmp + (uint32_t)16U;
1352
104
    uint64_t *x_10101 = tmp + (uint32_t)20U;
1353
104
    uint64_t *x_101111 = tmp + (uint32_t)24U;
1354
104
    memcpy(x6, r, (uint32_t)4U * sizeof(uint64_t));
1355
104
    {
1356
104
        qsqr(x6, x6);
1357
104
    }
1358
104
    qmul(x_11, x6, r);
1359
104
    qmul(x_101, x6, x_11);
1360
104
    qmul(x_111, x6, x_101);
1361
104
    memcpy(x6, x_101, (uint32_t)4U * sizeof(uint64_t));
1362
104
    {
1363
104
        qsqr(x6, x6);
1364
104
    }
1365
104
    qmul(x_1111, x_101, x6);
1366
104
    {
1367
104
        qsqr(x6, x6);
1368
104
    }
1369
104
    qmul(x_10101, x6, r);
1370
104
    memcpy(x6, x_10101, (uint32_t)4U * sizeof(uint64_t));
1371
104
    {
1372
104
        qsqr(x6, x6);
1373
104
    }
1374
104
    qmul(x_101111, x_101, x6);
1375
104
    qmul(x6, x_10101, x6);
1376
104
    uint64_t tmp1[4U] = { 0U };
1377
104
    KRML_MAYBE_FOR2(i, (uint32_t)0U, (uint32_t)2U, (uint32_t)1U, qsqr(x6, x6););
1378
104
    qmul(x6, x6, x_11);
1379
104
    memcpy(tmp1, x6, (uint32_t)4U * sizeof(uint64_t));
1380
104
    KRML_MAYBE_FOR8(i, (uint32_t)0U, (uint32_t)8U, (uint32_t)1U, qsqr(tmp1, tmp1););
1381
104
    qmul(tmp1, tmp1, x6);
1382
104
    memcpy(x6, tmp1, (uint32_t)4U * sizeof(uint64_t));
1383
104
    KRML_MAYBE_FOR16(i, (uint32_t)0U, (uint32_t)16U, (uint32_t)1U, qsqr(x6, x6););
1384
104
    qmul(x6, x6, tmp1);
1385
104
    memcpy(tmp1, x6, (uint32_t)4U * sizeof(uint64_t));
1386
6.76k
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)64U; i++) {
1387
6.65k
        qsqr(tmp1, tmp1);
1388
6.65k
    }
1389
104
    qmul(tmp1, tmp1, x6);
1390
3.43k
    for (uint32_t i = (uint32_t)0U; i < (uint32_t)32U; i++) {
1391
3.32k
        qsqr(tmp1, tmp1);
1392
3.32k
    }
1393
104
    qmul(tmp1, tmp1, x6);
1394
104
    KRML_MAYBE_FOR6(i, (uint32_t)0U, (uint32_t)6U, (uint32_t)1U, qsqr(tmp1, tmp1););
1395
104
    qmul(tmp1, tmp1, x_101111);
1396
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1397
104
    qmul(tmp1, tmp1, x_111);
1398
104
    KRML_MAYBE_FOR4(i, (uint32_t)0U, (uint32_t)4U, (uint32_t)1U, qsqr(tmp1, tmp1););
1399
104
    qmul(tmp1, tmp1, x_11);
1400
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1401
104
    qmul(tmp1, tmp1, x_1111);
1402
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1403
104
    qmul(tmp1, tmp1, x_10101);
1404
104
    KRML_MAYBE_FOR4(i, (uint32_t)0U, (uint32_t)4U, (uint32_t)1U, qsqr(tmp1, tmp1););
1405
104
    qmul(tmp1, tmp1, x_101);
1406
104
    KRML_MAYBE_FOR3(i, (uint32_t)0U, (uint32_t)3U, (uint32_t)1U, qsqr(tmp1, tmp1););
1407
104
    qmul(tmp1, tmp1, x_101);
1408
104
    KRML_MAYBE_FOR3(i, (uint32_t)0U, (uint32_t)3U, (uint32_t)1U, qsqr(tmp1, tmp1););
1409
104
    qmul(tmp1, tmp1, x_101);
1410
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1411
104
    qmul(tmp1, tmp1, x_111);
1412
104
    KRML_MAYBE_FOR9(i, (uint32_t)0U, (uint32_t)9U, (uint32_t)1U, qsqr(tmp1, tmp1););
1413
104
    qmul(tmp1, tmp1, x_101111);
1414
104
    KRML_MAYBE_FOR6(i, (uint32_t)0U, (uint32_t)6U, (uint32_t)1U, qsqr(tmp1, tmp1););
1415
104
    qmul(tmp1, tmp1, x_1111);
1416
104
    KRML_MAYBE_FOR2(i, (uint32_t)0U, (uint32_t)2U, (uint32_t)1U, qsqr(tmp1, tmp1););
1417
104
    qmul(tmp1, tmp1, r);
1418
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1419
104
    qmul(tmp1, tmp1, r);
1420
104
    KRML_MAYBE_FOR6(i, (uint32_t)0U, (uint32_t)6U, (uint32_t)1U, qsqr(tmp1, tmp1););
1421
104
    qmul(tmp1, tmp1, x_1111);
1422
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1423
104
    qmul(tmp1, tmp1, x_111);
1424
104
    KRML_MAYBE_FOR4(i, (uint32_t)0U, (uint32_t)4U, (uint32_t)1U, qsqr(tmp1, tmp1););
1425
104
    qmul(tmp1, tmp1, x_111);
1426
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1427
104
    qmul(tmp1, tmp1, x_111);
1428
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1429
104
    qmul(tmp1, tmp1, x_101);
1430
104
    KRML_MAYBE_FOR3(i, (uint32_t)0U, (uint32_t)3U, (uint32_t)1U, qsqr(tmp1, tmp1););
1431
104
    qmul(tmp1, tmp1, x_11);
1432
104
    KRML_MAYBE_FOR10(i, (uint32_t)0U, (uint32_t)10U, (uint32_t)1U, qsqr(tmp1, tmp1););
1433
104
    qmul(tmp1, tmp1, x_101111);
1434
104
    KRML_MAYBE_FOR2(i, (uint32_t)0U, (uint32_t)2U, (uint32_t)1U, qsqr(tmp1, tmp1););
1435
104
    qmul(tmp1, tmp1, x_11);
1436
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1437
104
    qmul(tmp1, tmp1, x_11);
1438
104
    KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, qsqr(tmp1, tmp1););
1439
104
    qmul(tmp1, tmp1, x_11);
1440
104
    KRML_MAYBE_FOR3(i, (uint32_t)0U, (uint32_t)3U, (uint32_t)1U, qsqr(tmp1, tmp1););
1441
104
    qmul(tmp1, tmp1, r);
1442
104
    KRML_MAYBE_FOR7(i, (uint32_t)0U, (uint32_t)7U, (uint32_t)1U, qsqr(tmp1, tmp1););
1443
104
    qmul(tmp1, tmp1, x_10101);
1444
104
    KRML_MAYBE_FOR6(i, (uint32_t)0U, (uint32_t)6U, (uint32_t)1U, qsqr(tmp1, tmp1););
1445
104
    qmul(tmp1, tmp1, x_1111);
1446
104
    memcpy(x6, tmp1, (uint32_t)4U * sizeof(uint64_t));
1447
104
    memcpy(res, x6, (uint32_t)4U * sizeof(uint64_t));
1448
104
}
1449
1450
static inline void
1451
qmul_mont(uint64_t *sinv, uint64_t *b, uint64_t *res)
1452
208
{
1453
208
    uint64_t tmp[4U] = { 0U };
1454
208
    from_qmont(tmp, b);
1455
208
    qmul(res, sinv, tmp);
1456
208
}
1457
1458
static inline bool
1459
ecdsa_verify_msg_as_qelem(
1460
    uint64_t *m_q,
1461
    uint8_t *public_key,
1462
    uint8_t *signature_r,
1463
    uint8_t *signature_s)
1464
108
{
1465
108
    uint64_t tmp[28U] = { 0U };
1466
108
    uint64_t *pk = tmp;
1467
108
    uint64_t *r_q = tmp + (uint32_t)12U;
1468
108
    uint64_t *s_q = tmp + (uint32_t)16U;
1469
108
    uint64_t *u1 = tmp + (uint32_t)20U;
1470
108
    uint64_t *u2 = tmp + (uint32_t)24U;
1471
108
    bool is_pk_valid = load_point_vartime(pk, public_key);
1472
108
    bn_from_bytes_be4(r_q, signature_r);
1473
108
    bn_from_bytes_be4(s_q, signature_s);
1474
108
    uint64_t is_r_valid = bn_is_lt_order_and_gt_zero_mask4(r_q);
1475
108
    uint64_t is_s_valid = bn_is_lt_order_and_gt_zero_mask4(s_q);
1476
108
    bool
1477
108
        is_rs_valid =
1478
108
            is_r_valid == (uint64_t)0xFFFFFFFFFFFFFFFFU && is_s_valid == (uint64_t)0xFFFFFFFFFFFFFFFFU;
1479
108
    if (!(is_pk_valid && is_rs_valid)) {
1480
4
        return false;
1481
4
    }
1482
104
    uint64_t sinv[4U] = { 0U };
1483
104
    qinv(sinv, s_q);
1484
104
    qmul_mont(sinv, m_q, u1);
1485
104
    qmul_mont(sinv, r_q, u2);
1486
104
    uint64_t res[12U] = { 0U };
1487
104
    point_mul_double_g(res, u1, u2, pk);
1488
104
    if (is_point_at_inf_vartime(res)) {
1489
0
        return false;
1490
0
    }
1491
104
    uint64_t x[4U] = { 0U };
1492
104
    to_aff_point_x(x, res);
1493
104
    qmod_short(x, x);
1494
104
    bool res1 = bn_is_eq_vartime4(x, r_q);
1495
104
    return res1;
1496
104
}
1497
1498
static inline bool
1499
ecdsa_sign_msg_as_qelem(
1500
    uint8_t *signature,
1501
    uint64_t *m_q,
1502
    uint8_t *private_key,
1503
    uint8_t *nonce)
1504
0
{
1505
0
    uint64_t rsdk_q[16U] = { 0U };
1506
0
    uint64_t *r_q = rsdk_q;
1507
0
    uint64_t *s_q = rsdk_q + (uint32_t)4U;
1508
0
    uint64_t *d_a = rsdk_q + (uint32_t)8U;
1509
0
    uint64_t *k_q = rsdk_q + (uint32_t)12U;
1510
0
    bn_from_bytes_be4(d_a, private_key);
1511
0
    uint64_t is_b_valid0 = bn_is_lt_order_and_gt_zero_mask4(d_a);
1512
0
    uint64_t oneq0[4U] = { 0U };
1513
0
    oneq0[0U] = (uint64_t)1U;
1514
0
    oneq0[1U] = (uint64_t)0U;
1515
0
    oneq0[2U] = (uint64_t)0U;
1516
0
    oneq0[3U] = (uint64_t)0U;
1517
0
    KRML_MAYBE_FOR4(i,
1518
0
                    (uint32_t)0U,
1519
0
                    (uint32_t)4U,
1520
0
                    (uint32_t)1U,
1521
0
                    uint64_t *os = d_a;
1522
0
                    uint64_t uu____0 = oneq0[i];
1523
0
                    uint64_t x = uu____0 ^ (is_b_valid0 & (d_a[i] ^ uu____0));
1524
0
                    os[i] = x;);
1525
0
    uint64_t is_sk_valid = is_b_valid0;
1526
0
    bn_from_bytes_be4(k_q, nonce);
1527
0
    uint64_t is_b_valid = bn_is_lt_order_and_gt_zero_mask4(k_q);
1528
0
    uint64_t oneq[4U] = { 0U };
1529
0
    oneq[0U] = (uint64_t)1U;
1530
0
    oneq[1U] = (uint64_t)0U;
1531
0
    oneq[2U] = (uint64_t)0U;
1532
0
    oneq[3U] = (uint64_t)0U;
1533
0
    KRML_MAYBE_FOR4(i,
1534
0
                    (uint32_t)0U,
1535
0
                    (uint32_t)4U,
1536
0
                    (uint32_t)1U,
1537
0
                    uint64_t *os = k_q;
1538
0
                    uint64_t uu____1 = oneq[i];
1539
0
                    uint64_t x = uu____1 ^ (is_b_valid & (k_q[i] ^ uu____1));
1540
0
                    os[i] = x;);
1541
0
    uint64_t is_nonce_valid = is_b_valid;
1542
0
    uint64_t are_sk_nonce_valid = is_sk_valid & is_nonce_valid;
1543
0
    uint64_t p[12U] = { 0U };
1544
0
    point_mul_g(p, k_q);
1545
0
    to_aff_point_x(r_q, p);
1546
0
    qmod_short(r_q, r_q);
1547
0
    uint64_t kinv[4U] = { 0U };
1548
0
    qinv(kinv, k_q);
1549
0
    qmul(s_q, r_q, d_a);
1550
0
    from_qmont(m_q, m_q);
1551
0
    qadd(s_q, m_q, s_q);
1552
0
    qmul(s_q, kinv, s_q);
1553
0
    bn2_to_bytes_be4(signature, r_q, s_q);
1554
0
    uint64_t is_r_zero = bn_is_zero_mask4(r_q);
1555
0
    uint64_t is_s_zero = bn_is_zero_mask4(s_q);
1556
0
    uint64_t m = are_sk_nonce_valid & (~is_r_zero & ~is_s_zero);
1557
0
    bool res = m == (uint64_t)0xFFFFFFFFFFFFFFFFU;
1558
0
    return res;
1559
0
}
1560
1561
/*******************************************************************************
1562
1563
 Verified C library for ECDSA and ECDH functions over the P-256 NIST curve.
1564
1565
 This module implements signing and verification, key validation, conversions
1566
 between various point representations, and ECDH key agreement.
1567
1568
*******************************************************************************/
1569
1570
/*****************/
1571
/* ECDSA signing */
1572
/*****************/
1573
1574
/**
1575
Create an ECDSA signature WITHOUT hashing first.
1576
1577
  This function is intended to receive a hash of the input.
1578
  For convenience, we recommend using one of the hash-and-sign combined functions above.
1579
1580
  The argument `msg` MUST be at least 32 bytes (i.e. `msg_len >= 32`).
1581
1582
  NOTE: The equivalent functions in OpenSSL and Fiat-Crypto both accept inputs
1583
  smaller than 32 bytes. These libraries left-pad the input with enough zeroes to
1584
  reach the minimum 32 byte size. Clients who need behavior identical to OpenSSL
1585
  need to perform the left-padding themselves.
1586
1587
  The function returns `true` for successful creation of an ECDSA signature and `false` otherwise.
1588
1589
  The outparam `signature` (R || S) points to 64 bytes of valid memory, i.e., uint8_t[64].
1590
  The argument `msg` points to `msg_len` bytes of valid memory, i.e., uint8_t[msg_len].
1591
  The arguments `private_key` and `nonce` point to 32 bytes of valid memory, i.e., uint8_t[32].
1592
1593
  The function also checks whether `private_key` and `nonce` are valid values:
1594
    • 0 < `private_key` < the order of the curve
1595
    • 0 < `nonce` < the order of the curve
1596
*/
1597
bool
1598
Hacl_P256_ecdsa_sign_p256_without_hash(
1599
    uint8_t *signature,
1600
    uint32_t msg_len,
1601
    uint8_t *msg,
1602
    uint8_t *private_key,
1603
    uint8_t *nonce)
1604
0
{
1605
0
    uint64_t m_q[4U] = { 0U };
1606
0
    uint8_t mHash[32U] = { 0U };
1607
0
    memcpy(mHash, msg, (uint32_t)32U * sizeof(uint8_t));
1608
0
    KRML_HOST_IGNORE(msg_len);
1609
0
    uint8_t *mHash32 = mHash;
1610
0
    bn_from_bytes_be4(m_q, mHash32);
1611
0
    qmod_short(m_q, m_q);
1612
0
    bool res = ecdsa_sign_msg_as_qelem(signature, m_q, private_key, nonce);
1613
0
    return res;
1614
0
}
1615
1616
/**********************/
1617
/* ECDSA verification */
1618
/**********************/
1619
1620
/**
1621
Verify an ECDSA signature WITHOUT hashing first.
1622
1623
  This function is intended to receive a hash of the input.
1624
  For convenience, we recommend using one of the hash-and-verify combined functions above.
1625
1626
  The argument `msg` MUST be at least 32 bytes (i.e. `msg_len >= 32`).
1627
1628
  The function returns `true` if the signature is valid and `false` otherwise.
1629
1630
  The argument `msg` points to `msg_len` bytes of valid memory, i.e., uint8_t[msg_len].
1631
  The argument `public_key` (x || y) points to 64 bytes of valid memory, i.e., uint8_t[64].
1632
  The arguments `signature_r` and `signature_s` point to 32 bytes of valid memory, i.e., uint8_t[32].
1633
1634
  The function also checks whether `public_key` is valid
1635
*/
1636
bool
1637
Hacl_P256_ecdsa_verif_without_hash(
1638
    uint32_t msg_len,
1639
    uint8_t *msg,
1640
    uint8_t *public_key,
1641
    uint8_t *signature_r,
1642
    uint8_t *signature_s)
1643
108
{
1644
108
    uint64_t m_q[4U] = { 0U };
1645
108
    uint8_t mHash[32U] = { 0U };
1646
108
    memcpy(mHash, msg, (uint32_t)32U * sizeof(uint8_t));
1647
108
    KRML_HOST_IGNORE(msg_len);
1648
108
    uint8_t *mHash32 = mHash;
1649
108
    bn_from_bytes_be4(m_q, mHash32);
1650
108
    qmod_short(m_q, m_q);
1651
108
    bool res = ecdsa_verify_msg_as_qelem(m_q, public_key, signature_r, signature_s);
1652
108
    return res;
1653
108
}
1654
1655
/******************/
1656
/* Key validation */
1657
/******************/
1658
1659
/**
1660
Public key validation.
1661
1662
  The function returns `true` if a public key is valid and `false` otherwise.
1663
1664
  The argument `public_key` points to 64 bytes of valid memory, i.e., uint8_t[64].
1665
1666
  The public key (x || y) is valid (with respect to SP 800-56A):
1667
    • the public key is not the “point at infinity”, represented as O.
1668
    • the affine x and y coordinates of the point represented by the public key are
1669
      in the range [0, p – 1] where p is the prime defining the finite field.
1670
    • y^2 = x^3 + ax + b where a and b are the coefficients of the curve equation.
1671
  The last extract is taken from: https://neilmadden.blog/2017/05/17/so-how-do-you-validate-nist-ecdh-public-keys/
1672
*/
1673
bool
1674
Hacl_P256_validate_public_key(uint8_t *public_key)
1675
45.5k
{
1676
45.5k
    uint64_t point_jac[12U] = { 0U };
1677
45.5k
    bool res = load_point_vartime(point_jac, public_key);
1678
45.5k
    return res;
1679
45.5k
}
1680
1681
/**
1682
Private key validation.
1683
1684
  The function returns `true` if a private key is valid and `false` otherwise.
1685
1686
  The argument `private_key` points to 32 bytes of valid memory, i.e., uint8_t[32].
1687
1688
  The private key is valid:
1689
    • 0 < `private_key` < the order of the curve
1690
*/
1691
bool
1692
Hacl_P256_validate_private_key(uint8_t *private_key)
1693
22.5k
{
1694
22.5k
    uint64_t bn_sk[4U] = { 0U };
1695
22.5k
    bn_from_bytes_be4(bn_sk, private_key);
1696
22.5k
    uint64_t res = bn_is_lt_order_and_gt_zero_mask4(bn_sk);
1697
22.5k
    return res == (uint64_t)0xFFFFFFFFFFFFFFFFU;
1698
22.5k
}
1699
1700
/*******************************************************************************
1701
  Parsing and Serializing public keys.
1702
1703
  A public key is a point (x, y) on the P-256 NIST curve.
1704
1705
  The point can be represented in the following three ways.
1706
    • raw          = [ x || y ], 64 bytes
1707
    • uncompressed = [ 0x04 || x || y ], 65 bytes
1708
    • compressed   = [ (0x02 for even `y` and 0x03 for odd `y`) || x ], 33 bytes
1709
1710
*******************************************************************************/
1711
1712
/**
1713
Convert a public key from uncompressed to its raw form.
1714
1715
  The function returns `true` for successful conversion of a public key and `false` otherwise.
1716
1717
  The outparam `pk_raw` points to 64 bytes of valid memory, i.e., uint8_t[64].
1718
  The argument `pk` points to 65 bytes of valid memory, i.e., uint8_t[65].
1719
1720
  The function DOESN'T check whether (x, y) is a valid point.
1721
*/
1722
bool
1723
Hacl_P256_uncompressed_to_raw(uint8_t *pk, uint8_t *pk_raw)
1724
0
{
1725
0
    uint8_t pk0 = pk[0U];
1726
0
    if (pk0 != (uint8_t)0x04U) {
1727
0
        return false;
1728
0
    }
1729
0
    memcpy(pk_raw, pk + (uint32_t)1U, (uint32_t)64U * sizeof(uint8_t));
1730
0
    return true;
1731
0
}
1732
1733
/**
1734
Convert a public key from compressed to its raw form.
1735
1736
  The function returns `true` for successful conversion of a public key and `false` otherwise.
1737
1738
  The outparam `pk_raw` points to 64 bytes of valid memory, i.e., uint8_t[64].
1739
  The argument `pk` points to 33 bytes of valid memory, i.e., uint8_t[33].
1740
1741
  The function also checks whether (x, y) is a valid point.
1742
*/
1743
bool
1744
Hacl_P256_compressed_to_raw(uint8_t *pk, uint8_t *pk_raw)
1745
0
{
1746
0
    uint64_t xa[4U] = { 0U };
1747
0
    uint64_t ya[4U] = { 0U };
1748
0
    uint8_t *pk_xb = pk + (uint32_t)1U;
1749
0
    bool b = aff_point_decompress_vartime(xa, ya, pk);
1750
0
    if (b) {
1751
0
        memcpy(pk_raw, pk_xb, (uint32_t)32U * sizeof(uint8_t));
1752
0
        bn_to_bytes_be4(pk_raw + (uint32_t)32U, ya);
1753
0
    }
1754
0
    return b;
1755
0
}
1756
1757
/**
1758
Convert a public key from raw to its uncompressed form.
1759
1760
  The outparam `pk` points to 65 bytes of valid memory, i.e., uint8_t[65].
1761
  The argument `pk_raw` points to 64 bytes of valid memory, i.e., uint8_t[64].
1762
1763
  The function DOESN'T check whether (x, y) is a valid point.
1764
*/
1765
void
1766
Hacl_P256_raw_to_uncompressed(uint8_t *pk_raw, uint8_t *pk)
1767
0
{
1768
0
    pk[0U] = (uint8_t)0x04U;
1769
0
    memcpy(pk + (uint32_t)1U, pk_raw, (uint32_t)64U * sizeof(uint8_t));
1770
0
}
1771
1772
/**
1773
Convert a public key from raw to its compressed form.
1774
1775
  The outparam `pk` points to 33 bytes of valid memory, i.e., uint8_t[33].
1776
  The argument `pk_raw` points to 64 bytes of valid memory, i.e., uint8_t[64].
1777
1778
  The function DOESN'T check whether (x, y) is a valid point.
1779
*/
1780
void
1781
Hacl_P256_raw_to_compressed(uint8_t *pk_raw, uint8_t *pk)
1782
0
{
1783
0
    uint8_t *pk_x = pk_raw;
1784
0
    uint8_t *pk_y = pk_raw + (uint32_t)32U;
1785
0
    uint64_t bn_f[4U] = { 0U };
1786
0
    bn_from_bytes_be4(bn_f, pk_y);
1787
0
    uint64_t is_odd_f = bn_f[0U] & (uint64_t)1U;
1788
0
    pk[0U] = (uint8_t)is_odd_f + (uint8_t)0x02U;
1789
0
    memcpy(pk + (uint32_t)1U, pk_x, (uint32_t)32U * sizeof(uint8_t));
1790
0
}
1791
1792
/******************/
1793
/* ECDH agreement */
1794
/******************/
1795
1796
/**
1797
Compute the public key from the private key.
1798
1799
  The function returns `true` if a private key is valid and `false` otherwise.
1800
1801
  The outparam `public_key`  points to 64 bytes of valid memory, i.e., uint8_t[64].
1802
  The argument `private_key` points to 32 bytes of valid memory, i.e., uint8_t[32].
1803
1804
  The private key is valid:
1805
    • 0 < `private_key` < the order of the curve.
1806
*/
1807
bool
1808
Hacl_P256_dh_initiator(uint8_t *public_key, uint8_t *private_key)
1809
22.5k
{
1810
22.5k
    return Hacl_Impl_P256_DH_ecp256dh_i(public_key, private_key);
1811
22.5k
}
1812
1813
/**
1814
Execute the diffie-hellmann key exchange.
1815
1816
  The function returns `true` for successful creation of an ECDH shared secret and
1817
  `false` otherwise.
1818
1819
  The outparam `shared_secret` points to 64 bytes of valid memory, i.e., uint8_t[64].
1820
  The argument `their_pubkey` points to 64 bytes of valid memory, i.e., uint8_t[64].
1821
  The argument `private_key` points to 32 bytes of valid memory, i.e., uint8_t[32].
1822
1823
  The function also checks whether `private_key` and `their_pubkey` are valid.
1824
*/
1825
bool
1826
Hacl_P256_dh_responder(uint8_t *shared_secret, uint8_t *their_pubkey, uint8_t *private_key)
1827
22.4k
{
1828
22.4k
    return Hacl_Impl_P256_DH_ecp256dh_r(shared_secret, their_pubkey, private_key);
1829
22.4k
}