1/*
2 * Elliptic curves over GF(p): curve-specific data and functions
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#include "common.h"
21
22#if defined(MBEDTLS_ECP_C)
23
24#include "mbedtls/ecp.h"
25#include "mbedtls/platform_util.h"
26#include "mbedtls/error.h"
27#include "mbedtls/bn_mul.h"
28
29#include "ecp_invasive.h"
30
31#include <string.h>
32
33#if !defined(MBEDTLS_ECP_ALT)
34
35/* Parameter validation macros based on platform_util.h */
36#define ECP_VALIDATE_RET(cond) \
37 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA)
38#define ECP_VALIDATE(cond) \
39 MBEDTLS_INTERNAL_VALIDATE(cond)
40
41#define ECP_MPI_INIT(s, n, p) { s, (n), (mbedtls_mpi_uint *) (p) }
42
43#define ECP_MPI_INIT_ARRAY(x) \
44 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
45
46/*
47 * Note: the constants are in little-endian order
48 * to be directly usable in MPIs
49 */
50
51/*
52 * Domain parameters for secp192r1
53 */
54#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
55static const mbedtls_mpi_uint secp192r1_p[] = {
56 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
57 MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
58 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
59};
60static const mbedtls_mpi_uint secp192r1_b[] = {
61 MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE),
62 MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F),
63 MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64),
64};
65static const mbedtls_mpi_uint secp192r1_gx[] = {
66 MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4),
67 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C),
68 MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18),
69};
70static const mbedtls_mpi_uint secp192r1_gy[] = {
71 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73),
72 MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63),
73 MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07),
74};
75static const mbedtls_mpi_uint secp192r1_n[] = {
76 MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14),
77 MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF),
78 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
79};
80#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
81
82/*
83 * Domain parameters for secp224r1
84 */
85#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
86static const mbedtls_mpi_uint secp224r1_p[] = {
87 MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
88 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
89 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
90 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
91};
92static const mbedtls_mpi_uint secp224r1_b[] = {
93 MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27),
94 MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50),
95 MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C),
96 MBEDTLS_BYTES_TO_T_UINT_4(0x85, 0x0A, 0x05, 0xB4),
97};
98static const mbedtls_mpi_uint secp224r1_gx[] = {
99 MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34),
100 MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A),
101 MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B),
102 MBEDTLS_BYTES_TO_T_UINT_4(0xBD, 0x0C, 0x0E, 0xB7),
103};
104static const mbedtls_mpi_uint secp224r1_gy[] = {
105 MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44),
106 MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD),
107 MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5),
108 MBEDTLS_BYTES_TO_T_UINT_4(0x88, 0x63, 0x37, 0xBD),
109};
110static const mbedtls_mpi_uint secp224r1_n[] = {
111 MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13),
112 MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF),
113 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
114 MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF),
115};
116#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
117
118/*
119 * Domain parameters for secp256r1
120 */
121#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
122static const mbedtls_mpi_uint secp256r1_p[] = {
123 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
124 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
125 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
126 MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
127};
128static const mbedtls_mpi_uint secp256r1_b[] = {
129 MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B),
130 MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65),
131 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3),
132 MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A),
133};
134static const mbedtls_mpi_uint secp256r1_gx[] = {
135 MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4),
136 MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77),
137 MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8),
138 MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B),
139};
140static const mbedtls_mpi_uint secp256r1_gy[] = {
141 MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB),
142 MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B),
143 MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E),
144 MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F),
145};
146static const mbedtls_mpi_uint secp256r1_n[] = {
147 MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3),
148 MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC),
149 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
150 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
151};
152#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
153
154/*
155 * Domain parameters for secp384r1
156 */
157#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
158static const mbedtls_mpi_uint secp384r1_p[] = {
159 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
160 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
161 MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
162 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
163 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
164 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
165};
166static const mbedtls_mpi_uint secp384r1_b[] = {
167 MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A),
168 MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6),
169 MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03),
170 MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18),
171 MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98),
172 MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3),
173};
174static const mbedtls_mpi_uint secp384r1_gx[] = {
175 MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A),
176 MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55),
177 MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59),
178 MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E),
179 MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E),
180 MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA),
181};
182static const mbedtls_mpi_uint secp384r1_gy[] = {
183 MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A),
184 MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A),
185 MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9),
186 MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8),
187 MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D),
188 MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36),
189};
190static const mbedtls_mpi_uint secp384r1_n[] = {
191 MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC),
192 MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58),
193 MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7),
194 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
195 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
196 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
197};
198#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
199
200/*
201 * Domain parameters for secp521r1
202 */
203#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
204static const mbedtls_mpi_uint secp521r1_p[] = {
205 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
206 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
207 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
208 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
209 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
210 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
211 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
212 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
213 MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01),
214};
215static const mbedtls_mpi_uint secp521r1_b[] = {
216 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF),
217 MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35),
218 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16),
219 MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56),
220 MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8),
221 MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2),
222 MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92),
223 MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95),
224 MBEDTLS_BYTES_TO_T_UINT_2(0x51, 0x00),
225};
226static const mbedtls_mpi_uint secp521r1_gx[] = {
227 MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9),
228 MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33),
229 MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE),
230 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1),
231 MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8),
232 MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C),
233 MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E),
234 MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85),
235 MBEDTLS_BYTES_TO_T_UINT_2(0xC6, 0x00),
236};
237static const mbedtls_mpi_uint secp521r1_gy[] = {
238 MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88),
239 MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35),
240 MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5),
241 MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97),
242 MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17),
243 MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98),
244 MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C),
245 MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39),
246 MBEDTLS_BYTES_TO_T_UINT_2(0x18, 0x01),
247};
248static const mbedtls_mpi_uint secp521r1_n[] = {
249 MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB),
250 MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B),
251 MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F),
252 MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51),
253 MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
254 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
255 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
256 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
257 MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01),
258};
259#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
260
261#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
262static const mbedtls_mpi_uint secp192k1_p[] = {
263 MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF),
264 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
265 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
266};
267static const mbedtls_mpi_uint secp192k1_a[] = {
268 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
269};
270static const mbedtls_mpi_uint secp192k1_b[] = {
271 MBEDTLS_BYTES_TO_T_UINT_2(0x03, 0x00),
272};
273static const mbedtls_mpi_uint secp192k1_gx[] = {
274 MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D),
275 MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26),
276 MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB),
277};
278static const mbedtls_mpi_uint secp192k1_gy[] = {
279 MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40),
280 MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84),
281 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B),
282};
283static const mbedtls_mpi_uint secp192k1_n[] = {
284 MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F),
285 MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF),
286 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
287};
288#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
289
290#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
291static const mbedtls_mpi_uint secp224k1_p[] = {
292 MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF),
293 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
294 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
295 MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF),
296};
297static const mbedtls_mpi_uint secp224k1_a[] = {
298 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
299};
300static const mbedtls_mpi_uint secp224k1_b[] = {
301 MBEDTLS_BYTES_TO_T_UINT_2(0x05, 0x00),
302};
303static const mbedtls_mpi_uint secp224k1_gx[] = {
304 MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F),
305 MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69),
306 MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D),
307 MBEDTLS_BYTES_TO_T_UINT_4(0x33, 0x5B, 0x45, 0xA1),
308};
309static const mbedtls_mpi_uint secp224k1_gy[] = {
310 MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2),
311 MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7),
312 MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F),
313 MBEDTLS_BYTES_TO_T_UINT_4(0xED, 0x9F, 0x08, 0x7E),
314};
315static const mbedtls_mpi_uint secp224k1_n[] = {
316 MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA),
317 MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00),
318 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
319 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00),
320};
321#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
322
323#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
324static const mbedtls_mpi_uint secp256k1_p[] = {
325 MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF),
326 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
327 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
328 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
329};
330static const mbedtls_mpi_uint secp256k1_a[] = {
331 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
332};
333static const mbedtls_mpi_uint secp256k1_b[] = {
334 MBEDTLS_BYTES_TO_T_UINT_2(0x07, 0x00),
335};
336static const mbedtls_mpi_uint secp256k1_gx[] = {
337 MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59),
338 MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02),
339 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55),
340 MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79),
341};
342static const mbedtls_mpi_uint secp256k1_gy[] = {
343 MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C),
344 MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD),
345 MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D),
346 MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48),
347};
348static const mbedtls_mpi_uint secp256k1_n[] = {
349 MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF),
350 MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA),
351 MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
352 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
353};
354#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
355
356/*
357 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
358 */
359#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
360static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
361 MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20),
362 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E),
363 MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E),
364 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9),
365};
366static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
367 MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9),
368 MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB),
369 MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE),
370 MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D),
371};
372static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
373 MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B),
374 MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95),
375 MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3),
376 MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26),
377};
378static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
379 MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A),
380 MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9),
381 MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C),
382 MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B),
383};
384static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
385 MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C),
386 MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2),
387 MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97),
388 MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54),
389};
390static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
391 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90),
392 MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C),
393 MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E),
394 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9),
395};
396#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
397
398/*
399 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
400 */
401#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
402static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
403 MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87),
404 MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC),
405 MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12),
406 MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15),
407 MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F),
408 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C),
409};
410static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
411 MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04),
412 MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A),
413 MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13),
414 MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2),
415 MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C),
416 MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B),
417};
418static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
419 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A),
420 MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C),
421 MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E),
422 MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F),
423 MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B),
424 MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04),
425};
426static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
427 MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF),
428 MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8),
429 MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB),
430 MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88),
431 MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2),
432 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D),
433};
434static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
435 MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42),
436 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E),
437 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1),
438 MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62),
439 MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C),
440 MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A),
441};
442static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
443 MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B),
444 MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF),
445 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F),
446 MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15),
447 MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F),
448 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C),
449};
450#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
451
452/*
453 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
454 */
455#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
456static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
457 MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28),
458 MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28),
459 MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE),
460 MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D),
461 MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6),
462 MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB),
463 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F),
464 MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA),
465};
466static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
467 MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7),
468 MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F),
469 MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A),
470 MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D),
471 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8),
472 MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94),
473 MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2),
474 MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78),
475};
476static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
477 MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28),
478 MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98),
479 MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77),
480 MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B),
481 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B),
482 MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8),
483 MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA),
484 MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D),
485};
486static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
487 MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B),
488 MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C),
489 MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50),
490 MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF),
491 MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4),
492 MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85),
493 MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A),
494 MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81),
495};
496static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
497 MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78),
498 MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1),
499 MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B),
500 MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2),
501 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0),
502 MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2),
503 MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0),
504 MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D),
505};
506static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
507 MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5),
508 MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D),
509 MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41),
510 MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55),
511 MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6),
512 MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB),
513 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F),
514 MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA),
515};
516#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
517
518#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
519 defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
520 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
521 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
522 defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
523 defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
524 defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
525 defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
526 defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
527 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
528 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
529/* For these curves, we build the group parameters dynamically. */
530#define ECP_LOAD_GROUP
531#endif
532
533#if defined(ECP_LOAD_GROUP)
534/*
535 * Create an MPI from embedded constants
536 * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint))
537 */
538static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len)
539{
540 X->s = 1;
541 X->n = len / sizeof(mbedtls_mpi_uint);
542 X->p = (mbedtls_mpi_uint *) p;
543}
544
545/*
546 * Set an MPI to static value 1
547 */
548static inline void ecp_mpi_set1(mbedtls_mpi *X)
549{
550 static mbedtls_mpi_uint one[] = { 1 };
551 X->s = 1;
552 X->n = 1;
553 X->p = one;
554}
555
556/*
557 * Make group available from embedded constants
558 */
559static int ecp_group_load(mbedtls_ecp_group *grp,
560 const mbedtls_mpi_uint *p, size_t plen,
561 const mbedtls_mpi_uint *a, size_t alen,
562 const mbedtls_mpi_uint *b, size_t blen,
563 const mbedtls_mpi_uint *gx, size_t gxlen,
564 const mbedtls_mpi_uint *gy, size_t gylen,
565 const mbedtls_mpi_uint *n, size_t nlen)
566{
567 ecp_mpi_load(&grp->P, p, plen);
568 if (a != NULL) {
569 ecp_mpi_load(&grp->A, a, alen);
570 }
571 ecp_mpi_load(&grp->B, b, blen);
572 ecp_mpi_load(&grp->N, n, nlen);
573
574 ecp_mpi_load(&grp->G.X, gx, gxlen);
575 ecp_mpi_load(&grp->G.Y, gy, gylen);
576 ecp_mpi_set1(&grp->G.Z);
577
578 grp->pbits = mbedtls_mpi_bitlen(&grp->P);
579 grp->nbits = mbedtls_mpi_bitlen(&grp->N);
580
581 grp->h = 1;
582
583 return 0;
584}
585#endif /* ECP_LOAD_GROUP */
586
587#if defined(MBEDTLS_ECP_NIST_OPTIM)
588/* Forward declarations */
589#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
590static int ecp_mod_p192(mbedtls_mpi *);
591#endif
592#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
593static int ecp_mod_p224(mbedtls_mpi *);
594#endif
595#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
596static int ecp_mod_p256(mbedtls_mpi *);
597#endif
598#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
599static int ecp_mod_p384(mbedtls_mpi *);
600#endif
601#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
602static int ecp_mod_p521(mbedtls_mpi *);
603#endif
604
605#define NIST_MODP(P) grp->modp = ecp_mod_ ## P;
606#else
607#define NIST_MODP(P)
608#endif /* MBEDTLS_ECP_NIST_OPTIM */
609
610/* Additional forward declarations */
611#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
612static int ecp_mod_p255(mbedtls_mpi *);
613#endif
614#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
615static int ecp_mod_p448(mbedtls_mpi *);
616#endif
617#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
618static int ecp_mod_p192k1(mbedtls_mpi *);
619#endif
620#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
621static int ecp_mod_p224k1(mbedtls_mpi *);
622#endif
623#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
624static int ecp_mod_p256k1(mbedtls_mpi *);
625#endif
626
627#if defined(ECP_LOAD_GROUP)
628#define LOAD_GROUP_A(G) ecp_group_load(grp, \
629 G ## _p, sizeof(G ## _p), \
630 G ## _a, sizeof(G ## _a), \
631 G ## _b, sizeof(G ## _b), \
632 G ## _gx, sizeof(G ## _gx), \
633 G ## _gy, sizeof(G ## _gy), \
634 G ## _n, sizeof(G ## _n))
635
636#define LOAD_GROUP(G) ecp_group_load(grp, \
637 G ## _p, sizeof(G ## _p), \
638 NULL, 0, \
639 G ## _b, sizeof(G ## _b), \
640 G ## _gx, sizeof(G ## _gx), \
641 G ## _gy, sizeof(G ## _gy), \
642 G ## _n, sizeof(G ## _n))
643#endif /* ECP_LOAD_GROUP */
644
645#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
646/* Constants used by ecp_use_curve25519() */
647static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
648static const unsigned char curve25519_part_of_n[] = {
649 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
650 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
651};
652
653/*
654 * Specialized function for creating the Curve25519 group
655 */
656static int ecp_use_curve25519(mbedtls_ecp_group *grp)
657{
658 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
659
660 /* Actually ( A + 2 ) / 4 */
661 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24));
662
663 /* P = 2^255 - 19 */
664 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
665 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 255));
666 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 19));
667 grp->pbits = mbedtls_mpi_bitlen(&grp->P);
668
669 /* N = 2^252 + 27742317777372353535851937790883648493 */
670 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&grp->N,
671 curve25519_part_of_n, sizeof(curve25519_part_of_n)));
672 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 252, 1));
673
674 /* Y intentionally not set, since we use x/z coordinates.
675 * This is used as a marker to identify Montgomery curves! */
676 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 9));
677 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1));
678 mbedtls_mpi_free(&grp->G.Y);
679
680 /* Actually, the required msb for private keys */
681 grp->nbits = 254;
682
683cleanup:
684 if (ret != 0) {
685 mbedtls_ecp_group_free(grp);
686 }
687
688 return ret;
689}
690#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
691
692#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
693/* Constants used by ecp_use_curve448() */
694static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
695static const unsigned char curve448_part_of_n[] = {
696 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
697 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
698 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
699 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
700};
701
702/*
703 * Specialized function for creating the Curve448 group
704 */
705static int ecp_use_curve448(mbedtls_ecp_group *grp)
706{
707 mbedtls_mpi Ns;
708 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
709
710 mbedtls_mpi_init(&Ns);
711
712 /* Actually ( A + 2 ) / 4 */
713 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24));
714
715 /* P = 2^448 - 2^224 - 1 */
716 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
717 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
718 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
719 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
720 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
721 grp->pbits = mbedtls_mpi_bitlen(&grp->P);
722
723 /* Y intentionally not set, since we use x/z coordinates.
724 * This is used as a marker to identify Montgomery curves! */
725 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 5));
726 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1));
727 mbedtls_mpi_free(&grp->G.Y);
728
729 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
730 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 446, 1));
731 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&Ns,
732 curve448_part_of_n, sizeof(curve448_part_of_n)));
733 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&grp->N, &grp->N, &Ns));
734
735 /* Actually, the required msb for private keys */
736 grp->nbits = 447;
737
738cleanup:
739 mbedtls_mpi_free(&Ns);
740 if (ret != 0) {
741 mbedtls_ecp_group_free(grp);
742 }
743
744 return ret;
745}
746#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
747
748/*
749 * Set a group using well-known domain parameters
750 */
751int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
752{
753 ECP_VALIDATE_RET(grp != NULL);
754 mbedtls_ecp_group_free(grp);
755
756 mbedtls_ecp_group_init(grp);
757
758 grp->id = id;
759
760 switch (id) {
761#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
762 case MBEDTLS_ECP_DP_SECP192R1:
763 NIST_MODP(p192);
764 return LOAD_GROUP(secp192r1);
765#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
766
767#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
768 case MBEDTLS_ECP_DP_SECP224R1:
769 NIST_MODP(p224);
770 return LOAD_GROUP(secp224r1);
771#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
772
773#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
774 case MBEDTLS_ECP_DP_SECP256R1:
775 NIST_MODP(p256);
776 return LOAD_GROUP(secp256r1);
777#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
778
779#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
780 case MBEDTLS_ECP_DP_SECP384R1:
781 NIST_MODP(p384);
782 return LOAD_GROUP(secp384r1);
783#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
784
785#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
786 case MBEDTLS_ECP_DP_SECP521R1:
787 NIST_MODP(p521);
788 return LOAD_GROUP(secp521r1);
789#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
790
791#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
792 case MBEDTLS_ECP_DP_SECP192K1:
793 grp->modp = ecp_mod_p192k1;
794 return LOAD_GROUP_A(secp192k1);
795#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
796
797#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
798 case MBEDTLS_ECP_DP_SECP224K1:
799 grp->modp = ecp_mod_p224k1;
800 return LOAD_GROUP_A(secp224k1);
801#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
802
803#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
804 case MBEDTLS_ECP_DP_SECP256K1:
805 grp->modp = ecp_mod_p256k1;
806 return LOAD_GROUP_A(secp256k1);
807#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
808
809#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
810 case MBEDTLS_ECP_DP_BP256R1:
811 return LOAD_GROUP_A(brainpoolP256r1);
812#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
813
814#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
815 case MBEDTLS_ECP_DP_BP384R1:
816 return LOAD_GROUP_A(brainpoolP384r1);
817#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
818
819#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
820 case MBEDTLS_ECP_DP_BP512R1:
821 return LOAD_GROUP_A(brainpoolP512r1);
822#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
823
824#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
825 case MBEDTLS_ECP_DP_CURVE25519:
826 grp->modp = ecp_mod_p255;
827 return ecp_use_curve25519(grp);
828#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
829
830#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
831 case MBEDTLS_ECP_DP_CURVE448:
832 grp->modp = ecp_mod_p448;
833 return ecp_use_curve448(grp);
834#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
835
836 default:
837 grp->id = MBEDTLS_ECP_DP_NONE;
838 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
839 }
840}
841
842#if defined(MBEDTLS_ECP_NIST_OPTIM)
843/*
844 * Fast reduction modulo the primes used by the NIST curves.
845 *
846 * These functions are critical for speed, but not needed for correct
847 * operations. So, we make the choice to heavily rely on the internals of our
848 * bignum library, which creates a tight coupling between these functions and
849 * our MPI implementation. However, the coupling between the ECP module and
850 * MPI remains loose, since these functions can be deactivated at will.
851 */
852
853#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
854/*
855 * Compared to the way things are presented in FIPS 186-3 D.2,
856 * we proceed in columns, from right (least significant chunk) to left,
857 * adding chunks to N in place, and keeping a carry for the next chunk.
858 * This avoids moving things around in memory, and uselessly adding zeros,
859 * compared to the more straightforward, line-oriented approach.
860 *
861 * For this prime we need to handle data in chunks of 64 bits.
862 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
863 * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it.
864 */
865
866/* Add 64-bit chunks (dst += src) and update carry */
867static inline void add64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry)
868{
869 unsigned char i;
870 mbedtls_mpi_uint c = 0;
871 for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++, src++) {
872 *dst += c; c = (*dst < c);
873 *dst += *src; c += (*dst < *src);
874 }
875 *carry += c;
876}
877
878/* Add carry to a 64-bit chunk and update carry */
879static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry)
880{
881 unsigned char i;
882 for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) {
883 *dst += *carry;
884 *carry = (*dst < *carry);
885 }
886}
887
888#define WIDTH 8 / sizeof(mbedtls_mpi_uint)
889#define A(i) N->p + (i) * WIDTH
890#define ADD(i) add64(p, A(i), &c)
891#define NEXT p += WIDTH; carry64(p, &c)
892#define LAST p += WIDTH; *p = c; while (++p < end) *p = 0
893
894/*
895 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
896 */
897static int ecp_mod_p192(mbedtls_mpi *N)
898{
899 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
900 mbedtls_mpi_uint c = 0;
901 mbedtls_mpi_uint *p, *end;
902
903 /* Make sure we have enough blocks so that A(5) is legal */
904 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, 6 * WIDTH));
905
906 p = N->p;
907 end = p + N->n;
908
909 ADD(3); ADD(5); NEXT; // A0 += A3 + A5
910 ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5
911 ADD(4); ADD(5); LAST; // A2 += A4 + A5
912
913cleanup:
914 return ret;
915}
916
917#undef WIDTH
918#undef A
919#undef ADD
920#undef NEXT
921#undef LAST
922#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
923
924#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
925 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
926 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
927/*
928 * The reader is advised to first understand ecp_mod_p192() since the same
929 * general structure is used here, but with additional complications:
930 * (1) chunks of 32 bits, and (2) subtractions.
931 */
932
933/*
934 * For these primes, we need to handle data in chunks of 32 bits.
935 * This makes it more complicated if we use 64 bits limbs in MPI,
936 * which prevents us from using a uniform access method as for p192.
937 *
938 * So, we define a mini abstraction layer to access 32 bit chunks,
939 * load them in 'cur' for work, and store them back from 'cur' when done.
940 *
941 * While at it, also define the size of N in terms of 32-bit chunks.
942 */
943#define LOAD32 cur = A(i);
944
945#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
946
947#define MAX32 N->n
948#define A(j) N->p[j]
949#define STORE32 N->p[i] = cur;
950
951#else /* 64-bit */
952
953#define MAX32 N->n * 2
954#define A(j) (j) % 2 ? (uint32_t) (N->p[(j)/2] >> 32) : \
955 (uint32_t) (N->p[(j)/2])
956#define STORE32 \
957 if (i % 2) { \
958 N->p[i/2] &= 0x00000000FFFFFFFF; \
959 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
960 } else { \
961 N->p[i/2] &= 0xFFFFFFFF00000000; \
962 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
963 }
964
965#endif /* sizeof( mbedtls_mpi_uint ) */
966
967/*
968 * Helpers for addition and subtraction of chunks, with signed carry.
969 */
970static inline void add32(uint32_t *dst, uint32_t src, signed char *carry)
971{
972 *dst += src;
973 *carry += (*dst < src);
974}
975
976static inline void sub32(uint32_t *dst, uint32_t src, signed char *carry)
977{
978 *carry -= (*dst < src);
979 *dst -= src;
980}
981
982#define ADD(j) add32(&cur, A(j), &c);
983#define SUB(j) sub32(&cur, A(j), &c);
984
985#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
986#define biL (ciL << 3) /* bits in limb */
987
988/*
989 * Helpers for the main 'loop'
990 */
991#define INIT(b) \
992 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
993 signed char c = 0, cc; \
994 uint32_t cur; \
995 size_t i = 0, bits = (b); \
996 /* N is the size of the product of two b-bit numbers, plus one */ \
997 /* limb for fix_negative */ \
998 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, (b) * 2 / biL + 1)); \
999 LOAD32;
1000
1001#define NEXT \
1002 STORE32; i++; LOAD32; \
1003 cc = c; c = 0; \
1004 if (cc < 0) \
1005 sub32(&cur, -cc, &c); \
1006 else \
1007 add32(&cur, cc, &c); \
1008
1009#define LAST \
1010 STORE32; i++; \
1011 cur = c > 0 ? c : 0; STORE32; \
1012 cur = 0; while (++i < MAX32) { STORE32; } \
1013 if (c < 0) mbedtls_ecp_fix_negative(N, c, bits);
1014
1015/*
1016 * If the result is negative, we get it in the form
1017 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
1018 */
1019MBEDTLS_STATIC_TESTABLE
1020void mbedtls_ecp_fix_negative(mbedtls_mpi *N, signed char c, size_t bits)
1021{
1022 size_t i;
1023
1024 /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
1025 * set the absolute value to 0xfff...fff - N. There is no carry
1026 * since we're subtracting from all-bits-one. */
1027 for (i = 0; i <= bits / 8 / sizeof(mbedtls_mpi_uint); i++) {
1028 N->p[i] = ~(mbedtls_mpi_uint) 0 - N->p[i];
1029 }
1030 /* Add 1, taking care of the carry. */
1031 i = 0;
1032 do {
1033 ++N->p[i];
1034 } while (N->p[i++] == 0 && i <= bits / 8 / sizeof(mbedtls_mpi_uint));
1035 /* Invert the sign.
1036 * Now N = N0 - 2^bits where N0 is the initial value of N. */
1037 N->s = -1;
1038
1039 /* Add |c| * 2^bits to the absolute value. Since c and N are
1040 * negative, this adds c * 2^bits. */
1041 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1042#if defined(MBEDTLS_HAVE_INT64)
1043 if (bits == 224) {
1044 msw <<= 32;
1045 }
1046#endif
1047 N->p[bits / 8 / sizeof(mbedtls_mpi_uint)] += msw;
1048}
1049
1050#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
1051/*
1052 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1053 */
1054static int ecp_mod_p224(mbedtls_mpi *N)
1055{
1056 INIT(224);
1057
1058 SUB(7); SUB(11); NEXT; // A0 += -A7 - A11
1059 SUB(8); SUB(12); NEXT; // A1 += -A8 - A12
1060 SUB(9); SUB(13); NEXT; // A2 += -A9 - A13
1061 SUB(10); ADD(7); ADD(11); NEXT; // A3 += -A10 + A7 + A11
1062 SUB(11); ADD(8); ADD(12); NEXT; // A4 += -A11 + A8 + A12
1063 SUB(12); ADD(9); ADD(13); NEXT; // A5 += -A12 + A9 + A13
1064 SUB(13); ADD(10); LAST; // A6 += -A13 + A10
1065
1066cleanup:
1067 return ret;
1068}
1069#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
1070
1071#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
1072/*
1073 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1074 */
1075static int ecp_mod_p256(mbedtls_mpi *N)
1076{
1077 INIT(256);
1078
1079 ADD(8); ADD(9);
1080 SUB(11); SUB(12); SUB(13); SUB(14); NEXT; // A0
1081
1082 ADD(9); ADD(10);
1083 SUB(12); SUB(13); SUB(14); SUB(15); NEXT; // A1
1084
1085 ADD(10); ADD(11);
1086 SUB(13); SUB(14); SUB(15); NEXT; // A2
1087
1088 ADD(11); ADD(11); ADD(12); ADD(12); ADD(13);
1089 SUB(15); SUB(8); SUB(9); NEXT; // A3
1090
1091 ADD(12); ADD(12); ADD(13); ADD(13); ADD(14);
1092 SUB(9); SUB(10); NEXT; // A4
1093
1094 ADD(13); ADD(13); ADD(14); ADD(14); ADD(15);
1095 SUB(10); SUB(11); NEXT; // A5
1096
1097 ADD(14); ADD(14); ADD(15); ADD(15); ADD(14); ADD(13);
1098 SUB(8); SUB(9); NEXT; // A6
1099
1100 ADD(15); ADD(15); ADD(15); ADD(8);
1101 SUB(10); SUB(11); SUB(12); SUB(13); LAST; // A7
1102
1103cleanup:
1104 return ret;
1105}
1106#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
1107
1108#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
1109/*
1110 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1111 */
1112static int ecp_mod_p384(mbedtls_mpi *N)
1113{
1114 INIT(384);
1115
1116 ADD(12); ADD(21); ADD(20);
1117 SUB(23); NEXT; // A0
1118
1119 ADD(13); ADD(22); ADD(23);
1120 SUB(12); SUB(20); NEXT; // A2
1121
1122 ADD(14); ADD(23);
1123 SUB(13); SUB(21); NEXT; // A2
1124
1125 ADD(15); ADD(12); ADD(20); ADD(21);
1126 SUB(14); SUB(22); SUB(23); NEXT; // A3
1127
1128 ADD(21); ADD(21); ADD(16); ADD(13); ADD(12); ADD(20); ADD(22);
1129 SUB(15); SUB(23); SUB(23); NEXT; // A4
1130
1131 ADD(22); ADD(22); ADD(17); ADD(14); ADD(13); ADD(21); ADD(23);
1132 SUB(16); NEXT; // A5
1133
1134 ADD(23); ADD(23); ADD(18); ADD(15); ADD(14); ADD(22);
1135 SUB(17); NEXT; // A6
1136
1137 ADD(19); ADD(16); ADD(15); ADD(23);
1138 SUB(18); NEXT; // A7
1139
1140 ADD(20); ADD(17); ADD(16);
1141 SUB(19); NEXT; // A8
1142
1143 ADD(21); ADD(18); ADD(17);
1144 SUB(20); NEXT; // A9
1145
1146 ADD(22); ADD(19); ADD(18);
1147 SUB(21); NEXT; // A10
1148
1149 ADD(23); ADD(20); ADD(19);
1150 SUB(22); LAST; // A11
1151
1152cleanup:
1153 return ret;
1154}
1155#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
1156
1157#undef A
1158#undef LOAD32
1159#undef STORE32
1160#undef MAX32
1161#undef INIT
1162#undef NEXT
1163#undef LAST
1164
1165#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1166 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1167 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
1168
1169#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
1170/*
1171 * Here we have an actual Mersenne prime, so things are more straightforward.
1172 * However, chunks are aligned on a 'weird' boundary (521 bits).
1173 */
1174
1175/* Size of p521 in terms of mbedtls_mpi_uint */
1176#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1)
1177
1178/* Bits to keep in the most significant mbedtls_mpi_uint */
1179#define P521_MASK 0x01FF
1180
1181/*
1182 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1183 * Write N as A1 + 2^521 A0, return A0 + A1
1184 */
1185static int ecp_mod_p521(mbedtls_mpi *N)
1186{
1187 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1188 size_t i;
1189 mbedtls_mpi M;
1190 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1191 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
1192 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1193 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1194
1195 if (N->n < P521_WIDTH) {
1196 return 0;
1197 }
1198
1199 /* M = A1 */
1200 M.s = 1;
1201 M.n = N->n - (P521_WIDTH - 1);
1202 if (M.n > P521_WIDTH + 1) {
1203 M.n = P521_WIDTH + 1;
1204 }
1205 M.p = Mp;
1206 memcpy(Mp, N->p + P521_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint));
1207 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 521 % (8 * sizeof(mbedtls_mpi_uint))));
1208
1209 /* N = A0 */
1210 N->p[P521_WIDTH - 1] &= P521_MASK;
1211 for (i = P521_WIDTH; i < N->n; i++) {
1212 N->p[i] = 0;
1213 }
1214
1215 /* N = A0 + A1 */
1216 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
1217
1218cleanup:
1219 return ret;
1220}
1221
1222#undef P521_WIDTH
1223#undef P521_MASK
1224#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
1225
1226#endif /* MBEDTLS_ECP_NIST_OPTIM */
1227
1228#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
1229
1230/* Size of p255 in terms of mbedtls_mpi_uint */
1231#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1)
1232
1233/*
1234 * Fast quasi-reduction modulo p255 = 2^255 - 19
1235 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
1236 */
1237static int ecp_mod_p255(mbedtls_mpi *N)
1238{
1239 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1240 size_t i;
1241 mbedtls_mpi M;
1242 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
1243
1244 if (N->n < P255_WIDTH) {
1245 return 0;
1246 }
1247
1248 /* M = A1 */
1249 M.s = 1;
1250 M.n = N->n - (P255_WIDTH - 1);
1251 if (M.n > P255_WIDTH + 1) {
1252 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1253 }
1254 M.p = Mp;
1255 memset(Mp, 0, sizeof(Mp));
1256 memcpy(Mp, N->p + P255_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint));
1257 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 255 % (8 * sizeof(mbedtls_mpi_uint))));
1258 M.n++; /* Make room for multiplication by 19 */
1259
1260 /* N = A0 */
1261 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(N, 255, 0));
1262 for (i = P255_WIDTH; i < N->n; i++) {
1263 N->p[i] = 0;
1264 }
1265
1266 /* N = A0 + 19 * A1 */
1267 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&M, &M, 19));
1268 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
1269
1270cleanup:
1271 return ret;
1272}
1273#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
1274
1275#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1276
1277/* Size of p448 in terms of mbedtls_mpi_uint */
1278#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint))
1279
1280/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1281#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y))
1282#define P224_WIDTH_MIN (28 / sizeof(mbedtls_mpi_uint))
1283#define P224_WIDTH_MAX DIV_ROUND_UP(28, sizeof(mbedtls_mpi_uint))
1284#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224)
1285
1286/*
1287 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1288 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1289 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1290 * implementation of Curve448, which uses its own special 56-bit limbs rather
1291 * than a generic bignum library. We could squeeze some extra speed out on
1292 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1293 * arithmetic using the limbs directly as we do for the NIST primes above,
1294 * but for 64-bit targets it should use half the number of operations if we do
1295 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1296 */
1297static int ecp_mod_p448(mbedtls_mpi *N)
1298{
1299 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1300 size_t i;
1301 mbedtls_mpi M, Q;
1302 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1303
1304 if (N->n <= P448_WIDTH) {
1305 return 0;
1306 }
1307
1308 /* M = A1 */
1309 M.s = 1;
1310 M.n = N->n - (P448_WIDTH);
1311 if (M.n > P448_WIDTH) {
1312 /* Shouldn't be called with N larger than 2^896! */
1313 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1314 }
1315 M.p = Mp;
1316 memset(Mp, 0, sizeof(Mp));
1317 memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint));
1318
1319 /* N = A0 */
1320 for (i = P448_WIDTH; i < N->n; i++) {
1321 N->p[i] = 0;
1322 }
1323
1324 /* N += A1 */
1325 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
1326
1327 /* Q = B1, N += B1 */
1328 Q = M;
1329 Q.p = Qp;
1330 memcpy(Qp, Mp, sizeof(Qp));
1331 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Q, 224));
1332 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &Q));
1333
1334 /* M = (B0 + B1) * 2^224, N += M */
1335 if (sizeof(mbedtls_mpi_uint) > 4) {
1336 Mp[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
1337 }
1338 for (i = P224_WIDTH_MAX; i < M.n; ++i) {
1339 Mp[i] = 0;
1340 }
1341 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q));
1342 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1343 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224));
1344 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
1345
1346cleanup:
1347 return ret;
1348}
1349#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1350
1351#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1352 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1353 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1354/*
1355 * Fast quasi-reduction modulo P = 2^s - R,
1356 * with R about 33 bits, used by the Koblitz curves.
1357 *
1358 * Write N as A0 + 2^224 A1, return A0 + R * A1.
1359 * Actually do two passes, since R is big.
1360 */
1361#define P_KOBLITZ_MAX (256 / 8 / sizeof(mbedtls_mpi_uint)) // Max limbs in P
1362#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R
1363static inline int ecp_mod_koblitz(mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1364 size_t adjust, size_t shift, mbedtls_mpi_uint mask)
1365{
1366 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1367 size_t i;
1368 mbedtls_mpi M, R;
1369 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
1370
1371 if (N->n < p_limbs) {
1372 return 0;
1373 }
1374
1375 /* Init R */
1376 R.s = 1;
1377 R.p = Rp;
1378 R.n = P_KOBLITZ_R;
1379
1380 /* Common setup for M */
1381 M.s = 1;
1382 M.p = Mp;
1383
1384 /* M = A1 */
1385 M.n = N->n - (p_limbs - adjust);
1386 if (M.n > p_limbs + adjust) {
1387 M.n = p_limbs + adjust;
1388 }
1389 memset(Mp, 0, sizeof(Mp));
1390 memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
1391 if (shift != 0) {
1392 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
1393 }
1394 M.n += R.n; /* Make room for multiplication by R */
1395
1396 /* N = A0 */
1397 if (mask != 0) {
1398 N->p[p_limbs - 1] &= mask;
1399 }
1400 for (i = p_limbs; i < N->n; i++) {
1401 N->p[i] = 0;
1402 }
1403
1404 /* N = A0 + R * A1 */
1405 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
1406 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
1407
1408 /* Second pass */
1409
1410 /* M = A1 */
1411 M.n = N->n - (p_limbs - adjust);
1412 if (M.n > p_limbs + adjust) {
1413 M.n = p_limbs + adjust;
1414 }
1415 memset(Mp, 0, sizeof(Mp));
1416 memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
1417 if (shift != 0) {
1418 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
1419 }
1420 M.n += R.n; /* Make room for multiplication by R */
1421
1422 /* N = A0 */
1423 if (mask != 0) {
1424 N->p[p_limbs - 1] &= mask;
1425 }
1426 for (i = p_limbs; i < N->n; i++) {
1427 N->p[i] = 0;
1428 }
1429
1430 /* N = A0 + R * A1 */
1431 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
1432 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
1433
1434cleanup:
1435 return ret;
1436}
1437#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1438 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1439 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
1440
1441#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
1442/*
1443 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1444 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1445 */
1446static int ecp_mod_p192k1(mbedtls_mpi *N)
1447{
1448 static mbedtls_mpi_uint Rp[] = {
1449 MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
1450 0x00)
1451 };
1452
1453 return ecp_mod_koblitz(N, Rp, 192 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1454 0);
1455}
1456#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
1457
1458#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
1459/*
1460 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1461 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1462 */
1463static int ecp_mod_p224k1(mbedtls_mpi *N)
1464{
1465 static mbedtls_mpi_uint Rp[] = {
1466 MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
1467 0x00)
1468 };
1469
1470#if defined(MBEDTLS_HAVE_INT64)
1471 return ecp_mod_koblitz(N, Rp, 4, 1, 32, 0xFFFFFFFF);
1472#else
1473 return ecp_mod_koblitz(N, Rp, 224 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1474 0);
1475#endif
1476}
1477
1478#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
1479
1480#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1481/*
1482 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1483 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1484 */
1485static int ecp_mod_p256k1(mbedtls_mpi *N)
1486{
1487 static mbedtls_mpi_uint Rp[] = {
1488 MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
1489 0x00)
1490 };
1491 return ecp_mod_koblitz(N, Rp, 256 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1492 0);
1493}
1494#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
1495
1496#endif /* !MBEDTLS_ECP_ALT */
1497
1498#endif /* MBEDTLS_ECP_C */
1499