• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2014, Intel Corporation. All Rights Reserved.
4  *
5  * Licensed under the OpenSSL license (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  *
10  * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1)
11  * (1) Intel Corporation, Israel Development Center, Haifa, Israel
12  * (2) University of Haifa, Israel
13  *
14  * Reference:
15  * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with
16  *                          256 Bit Primes"
17  */
18 
19 #ifndef OPENSSL_HEADER_EC_P256_X86_64_H
20 #define OPENSSL_HEADER_EC_P256_X86_64_H
21 
22 #include <openssl/base.h>
23 
24 #include <openssl/bn.h>
25 
26 #include "../bn/internal.h"
27 
28 #if defined(__cplusplus)
29 extern "C" {
30 #endif
31 
32 
33 #if !defined(OPENSSL_NO_ASM) && \
34     (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) &&   \
35     !defined(OPENSSL_SMALL)
36 
37 // P-256 field operations.
38 //
39 // An element mod P in P-256 is represented as a little-endian array of
40 // |P256_LIMBS| |BN_ULONG|s, spanning the full range of values.
41 //
42 // The following functions take fully-reduced inputs mod P and give
43 // fully-reduced outputs. They may be used in-place.
44 
45 #define P256_LIMBS (256 / BN_BITS2)
46 
47 // ecp_nistz256_neg sets |res| to -|a| mod P.
48 void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
49 
50 // ecp_nistz256_mul_mont sets |res| to |a| * |b| * 2^-256 mod P.
51 #if defined(OPENSSL_X86_64)
52 void ecp_nistz256_mul_mont_nohw(BN_ULONG res[P256_LIMBS],
53                                 const BN_ULONG a[P256_LIMBS],
54                                 const BN_ULONG b[P256_LIMBS]);
55 void ecp_nistz256_mul_mont_adx(BN_ULONG res[P256_LIMBS],
56                                const BN_ULONG a[P256_LIMBS],
57                                const BN_ULONG b[P256_LIMBS]);
58 #else
59 void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS],
60                            const BN_ULONG a[P256_LIMBS],
61                            const BN_ULONG b[P256_LIMBS]);
62 #endif
63 
64 // ecp_nistz256_sqr_mont sets |res| to |a| * |a| * 2^-256 mod P.
65 #if defined(OPENSSL_X86_64)
66 void ecp_nistz256_sqr_mont_nohw(BN_ULONG res[P256_LIMBS],
67                                 const BN_ULONG a[P256_LIMBS]);
68 void ecp_nistz256_sqr_mont_adx(BN_ULONG res[P256_LIMBS],
69                                const BN_ULONG a[P256_LIMBS]);
70 #else
71 void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
72                            const BN_ULONG a[P256_LIMBS]);
73 #endif
74 
75 
76 // P-256 scalar operations.
77 //
78 // The following functions compute modulo N, where N is the order of P-256. They
79 // take fully-reduced inputs and give fully-reduced outputs.
80 
81 // ecp_nistz256_ord_mul_mont sets |res| to |a| * |b| where inputs and outputs
82 // are in Montgomery form. That is, |res| is |a| * |b| * 2^-256 mod N.
83 #if defined(OPENSSL_X86_64)
84 void ecp_nistz256_ord_mul_mont_nohw(BN_ULONG res[P256_LIMBS],
85                                     const BN_ULONG a[P256_LIMBS],
86                                     const BN_ULONG b[P256_LIMBS]);
87 void ecp_nistz256_ord_mul_mont_adx(BN_ULONG res[P256_LIMBS],
88                                    const BN_ULONG a[P256_LIMBS],
89                                    const BN_ULONG b[P256_LIMBS]);
90 #else
91 void ecp_nistz256_ord_mul_mont(BN_ULONG res[P256_LIMBS],
92                                const BN_ULONG a[P256_LIMBS],
93                                const BN_ULONG b[P256_LIMBS]);
94 #endif
95 
96 // ecp_nistz256_ord_sqr_mont sets |res| to |a|^(2*|rep|) where inputs and
97 // outputs are in Montgomery form. That is, |res| is
98 // (|a| * 2^-256)^(2*|rep|) * 2^256 mod N.
99 #if defined(OPENSSL_X86_64)
100 void ecp_nistz256_ord_sqr_mont_nohw(BN_ULONG res[P256_LIMBS],
101                                     const BN_ULONG a[P256_LIMBS], BN_ULONG rep);
102 void ecp_nistz256_ord_sqr_mont_adx(BN_ULONG res[P256_LIMBS],
103                                    const BN_ULONG a[P256_LIMBS], BN_ULONG rep);
104 #else
105 void ecp_nistz256_ord_sqr_mont(BN_ULONG res[P256_LIMBS],
106                                const BN_ULONG a[P256_LIMBS], BN_ULONG rep);
107 #endif
108 
109 // beeu_mod_inverse_vartime sets out = a^-1 mod p using a Euclidean algorithm.
110 // Assumption: 0 < a < p < 2^(256) and p is odd.
111 int beeu_mod_inverse_vartime(BN_ULONG out[P256_LIMBS],
112                              const BN_ULONG a[P256_LIMBS],
113                              const BN_ULONG p[P256_LIMBS]);
114 
115 
116 // P-256 point operations.
117 //
118 // The following functions may be used in-place. All coordinates are in the
119 // Montgomery domain.
120 
121 // A P256_POINT represents a P-256 point in Jacobian coordinates.
122 typedef struct {
123   BN_ULONG X[P256_LIMBS];
124   BN_ULONG Y[P256_LIMBS];
125   BN_ULONG Z[P256_LIMBS];
126 } P256_POINT;
127 
128 // A P256_POINT_AFFINE represents a P-256 point in affine coordinates. Infinity
129 // is encoded as (0, 0).
130 typedef struct {
131   BN_ULONG X[P256_LIMBS];
132   BN_ULONG Y[P256_LIMBS];
133 } P256_POINT_AFFINE;
134 
135 // ecp_nistz256_select_w5 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 16
136 // and all zeros (the point at infinity) if |index| is 0. This is done in
137 // constant time.
138 #if defined(OPENSSL_X86_64)
139 void ecp_nistz256_select_w5_nohw(P256_POINT *val, const P256_POINT in_t[16],
140                                  int index);
141 void ecp_nistz256_select_w5_avx2(P256_POINT *val, const P256_POINT in_t[16],
142                                  int index);
143 #else
144 void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT in_t[16],
145                             int index);
146 #endif
147 
148 // ecp_nistz256_select_w7 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 64
149 // and all zeros (the point at infinity) if |index| is 0. This is done in
150 // constant time.
151 #if defined(OPENSSL_X86_64)
152 void ecp_nistz256_select_w7_nohw(P256_POINT_AFFINE *val,
153                                  const P256_POINT_AFFINE in_t[64], int index);
154 void ecp_nistz256_select_w7_avx2(P256_POINT_AFFINE *val,
155                                  const P256_POINT_AFFINE in_t[64], int index);
156 #else
157 void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
158                             const P256_POINT_AFFINE in_t[64], int index);
159 #endif
160 
161 // ecp_nistz256_point_double sets |r| to |a| doubled.
162 #if defined(OPENSSL_X86_64)
163 void ecp_nistz256_point_double_nohw(P256_POINT *r, const P256_POINT *a);
164 void ecp_nistz256_point_double_adx(P256_POINT *r, const P256_POINT *a);
165 #else
166 void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
167 #endif
168 
169 // ecp_nistz256_point_add adds |a| to |b| and places the result in |r|.
170 #if defined(OPENSSL_X86_64)
171 void ecp_nistz256_point_add_nohw(P256_POINT *r, const P256_POINT *a,
172                                  const P256_POINT *b);
173 void ecp_nistz256_point_add_adx(P256_POINT *r, const P256_POINT *a,
174                                 const P256_POINT *b);
175 #else
176 void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
177                             const P256_POINT *b);
178 #endif
179 
180 // ecp_nistz256_point_add_affine adds |a| to |b| and places the result in
181 // |r|. |a| and |b| must not represent the same point unless they are both
182 // infinity.
183 #if defined(OPENSSL_X86_64)
184 void ecp_nistz256_point_add_affine_adx(P256_POINT *r, const P256_POINT *a,
185                                        const P256_POINT_AFFINE *b);
186 void ecp_nistz256_point_add_affine_nohw(P256_POINT *r, const P256_POINT *a,
187                                         const P256_POINT_AFFINE *b);
188 #else
189 void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a,
190                                    const P256_POINT_AFFINE *b);
191 #endif
192 
193 #endif /* !defined(OPENSSL_NO_ASM) && \
194           (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) &&   \
195           !defined(OPENSSL_SMALL) */
196 
197 
198 #if defined(__cplusplus)
199 }  // extern C++
200 #endif
201 
202 #endif  // OPENSSL_HEADER_EC_P256_X86_64_H
203