/src/openssl/crypto/ec/curve448/field.h
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved.  | 
3  |  |  * Copyright 2014 Cryptography Research, Inc.  | 
4  |  |  *  | 
5  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use  | 
6  |  |  * this file except in compliance with the License.  You can obtain a copy  | 
7  |  |  * in the file LICENSE in the source distribution or at  | 
8  |  |  * https://www.openssl.org/source/license.html  | 
9  |  |  *  | 
10  |  |  * Originally written by Mike Hamburg  | 
11  |  |  */  | 
12  |  |  | 
13  |  | #ifndef OSSL_CRYPTO_EC_CURVE448_FIELD_H  | 
14  |  | # define OSSL_CRYPTO_EC_CURVE448_FIELD_H  | 
15  |  |  | 
16  |  | # include "internal/constant_time.h"  | 
17  |  | # include <string.h>  | 
18  |  | # include <assert.h>  | 
19  |  | # include "word.h"  | 
20  |  |  | 
21  | 0  | # define NLIMBS (64/sizeof(word_t))  | 
22  | 0  | # define X_SER_BYTES 56  | 
23  | 0  | # define SER_BYTES 56  | 
24  |  |  | 
25  |  | # if defined(__GNUC__) || defined(__clang__)  | 
26  |  | #  define INLINE_UNUSED __inline__ __attribute__((__unused__,__always_inline__))  | 
27  |  | #  define RESTRICT __restrict__  | 
28  |  | #  define ALIGNED __attribute__((__aligned__(16)))  | 
29  |  | # else  | 
30  |  | #  define INLINE_UNUSED ossl_inline  | 
31  |  | #  define RESTRICT  | 
32  |  | #  define ALIGNED  | 
33  |  | # endif  | 
34  |  |  | 
35  |  | typedef struct gf_s { | 
36  |  |     word_t limb[NLIMBS];  | 
37  |  | } ALIGNED gf_s, gf[1];  | 
38  |  |  | 
39  |  | /* RFC 7748 support */  | 
40  | 0  | # define X_PUBLIC_BYTES  X_SER_BYTES  | 
41  | 0  | # define X_PRIVATE_BYTES X_PUBLIC_BYTES  | 
42  | 0  | # define X_PRIVATE_BITS  448  | 
43  |  |  | 
44  |  | static INLINE_UNUSED void gf_copy(gf out, const gf a)  | 
45  | 0  | { | 
46  | 0  |     *out = *a;  | 
47  | 0  | } Unexecuted instantiation: curve448.c:gf_copy Unexecuted instantiation: curve448_tables.c:gf_copy Unexecuted instantiation: eddsa.c:gf_copy Unexecuted instantiation: f_generic.c:gf_copy Unexecuted instantiation: scalar.c:gf_copy Unexecuted instantiation: f_impl64.c:gf_copy  | 
48  |  |  | 
49  |  | static INLINE_UNUSED void gf_add_RAW(gf out, const gf a, const gf b);  | 
50  |  | static INLINE_UNUSED void gf_sub_RAW(gf out, const gf a, const gf b);  | 
51  |  | static INLINE_UNUSED void gf_bias(gf inout, int amount);  | 
52  |  | static INLINE_UNUSED void gf_weak_reduce(gf inout);  | 
53  |  |  | 
54  |  | void gf_strong_reduce(gf inout);  | 
55  |  | void gf_add(gf out, const gf a, const gf b);  | 
56  |  | void gf_sub(gf out, const gf a, const gf b);  | 
57  |  | void ossl_gf_mul(gf_s * RESTRICT out, const gf a, const gf b);  | 
58  |  | void ossl_gf_mulw_unsigned(gf_s * RESTRICT out, const gf a, uint32_t b);  | 
59  |  | void ossl_gf_sqr(gf_s * RESTRICT out, const gf a);  | 
60  |  | mask_t gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0.  Return true if successful */  | 
61  |  | mask_t gf_eq(const gf x, const gf y);  | 
62  |  | mask_t gf_lobit(const gf x);  | 
63  |  | mask_t gf_hibit(const gf x);  | 
64  |  |  | 
65  |  | void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_highbit);  | 
66  |  | mask_t gf_deserialize(gf x, const uint8_t serial[SER_BYTES], int with_hibit,  | 
67  |  |                       uint8_t hi_nmask);  | 
68  |  |  | 
69  |  |  | 
70  | 0  | # define LIMBPERM(i) (i)  | 
71  |  | # if (ARCH_WORD_BITS == 32)  | 
72  |  | #  include "arch_32/f_impl.h"    /* Bring in the inline implementations */  | 
73  |  | #  define LIMB_MASK(i) (((1)<<LIMB_PLACE_VALUE(i))-1)  | 
74  |  | # elif (ARCH_WORD_BITS == 64)  | 
75  |  | #  include "arch_64/f_impl.h"    /* Bring in the inline implementations */  | 
76  | 0  | #  define LIMB_MASK(i) (((1ULL)<<LIMB_PLACE_VALUE(i))-1)  | 
77  |  | # endif  | 
78  |  |  | 
79  |  | static const gf ZERO = {{{0}}}, ONE = {{{1}}}; | 
80  |  |  | 
81  |  | /* Square x, n times. */  | 
82  |  | static ossl_inline void gf_sqrn(gf_s * RESTRICT y, const gf x, int n)  | 
83  | 0  | { | 
84  | 0  |     gf tmp;  | 
85  |  | 
  | 
86  | 0  |     assert(n > 0);  | 
87  | 0  |     if (n & 1) { | 
88  | 0  |         ossl_gf_sqr(y, x);  | 
89  | 0  |         n--;  | 
90  | 0  |     } else { | 
91  | 0  |         ossl_gf_sqr(tmp, x);  | 
92  | 0  |         ossl_gf_sqr(y, tmp);  | 
93  | 0  |         n -= 2;  | 
94  | 0  |     }  | 
95  | 0  |     for (; n; n -= 2) { | 
96  | 0  |         ossl_gf_sqr(tmp, y);  | 
97  | 0  |         ossl_gf_sqr(y, tmp);  | 
98  | 0  |     }  | 
99  | 0  | } Unexecuted instantiation: curve448.c:gf_sqrn Unexecuted instantiation: curve448_tables.c:gf_sqrn Unexecuted instantiation: eddsa.c:gf_sqrn Unexecuted instantiation: f_generic.c:gf_sqrn Unexecuted instantiation: scalar.c:gf_sqrn Unexecuted instantiation: f_impl64.c:gf_sqrn  | 
100  |  |  | 
101  | 0  | # define gf_add_nr gf_add_RAW  | 
102  |  |  | 
103  |  | /* Subtract mod p.  Bias by 2 and don't reduce  */  | 
104  |  | static ossl_inline void gf_sub_nr(gf c, const gf a, const gf b)  | 
105  | 0  | { | 
106  | 0  |     gf_sub_RAW(c, a, b);  | 
107  | 0  |     gf_bias(c, 2);  | 
108  | 0  |     if (GF_HEADROOM < 3)  | 
109  | 0  |         gf_weak_reduce(c);  | 
110  | 0  | } Unexecuted instantiation: curve448.c:gf_sub_nr Unexecuted instantiation: curve448_tables.c:gf_sub_nr Unexecuted instantiation: eddsa.c:gf_sub_nr Unexecuted instantiation: f_generic.c:gf_sub_nr Unexecuted instantiation: scalar.c:gf_sub_nr Unexecuted instantiation: f_impl64.c:gf_sub_nr  | 
111  |  |  | 
112  |  | /* Subtract mod p. Bias by amt but don't reduce.  */  | 
113  |  | static ossl_inline void gf_subx_nr(gf c, const gf a, const gf b, int amt)  | 
114  | 0  | { | 
115  | 0  |     gf_sub_RAW(c, a, b);  | 
116  | 0  |     gf_bias(c, amt);  | 
117  | 0  |     if (GF_HEADROOM < amt + 1)  | 
118  | 0  |         gf_weak_reduce(c);  | 
119  | 0  | } Unexecuted instantiation: curve448.c:gf_subx_nr Unexecuted instantiation: curve448_tables.c:gf_subx_nr Unexecuted instantiation: eddsa.c:gf_subx_nr Unexecuted instantiation: f_generic.c:gf_subx_nr Unexecuted instantiation: scalar.c:gf_subx_nr Unexecuted instantiation: f_impl64.c:gf_subx_nr  | 
120  |  |  | 
121  |  | /* Mul by signed int.  Not constant-time WRT the sign of that int. */  | 
122  |  | static ossl_inline void gf_mulw(gf c, const gf a, int32_t w)  | 
123  | 0  | { | 
124  | 0  |     if (w > 0) { | 
125  | 0  |         ossl_gf_mulw_unsigned(c, a, w);  | 
126  | 0  |     } else { | 
127  | 0  |         ossl_gf_mulw_unsigned(c, a, -w);  | 
128  | 0  |         gf_sub(c, ZERO, c);  | 
129  | 0  |     }  | 
130  | 0  | } Unexecuted instantiation: curve448.c:gf_mulw Unexecuted instantiation: curve448_tables.c:gf_mulw Unexecuted instantiation: eddsa.c:gf_mulw Unexecuted instantiation: f_generic.c:gf_mulw Unexecuted instantiation: scalar.c:gf_mulw Unexecuted instantiation: f_impl64.c:gf_mulw  | 
131  |  |  | 
132  |  | /* Constant time, x = is_z ? z : y */  | 
133  |  | static ossl_inline void gf_cond_sel(gf x, const gf y, const gf z, mask_t is_z)  | 
134  | 0  | { | 
135  | 0  |     size_t i;  | 
136  |  | 
  | 
137  | 0  |     for (i = 0; i < NLIMBS; i++) { | 
138  |  | #if ARCH_WORD_BITS == 32  | 
139  |  |         x[0].limb[i] = constant_time_select_32(is_z, z[0].limb[i],  | 
140  |  |                                                y[0].limb[i]);  | 
141  |  | #else  | 
142  |  |         /* Must be 64 bit */  | 
143  | 0  |         x[0].limb[i] = constant_time_select_64(is_z, z[0].limb[i],  | 
144  | 0  |                                                y[0].limb[i]);  | 
145  | 0  | #endif  | 
146  | 0  |     }  | 
147  | 0  | } Unexecuted instantiation: curve448.c:gf_cond_sel Unexecuted instantiation: curve448_tables.c:gf_cond_sel Unexecuted instantiation: eddsa.c:gf_cond_sel Unexecuted instantiation: f_generic.c:gf_cond_sel Unexecuted instantiation: scalar.c:gf_cond_sel Unexecuted instantiation: f_impl64.c:gf_cond_sel  | 
148  |  |  | 
149  |  | /* Constant time, if (neg) x=-x; */  | 
150  |  | static ossl_inline void gf_cond_neg(gf x, mask_t neg)  | 
151  | 0  | { | 
152  | 0  |     gf y;  | 
153  |  | 
  | 
154  | 0  |     gf_sub(y, ZERO, x);  | 
155  | 0  |     gf_cond_sel(x, x, y, neg);  | 
156  | 0  | } Unexecuted instantiation: curve448.c:gf_cond_neg Unexecuted instantiation: curve448_tables.c:gf_cond_neg Unexecuted instantiation: eddsa.c:gf_cond_neg Unexecuted instantiation: f_generic.c:gf_cond_neg Unexecuted instantiation: scalar.c:gf_cond_neg Unexecuted instantiation: f_impl64.c:gf_cond_neg  | 
157  |  |  | 
158  |  | /* Constant time, if (swap) (x,y) = (y,x); */  | 
159  |  | static ossl_inline void gf_cond_swap(gf x, gf_s * RESTRICT y, mask_t swap)  | 
160  | 0  | { | 
161  | 0  |     size_t i;  | 
162  |  | 
  | 
163  | 0  |     for (i = 0; i < NLIMBS; i++) { | 
164  |  | #if ARCH_WORD_BITS == 32  | 
165  |  |         constant_time_cond_swap_32(swap, &(x[0].limb[i]), &(y->limb[i]));  | 
166  |  | #else  | 
167  |  |         /* Must be 64 bit */  | 
168  | 0  |         constant_time_cond_swap_64(swap, &(x[0].limb[i]), &(y->limb[i]));  | 
169  | 0  | #endif  | 
170  | 0  |     }  | 
171  | 0  | } Unexecuted instantiation: curve448.c:gf_cond_swap Unexecuted instantiation: curve448_tables.c:gf_cond_swap Unexecuted instantiation: eddsa.c:gf_cond_swap Unexecuted instantiation: f_generic.c:gf_cond_swap Unexecuted instantiation: scalar.c:gf_cond_swap Unexecuted instantiation: f_impl64.c:gf_cond_swap  | 
172  |  |  | 
173  |  | #endif                          /* OSSL_CRYPTO_EC_CURVE448_FIELD_H */  |