1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #ifndef __ecl_priv_h_
6 #define __ecl_priv_h_
7 
8 #include "ecl.h"
9 #include "mpi.h"
10 #include "mplogic.h"
11 #include "../blapii.h"
12 
13 /* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
14 /* the following needs to go away... */
15 #if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT)
16 #define ECL_SIXTY_FOUR_BIT
17 #else
18 #define ECL_THIRTY_TWO_BIT
19 #endif
20 
21 #define ECL_CURVE_DIGITS(curve_size_in_bits) \
22     (((curve_size_in_bits) + (sizeof(mp_digit) * 8 - 1)) / (sizeof(mp_digit) * 8))
23 #define ECL_BITS (sizeof(mp_digit) * 8)
24 #define ECL_MAX_FIELD_SIZE_DIGITS (80 / sizeof(mp_digit))
25 
26 /* Gets the i'th bit in the binary representation of a. If i >= length(a),
27  * then return 0. (The above behaviour differs from mpl_get_bit, which
28  * causes an error if i >= length(a).) */
29 #define MP_GET_BIT(a, i) \
30     ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
31 
32 #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
33 #define MP_ADD_CARRY(a1, a2, s, carry)      \
34     {                                       \
35         mp_word w;                          \
36         w = ((mp_word)carry) + (a1) + (a2); \
37         s = ACCUM(w);                       \
38         carry = CARRYOUT(w);                \
39     }
40 
41 #define MP_SUB_BORROW(a1, a2, s, borrow)   \
42     {                                      \
43         mp_word w;                         \
44         w = ((mp_word)(a1)) - (a2)-borrow; \
45         s = ACCUM(w);                      \
46         borrow = (w >> MP_DIGIT_BIT) & 1;  \
47     }
48 
49 #else
50 /* NOTE,
51  * carry and borrow are both read and written.
52  * a1 or a2 and s could be the same variable.
53  * don't trash those outputs until their respective inputs have
54  * been read. */
55 #define MP_ADD_CARRY(a1, a2, s, carry)           \
56     {                                            \
57         mp_digit tmp, sum;                       \
58         tmp = (a1);                              \
59         sum = tmp + (a2);                        \
60         tmp = (sum < tmp); /* detect overflow */ \
61         s = sum += carry;                        \
62         carry = tmp + (sum < carry);             \
63     }
64 
65 #define MP_SUB_BORROW(a1, a2, s, borrow)     \
66     {                                        \
67         mp_digit tmp;                        \
68         tmp = (a1);                          \
69         s = tmp - (a2);                      \
70         tmp = (s > tmp); /* detect borrow */ \
71         if (borrow && !s--)                  \
72             tmp++;                           \
73         borrow = tmp;                        \
74     }
75 #endif
76 
77 struct GFMethodStr;
78 typedef struct GFMethodStr GFMethod;
79 struct GFMethodStr {
80     /* Indicates whether the structure was constructed from dynamic memory
81      * or statically created. */
82     int constructed;
83     /* Irreducible that defines the field. For prime fields, this is the
84      * prime p. For binary polynomial fields, this is the bitstring
85      * representation of the irreducible polynomial. */
86     mp_int irr;
87     /* For prime fields, the value irr_arr[0] is the number of bits in the
88      * field. For binary polynomial fields, the irreducible polynomial
89      * f(t) is represented as an array of unsigned int[], where f(t) is
90      * of the form: f(t) = t^p[0] + t^p[1] + ... + t^p[4] where m = p[0]
91      * > p[1] > ... > p[4] = 0. */
92     unsigned int irr_arr[5];
93     /* Field arithmetic methods. All methods (except field_enc and
94      * field_dec) are assumed to take field-encoded parameters and return
95      * field-encoded values. All methods (except field_enc and field_dec)
96      * are required to be implemented. */
97     mp_err (*field_add)(const mp_int *a, const mp_int *b, mp_int *r,
98                         const GFMethod *meth);
99     mp_err (*field_neg)(const mp_int *a, mp_int *r, const GFMethod *meth);
100     mp_err (*field_sub)(const mp_int *a, const mp_int *b, mp_int *r,
101                         const GFMethod *meth);
102     mp_err (*field_mod)(const mp_int *a, mp_int *r, const GFMethod *meth);
103     mp_err (*field_mul)(const mp_int *a, const mp_int *b, mp_int *r,
104                         const GFMethod *meth);
105     mp_err (*field_sqr)(const mp_int *a, mp_int *r, const GFMethod *meth);
106     mp_err (*field_div)(const mp_int *a, const mp_int *b, mp_int *r,
107                         const GFMethod *meth);
108     mp_err (*field_enc)(const mp_int *a, mp_int *r, const GFMethod *meth);
109     mp_err (*field_dec)(const mp_int *a, mp_int *r, const GFMethod *meth);
110     /* Extra storage for implementation-specific data.  Any memory
111      * allocated to these extra fields will be cleared by extra_free. */
112     void *extra1;
113     void *extra2;
114     void (*extra_free)(GFMethod *meth);
115 };
116 
117 /* Construct generic GFMethods. */
118 GFMethod *GFMethod_consGFp(const mp_int *irr);
119 GFMethod *GFMethod_consGFp_mont(const mp_int *irr);
120 
121 /* Free the memory allocated (if any) to a GFMethod object. */
122 void GFMethod_free(GFMethod *meth);
123 
124 struct ECGroupStr {
125     /* Indicates whether the structure was constructed from dynamic memory
126      * or statically created. */
127     int constructed;
128     /* Field definition and arithmetic. */
129     GFMethod *meth;
130     /* Textual representation of curve name, if any. */
131     char *text;
132     /* Curve parameters, field-encoded. */
133     mp_int curvea, curveb;
134     /* x and y coordinates of the base point, field-encoded. */
135     mp_int genx, geny;
136     /* Order and cofactor of the base point. */
137     mp_int order;
138     int cofactor;
139     /* Point arithmetic methods. All methods are assumed to take
140      * field-encoded parameters and return field-encoded values. All
141      * methods (except base_point_mul and points_mul) are required to be
142      * implemented. */
143     mp_err (*point_add)(const mp_int *px, const mp_int *py,
144                         const mp_int *qx, const mp_int *qy, mp_int *rx,
145                         mp_int *ry, const ECGroup *group);
146     mp_err (*point_sub)(const mp_int *px, const mp_int *py,
147                         const mp_int *qx, const mp_int *qy, mp_int *rx,
148                         mp_int *ry, const ECGroup *group);
149     mp_err (*point_dbl)(const mp_int *px, const mp_int *py, mp_int *rx,
150                         mp_int *ry, const ECGroup *group);
151     mp_err (*point_mul)(const mp_int *n, const mp_int *px,
152                         const mp_int *py, mp_int *rx, mp_int *ry,
153                         const ECGroup *group);
154     mp_err (*base_point_mul)(const mp_int *n, mp_int *rx, mp_int *ry,
155                              const ECGroup *group);
156     mp_err (*points_mul)(const mp_int *k1, const mp_int *k2,
157                          const mp_int *px, const mp_int *py, mp_int *rx,
158                          mp_int *ry, const ECGroup *group);
159     mp_err (*validate_point)(const mp_int *px, const mp_int *py, const ECGroup *group);
160     /* Extra storage for implementation-specific data.  Any memory
161      * allocated to these extra fields will be cleared by extra_free. */
162     void *extra1;
163     void *extra2;
164     void (*extra_free)(ECGroup *group);
165 };
166 
167 /* Wrapper functions for generic prime field arithmetic. */
168 mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
169                   const GFMethod *meth);
170 mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
171 mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
172                   const GFMethod *meth);
173 
174 /* fixed length in-line adds. Count is in words */
175 mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
176                     const GFMethod *meth);
177 mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
178                     const GFMethod *meth);
179 mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
180                     const GFMethod *meth);
181 mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
182                     const GFMethod *meth);
183 mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
184                     const GFMethod *meth);
185 mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
186                     const GFMethod *meth);
187 mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
188                     const GFMethod *meth);
189 mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
190                     const GFMethod *meth);
191 
192 mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
193 mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
194                   const GFMethod *meth);
195 mp_err ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
196 mp_err ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
197                   const GFMethod *meth);
198 /* Wrapper functions for generic binary polynomial field arithmetic. */
199 mp_err ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
200                    const GFMethod *meth);
201 mp_err ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
202 mp_err ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
203 mp_err ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
204                    const GFMethod *meth);
205 mp_err ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
206 mp_err ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
207                    const GFMethod *meth);
208 
209 /* Montgomery prime field arithmetic. */
210 mp_err ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
211                        const GFMethod *meth);
212 mp_err ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
213 mp_err ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
214                        const GFMethod *meth);
215 mp_err ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
216 mp_err ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
217 void ec_GFp_extra_free_mont(GFMethod *meth);
218 
219 /* point multiplication */
220 mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
221                         const mp_int *px, const mp_int *py, mp_int *rx,
222                         mp_int *ry, const ECGroup *group);
223 mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
224                            const mp_int *px, const mp_int *py, mp_int *rx,
225                            mp_int *ry, const ECGroup *group);
226 
227 /* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
228  * be an array of signed char's to output to, bitsize should be the number
229  * of bits of out, in is the original scalar, and w is the window size.
230  * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
231  * Menezes, "Software implementation of elliptic curve cryptography over
232  * binary fields", Proc. CHES 2000. */
233 mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in,
234                        int w);
235 
236 /* Optimized field arithmetic */
237 mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
238 mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName);
239 mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName);
240 mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName);
241 mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName);
242 mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name);
243 mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name);
244 mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
245 
246 /* Optimized point multiplication */
247 mp_err ec_group_set_gfp256_32(ECGroup *group, ECCurveName name);
248 mp_err ec_group_set_secp384r1(ECGroup *group, ECCurveName name);
249 mp_err ec_group_set_secp521r1(ECGroup *group, ECCurveName name);
250 
251 SECStatus ec_Curve25519_mul(PRUint8 *q, const PRUint8 *s, const PRUint8 *p);
252 #endif /* __ecl_priv_h_ */
253