blob: ff26a18e8fc1278507378f87bad00e5816b40fa1 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * Elliptic curves over GF(p): curve-specific data and functions
3 *
Jerome Forissier3602df82021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
19
Jerome Forissier3602df82021-07-28 10:24:04 +020020#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020021
22#if defined(MBEDTLS_ECP_C)
23
24#include "mbedtls/ecp.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010025#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020026#include "mbedtls/error.h"
Jerome Forissier3602df82021-07-28 10:24:04 +020027#include "mbedtls/bn_mul.h"
28
29#include "ecp_invasive.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020030
31#include <string.h>
32
33#if !defined(MBEDTLS_ECP_ALT)
34
Jens Wiklander3d3b0592019-03-20 15:30:29 +010035/* 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
Jens Wiklander817466c2018-05-22 13:49:31 +020041#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
42 !defined(inline) && !defined(__cplusplus)
43#define inline __inline
44#endif
45
Jerome Forissier3602df82021-07-28 10:24:04 +020046#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
Jens Wiklander817466c2018-05-22 13:49:31 +020047
Jerome Forissier3602df82021-07-28 10:24:04 +020048#define ECP_MPI_INIT_ARRAY(x) \
49 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
Jens Wiklander817466c2018-05-22 13:49:31 +020050
51/*
52 * Note: the constants are in little-endian order
53 * to be directly usable in MPIs
54 */
55
56/*
57 * Domain parameters for secp192r1
58 */
59#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
60static const mbedtls_mpi_uint secp192r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +020061 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
62 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
63 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +020064};
65static const mbedtls_mpi_uint secp192r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +020066 MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
67 MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
68 MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
Jens Wiklander817466c2018-05-22 13:49:31 +020069};
70static const mbedtls_mpi_uint secp192r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +020071 MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
72 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
73 MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
Jens Wiklander817466c2018-05-22 13:49:31 +020074};
75static const mbedtls_mpi_uint secp192r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +020076 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
77 MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
78 MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
Jens Wiklander817466c2018-05-22 13:49:31 +020079};
80static const mbedtls_mpi_uint secp192r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +020081 MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
82 MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
83 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +020084};
85#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
86
87/*
88 * Domain parameters for secp224r1
89 */
90#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
91static const mbedtls_mpi_uint secp224r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +020092 MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
93 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
94 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
95 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +020096};
97static const mbedtls_mpi_uint secp224r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +020098 MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
99 MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
100 MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
101 MBEDTLS_BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200102};
103static const mbedtls_mpi_uint secp224r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200104 MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
105 MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
106 MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
107 MBEDTLS_BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200108};
109static const mbedtls_mpi_uint secp224r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200110 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
111 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
112 MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
113 MBEDTLS_BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200114};
115static const mbedtls_mpi_uint secp224r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200116 MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
117 MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
118 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
119 MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200120};
121#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
122
123/*
124 * Domain parameters for secp256r1
125 */
126#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
127static const mbedtls_mpi_uint secp256r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200128 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
129 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
130 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
131 MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200132};
133static const mbedtls_mpi_uint secp256r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200134 MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
135 MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
136 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
137 MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200138};
139static const mbedtls_mpi_uint secp256r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200140 MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
141 MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
142 MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
143 MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200144};
145static const mbedtls_mpi_uint secp256r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200146 MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
147 MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
148 MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
149 MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200150};
151static const mbedtls_mpi_uint secp256r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200152 MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
153 MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
154 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
155 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200156};
157#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
158
159/*
160 * Domain parameters for secp384r1
161 */
162#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
163static const mbedtls_mpi_uint secp384r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200164 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
165 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
166 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
167 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
168 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
169 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200170};
171static const mbedtls_mpi_uint secp384r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200172 MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
173 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
174 MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
175 MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
176 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
177 MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200178};
179static const mbedtls_mpi_uint secp384r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200180 MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
181 MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
182 MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
183 MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
184 MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
185 MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200186};
187static const mbedtls_mpi_uint secp384r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200188 MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
189 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
190 MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
191 MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
192 MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
193 MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200194};
195static const mbedtls_mpi_uint secp384r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200196 MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
197 MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
198 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
199 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
200 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
201 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200202};
203#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
204
205/*
206 * Domain parameters for secp521r1
207 */
208#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
209static const mbedtls_mpi_uint secp521r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200210 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_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
214 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
215 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
216 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
217 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
218 MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200219};
220static const mbedtls_mpi_uint secp521r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200221 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
222 MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
223 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
224 MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
225 MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
226 MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
227 MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
228 MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
229 MBEDTLS_BYTES_TO_T_UINT_2( 0x51, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200230};
231static const mbedtls_mpi_uint secp521r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200232 MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
233 MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
234 MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
235 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
236 MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
237 MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
238 MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
239 MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
240 MBEDTLS_BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200241};
242static const mbedtls_mpi_uint secp521r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200243 MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
244 MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
245 MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
246 MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
247 MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
248 MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
249 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
250 MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
251 MBEDTLS_BYTES_TO_T_UINT_2( 0x18, 0x01 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200252};
253static const mbedtls_mpi_uint secp521r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200254 MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
255 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
256 MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
257 MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
258 MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
259 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
260 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
261 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
262 MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200263};
264#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
265
266#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
267static const mbedtls_mpi_uint secp192k1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200268 MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
269 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
270 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200271};
272static const mbedtls_mpi_uint secp192k1_a[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200273 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200274};
275static const mbedtls_mpi_uint secp192k1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200276 MBEDTLS_BYTES_TO_T_UINT_2( 0x03, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200277};
278static const mbedtls_mpi_uint secp192k1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200279 MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
280 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
281 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200282};
283static const mbedtls_mpi_uint secp192k1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200284 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
285 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
286 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200287};
288static const mbedtls_mpi_uint secp192k1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200289 MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
290 MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
291 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200292};
293#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
294
295#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
296static const mbedtls_mpi_uint secp224k1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200297 MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
298 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
299 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
300 MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200301};
302static const mbedtls_mpi_uint secp224k1_a[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200303 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200304};
305static const mbedtls_mpi_uint secp224k1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200306 MBEDTLS_BYTES_TO_T_UINT_2( 0x05, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200307};
308static const mbedtls_mpi_uint secp224k1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200309 MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
310 MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
311 MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
312 MBEDTLS_BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200313};
314static const mbedtls_mpi_uint secp224k1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200315 MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
316 MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
317 MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
318 MBEDTLS_BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200319};
320static const mbedtls_mpi_uint secp224k1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200321 MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
322 MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
323 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
324 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200325};
326#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
327
328#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
329static const mbedtls_mpi_uint secp256k1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200330 MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
331 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
332 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
333 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200334};
335static const mbedtls_mpi_uint secp256k1_a[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200336 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200337};
338static const mbedtls_mpi_uint secp256k1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200339 MBEDTLS_BYTES_TO_T_UINT_2( 0x07, 0x00 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200340};
341static const mbedtls_mpi_uint secp256k1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200342 MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
343 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
344 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
345 MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200346};
347static const mbedtls_mpi_uint secp256k1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200348 MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
349 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
350 MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
351 MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200352};
353static const mbedtls_mpi_uint secp256k1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200354 MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
355 MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
356 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
357 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200358};
359#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
360
361/*
362 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
363 */
364#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
365static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200366 MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
367 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
368 MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
369 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200370};
371static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200372 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
373 MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
374 MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
375 MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200376};
377static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200378 MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
379 MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
380 MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
381 MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200382};
383static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200384 MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
385 MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
386 MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
387 MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200388};
389static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200390 MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
391 MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
392 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
393 MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200394};
395static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200396 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
397 MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
398 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
399 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200400};
401#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
402
403/*
404 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
405 */
406#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
407static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200408 MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
409 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
410 MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
411 MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
412 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
413 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200414};
415static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200416 MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
417 MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
418 MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
419 MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
420 MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
421 MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200422};
423static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200424 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
425 MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
426 MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
427 MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
428 MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
429 MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200430};
431static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200432 MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
433 MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
434 MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
435 MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
436 MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
437 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200438};
439static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200440 MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
441 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
442 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
443 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
444 MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
445 MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200446};
447static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200448 MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
449 MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
450 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
451 MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
452 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
453 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200454};
455#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
456
457/*
458 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
459 */
460#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
461static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200462 MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
463 MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
464 MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
465 MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
466 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
467 MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
468 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
469 MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200470};
471static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200472 MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
473 MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
474 MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
475 MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
476 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
477 MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
478 MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
479 MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200480};
481static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200482 MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
483 MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
484 MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
485 MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
486 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
487 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
488 MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
489 MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200490};
491static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200492 MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
493 MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
494 MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
495 MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
496 MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
497 MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
498 MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
499 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200500};
501static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200502 MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
503 MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
504 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
505 MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
506 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
507 MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
508 MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
509 MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200510};
511static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +0200512 MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
513 MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
514 MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
515 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
516 MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
517 MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
518 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
519 MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Jens Wiklander817466c2018-05-22 13:49:31 +0200520};
521#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
522
Jerome Forissier3602df82021-07-28 10:24:04 +0200523#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
524 defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
525 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
526 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
527 defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
528 defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
529 defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
530 defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
531 defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
532 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
533 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
534/* For these curves, we build the group parameters dynamically. */
535#define ECP_LOAD_GROUP
536#endif
537
538#if defined(ECP_LOAD_GROUP)
Jerome Forissier9fc24422021-01-22 16:30:41 +0100539/*
Jens Wiklander817466c2018-05-22 13:49:31 +0200540 * Create an MPI from embedded constants
541 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
542 */
543static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len )
544{
545 X->s = 1;
546 X->n = len / sizeof( mbedtls_mpi_uint );
547 X->p = (mbedtls_mpi_uint *) p;
548}
549
550/*
551 * Set an MPI to static value 1
552 */
553static inline void ecp_mpi_set1( mbedtls_mpi *X )
554{
555 static mbedtls_mpi_uint one[] = { 1 };
556 X->s = 1;
557 X->n = 1;
558 X->p = one;
559}
560
561/*
562 * Make group available from embedded constants
563 */
564static int ecp_group_load( mbedtls_ecp_group *grp,
565 const mbedtls_mpi_uint *p, size_t plen,
566 const mbedtls_mpi_uint *a, size_t alen,
567 const mbedtls_mpi_uint *b, size_t blen,
568 const mbedtls_mpi_uint *gx, size_t gxlen,
569 const mbedtls_mpi_uint *gy, size_t gylen,
570 const mbedtls_mpi_uint *n, size_t nlen)
571{
572 ecp_mpi_load( &grp->P, p, plen );
573 if( a != NULL )
574 ecp_mpi_load( &grp->A, a, alen );
575 ecp_mpi_load( &grp->B, b, blen );
576 ecp_mpi_load( &grp->N, n, nlen );
577
578 ecp_mpi_load( &grp->G.X, gx, gxlen );
579 ecp_mpi_load( &grp->G.Y, gy, gylen );
580 ecp_mpi_set1( &grp->G.Z );
581
582 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
583 grp->nbits = mbedtls_mpi_bitlen( &grp->N );
584
585 grp->h = 1;
586
587 return( 0 );
588}
Jerome Forissier3602df82021-07-28 10:24:04 +0200589#endif /* ECP_LOAD_GROUP */
Jens Wiklander817466c2018-05-22 13:49:31 +0200590
591#if defined(MBEDTLS_ECP_NIST_OPTIM)
592/* Forward declarations */
593#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
594static int ecp_mod_p192( mbedtls_mpi * );
595#endif
596#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
597static int ecp_mod_p224( mbedtls_mpi * );
598#endif
599#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
600static int ecp_mod_p256( mbedtls_mpi * );
601#endif
602#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
603static int ecp_mod_p384( mbedtls_mpi * );
604#endif
605#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
606static int ecp_mod_p521( mbedtls_mpi * );
607#endif
608
609#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
610#else
611#define NIST_MODP( P )
612#endif /* MBEDTLS_ECP_NIST_OPTIM */
613
614/* Additional forward declarations */
615#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
616static int ecp_mod_p255( mbedtls_mpi * );
617#endif
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100618#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
619static int ecp_mod_p448( mbedtls_mpi * );
620#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200621#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
622static int ecp_mod_p192k1( mbedtls_mpi * );
623#endif
624#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
625static int ecp_mod_p224k1( mbedtls_mpi * );
626#endif
627#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
628static int ecp_mod_p256k1( mbedtls_mpi * );
629#endif
630
Jerome Forissier3602df82021-07-28 10:24:04 +0200631#if defined(ECP_LOAD_GROUP)
Jens Wiklander817466c2018-05-22 13:49:31 +0200632#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
633 G ## _p, sizeof( G ## _p ), \
634 G ## _a, sizeof( G ## _a ), \
635 G ## _b, sizeof( G ## _b ), \
636 G ## _gx, sizeof( G ## _gx ), \
637 G ## _gy, sizeof( G ## _gy ), \
638 G ## _n, sizeof( G ## _n ) )
639
640#define LOAD_GROUP( G ) ecp_group_load( grp, \
641 G ## _p, sizeof( G ## _p ), \
642 NULL, 0, \
643 G ## _b, sizeof( G ## _b ), \
644 G ## _gx, sizeof( G ## _gx ), \
645 G ## _gy, sizeof( G ## _gy ), \
646 G ## _n, sizeof( G ## _n ) )
Jerome Forissier3602df82021-07-28 10:24:04 +0200647#endif /* ECP_LOAD_GROUP */
Jens Wiklander817466c2018-05-22 13:49:31 +0200648
649#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Jerome Forissier3602df82021-07-28 10:24:04 +0200650/* Constants used by ecp_use_curve25519() */
651static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
652static const unsigned char curve25519_part_of_n[] = {
653 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
654 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
655};
656
Jens Wiklander817466c2018-05-22 13:49:31 +0200657/*
658 * Specialized function for creating the Curve25519 group
659 */
660static int ecp_use_curve25519( mbedtls_ecp_group *grp )
661{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200662 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200663
664 /* Actually ( A + 2 ) / 4 */
Jerome Forissier3602df82021-07-28 10:24:04 +0200665 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200666
667 /* P = 2^255 - 19 */
668 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
669 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
670 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
671 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
672
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100673 /* N = 2^252 + 27742317777372353535851937790883648493 */
Jerome Forissier3602df82021-07-28 10:24:04 +0200674 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
675 curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100676 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
677
678 /* Y intentionally not set, since we use x/z coordinates.
Jens Wiklander817466c2018-05-22 13:49:31 +0200679 * This is used as a marker to identify Montgomery curves! */
680 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
681 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
682 mbedtls_mpi_free( &grp->G.Y );
683
684 /* Actually, the required msb for private keys */
685 grp->nbits = 254;
686
687cleanup:
688 if( ret != 0 )
689 mbedtls_ecp_group_free( grp );
690
691 return( ret );
692}
693#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
694
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100695#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Jerome Forissier3602df82021-07-28 10:24:04 +0200696/* Constants used by ecp_use_curve448() */
697static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
698static const unsigned char curve448_part_of_n[] = {
699 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
700 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
701 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
702 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
703};
704
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100705/*
706 * Specialized function for creating the Curve448 group
707 */
708static int ecp_use_curve448( mbedtls_ecp_group *grp )
709{
710 mbedtls_mpi Ns;
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200711 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100712
713 mbedtls_mpi_init( &Ns );
714
715 /* Actually ( A + 2 ) / 4 */
Jerome Forissier3602df82021-07-28 10:24:04 +0200716 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve448_a24 ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100717
718 /* P = 2^448 - 2^224 - 1 */
719 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
720 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
721 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
722 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
723 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
724 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
725
726 /* Y intentionally not set, since we use x/z coordinates.
727 * This is used as a marker to identify Montgomery curves! */
728 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
729 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
730 mbedtls_mpi_free( &grp->G.Y );
731
732 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
733 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Jerome Forissier3602df82021-07-28 10:24:04 +0200734 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
735 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100736 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
737
738 /* Actually, the required msb for private keys */
739 grp->nbits = 447;
740
741cleanup:
742 mbedtls_mpi_free( &Ns );
743 if( ret != 0 )
744 mbedtls_ecp_group_free( grp );
745
746 return( ret );
747}
748#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
749
Jens Wiklander817466c2018-05-22 13:49:31 +0200750/*
751 * Set a group using well-known domain parameters
752 */
753int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
754{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100755 ECP_VALIDATE_RET( grp != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200756 mbedtls_ecp_group_free( grp );
757
758 grp->id = id;
759
760 switch( id )
761 {
762#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
763 case MBEDTLS_ECP_DP_SECP192R1:
764 NIST_MODP( p192 );
765 return( LOAD_GROUP( secp192r1 ) );
766#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
767
768#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
769 case MBEDTLS_ECP_DP_SECP224R1:
770 NIST_MODP( p224 );
771 return( LOAD_GROUP( secp224r1 ) );
772#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
773
774#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
775 case MBEDTLS_ECP_DP_SECP256R1:
776 NIST_MODP( p256 );
777 return( LOAD_GROUP( secp256r1 ) );
778#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
779
780#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
781 case MBEDTLS_ECP_DP_SECP384R1:
782 NIST_MODP( p384 );
783 return( LOAD_GROUP( secp384r1 ) );
784#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
785
786#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
787 case MBEDTLS_ECP_DP_SECP521R1:
788 NIST_MODP( p521 );
789 return( LOAD_GROUP( secp521r1 ) );
790#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
791
792#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
793 case MBEDTLS_ECP_DP_SECP192K1:
794 grp->modp = ecp_mod_p192k1;
795 return( LOAD_GROUP_A( secp192k1 ) );
796#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
797
798#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
799 case MBEDTLS_ECP_DP_SECP224K1:
800 grp->modp = ecp_mod_p224k1;
801 return( LOAD_GROUP_A( secp224k1 ) );
802#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
803
804#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
805 case MBEDTLS_ECP_DP_SECP256K1:
806 grp->modp = ecp_mod_p256k1;
807 return( LOAD_GROUP_A( secp256k1 ) );
808#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
809
810#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
811 case MBEDTLS_ECP_DP_BP256R1:
812 return( LOAD_GROUP_A( brainpoolP256r1 ) );
813#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
814
815#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
816 case MBEDTLS_ECP_DP_BP384R1:
817 return( LOAD_GROUP_A( brainpoolP384r1 ) );
818#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
819
820#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
821 case MBEDTLS_ECP_DP_BP512R1:
822 return( LOAD_GROUP_A( brainpoolP512r1 ) );
823#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
824
825#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
826 case MBEDTLS_ECP_DP_CURVE25519:
827 grp->modp = ecp_mod_p255;
828 return( ecp_use_curve25519( grp ) );
829#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
830
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100831#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
832 case MBEDTLS_ECP_DP_CURVE448:
833 grp->modp = ecp_mod_p448;
834 return( ecp_use_curve448( grp ) );
835#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
836
Jens Wiklander817466c2018-05-22 13:49:31 +0200837 default:
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200838 grp->id = MBEDTLS_ECP_DP_NONE;
Jens Wiklander817466c2018-05-22 13:49:31 +0200839 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
840 }
841}
842
843#if defined(MBEDTLS_ECP_NIST_OPTIM)
844/*
845 * Fast reduction modulo the primes used by the NIST curves.
846 *
847 * These functions are critical for speed, but not needed for correct
848 * operations. So, we make the choice to heavily rely on the internals of our
849 * bignum library, which creates a tight coupling between these functions and
850 * our MPI implementation. However, the coupling between the ECP module and
851 * MPI remains loose, since these functions can be deactivated at will.
852 */
853
854#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
855/*
856 * Compared to the way things are presented in FIPS 186-3 D.2,
857 * we proceed in columns, from right (least significant chunk) to left,
858 * adding chunks to N in place, and keeping a carry for the next chunk.
859 * This avoids moving things around in memory, and uselessly adding zeros,
860 * compared to the more straightforward, line-oriented approach.
861 *
862 * For this prime we need to handle data in chunks of 64 bits.
863 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
864 * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it.
865 */
866
867/* Add 64-bit chunks (dst += src) and update carry */
868static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
869{
870 unsigned char i;
871 mbedtls_mpi_uint c = 0;
872 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
873 {
874 *dst += c; c = ( *dst < c );
875 *dst += *src; c += ( *dst < *src );
876 }
877 *carry += c;
878}
879
880/* Add carry to a 64-bit chunk and update carry */
881static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
882{
883 unsigned char i;
884 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
885 {
886 *dst += *carry;
887 *carry = ( *dst < *carry );
888 }
889}
890
891#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Jerome Forissier5b25c762020-04-07 11:18:49 +0200892#define A( i ) N->p + (i) * WIDTH
Jens Wiklander817466c2018-05-22 13:49:31 +0200893#define ADD( i ) add64( p, A( i ), &c )
894#define NEXT p += WIDTH; carry64( p, &c )
895#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
896
897/*
898 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
899 */
900static int ecp_mod_p192( mbedtls_mpi *N )
901{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200902 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200903 mbedtls_mpi_uint c = 0;
904 mbedtls_mpi_uint *p, *end;
905
906 /* Make sure we have enough blocks so that A(5) is legal */
907 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
908
909 p = N->p;
910 end = p + N->n;
911
912 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
913 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
914 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
915
916cleanup:
917 return( ret );
918}
919
920#undef WIDTH
921#undef A
922#undef ADD
923#undef NEXT
924#undef LAST
925#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
926
927#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
928 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
929 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
930/*
931 * The reader is advised to first understand ecp_mod_p192() since the same
932 * general structure is used here, but with additional complications:
933 * (1) chunks of 32 bits, and (2) subtractions.
934 */
935
936/*
937 * For these primes, we need to handle data in chunks of 32 bits.
938 * This makes it more complicated if we use 64 bits limbs in MPI,
939 * which prevents us from using a uniform access method as for p192.
940 *
941 * So, we define a mini abstraction layer to access 32 bit chunks,
942 * load them in 'cur' for work, and store them back from 'cur' when done.
943 *
944 * While at it, also define the size of N in terms of 32-bit chunks.
945 */
946#define LOAD32 cur = A( i );
947
948#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
949
950#define MAX32 N->n
951#define A( j ) N->p[j]
952#define STORE32 N->p[i] = cur;
953
954#else /* 64-bit */
955
956#define MAX32 N->n * 2
Jerome Forissier5b25c762020-04-07 11:18:49 +0200957#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
958 (uint32_t)( N->p[(j)/2] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200959#define STORE32 \
960 if( i % 2 ) { \
961 N->p[i/2] &= 0x00000000FFFFFFFF; \
962 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
963 } else { \
964 N->p[i/2] &= 0xFFFFFFFF00000000; \
965 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
966 }
967
968#endif /* sizeof( mbedtls_mpi_uint ) */
969
970/*
971 * Helpers for addition and subtraction of chunks, with signed carry.
972 */
973static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
974{
975 *dst += src;
976 *carry += ( *dst < src );
977}
978
979static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
980{
981 *carry -= ( *dst < src );
982 *dst -= src;
983}
984
985#define ADD( j ) add32( &cur, A( j ), &c );
986#define SUB( j ) sub32( &cur, A( j ), &c );
987
Jerome Forissier3602df82021-07-28 10:24:04 +0200988#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
989#define biL (ciL << 3) /* bits in limb */
990
Jens Wiklander817466c2018-05-22 13:49:31 +0200991/*
992 * Helpers for the main 'loop'
Jens Wiklander817466c2018-05-22 13:49:31 +0200993 */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200994#define INIT( b ) \
Jerome Forissier3602df82021-07-28 10:24:04 +0200995 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
Jerome Forissier5b25c762020-04-07 11:18:49 +0200996 signed char c = 0, cc; \
997 uint32_t cur; \
998 size_t i = 0, bits = (b); \
Jerome Forissier3602df82021-07-28 10:24:04 +0200999 /* N is the size of the product of two b-bit numbers, plus one */ \
1000 /* limb for fix_negative */ \
1001 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, ( b ) * 2 / biL + 1 ) ); \
Jens Wiklander817466c2018-05-22 13:49:31 +02001002 LOAD32;
1003
1004#define NEXT \
1005 STORE32; i++; LOAD32; \
1006 cc = c; c = 0; \
1007 if( cc < 0 ) \
1008 sub32( &cur, -cc, &c ); \
1009 else \
1010 add32( &cur, cc, &c ); \
1011
1012#define LAST \
1013 STORE32; i++; \
1014 cur = c > 0 ? c : 0; STORE32; \
1015 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Jerome Forissier3602df82021-07-28 10:24:04 +02001016 if( c < 0 ) mbedtls_ecp_fix_negative( N, c, bits );
Jens Wiklander817466c2018-05-22 13:49:31 +02001017
1018/*
1019 * If the result is negative, we get it in the form
Jerome Forissier3602df82021-07-28 10:24:04 +02001020 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Jens Wiklander817466c2018-05-22 13:49:31 +02001021 */
Jerome Forissier3602df82021-07-28 10:24:04 +02001022MBEDTLS_STATIC_TESTABLE
1023void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits )
Jens Wiklander817466c2018-05-22 13:49:31 +02001024{
Jerome Forissier3602df82021-07-28 10:24:04 +02001025 size_t i;
Jens Wiklander817466c2018-05-22 13:49:31 +02001026
Jerome Forissier3602df82021-07-28 10:24:04 +02001027 /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
1028 * set the absolute value to 0xfff...fff - N. There is no carry
1029 * since we're subtracting from all-bits-one. */
1030 for( i = 0; i <= bits / 8 / sizeof( mbedtls_mpi_uint ); i++ )
1031 {
1032 N->p[i] = ~(mbedtls_mpi_uint)0 - N->p[i];
1033 }
1034 /* Add 1, taking care of the carry. */
1035 i = 0;
1036 do
1037 ++N->p[i];
1038 while( N->p[i++] == 0 && i <= bits / 8 / sizeof( mbedtls_mpi_uint ) );
1039 /* Invert the sign.
1040 * Now N = N0 - 2^bits where N0 is the initial value of N. */
Jens Wiklander817466c2018-05-22 13:49:31 +02001041 N->s = -1;
1042
Jerome Forissier3602df82021-07-28 10:24:04 +02001043 /* Add |c| * 2^bits to the absolute value. Since c and N are
1044 * negative, this adds c * 2^bits. */
1045 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1046#if defined(MBEDTLS_HAVE_INT64)
1047 if( bits == 224 )
1048 msw <<= 32;
1049#endif
1050 N->p[bits / 8 / sizeof( mbedtls_mpi_uint)] += msw;
Jens Wiklander817466c2018-05-22 13:49:31 +02001051}
1052
1053#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
1054/*
1055 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1056 */
1057static int ecp_mod_p224( mbedtls_mpi *N )
1058{
1059 INIT( 224 );
1060
1061 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1062 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1063 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1064 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1065 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1066 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1067 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1068
1069cleanup:
1070 return( ret );
1071}
1072#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
1073
1074#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
1075/*
1076 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1077 */
1078static int ecp_mod_p256( mbedtls_mpi *N )
1079{
1080 INIT( 256 );
1081
1082 ADD( 8 ); ADD( 9 );
1083 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1084
1085 ADD( 9 ); ADD( 10 );
1086 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1087
1088 ADD( 10 ); ADD( 11 );
1089 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1090
1091 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1092 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1093
1094 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1095 SUB( 9 ); SUB( 10 ); NEXT; // A4
1096
1097 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1098 SUB( 10 ); SUB( 11 ); NEXT; // A5
1099
1100 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1101 SUB( 8 ); SUB( 9 ); NEXT; // A6
1102
1103 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1104 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1105
1106cleanup:
1107 return( ret );
1108}
1109#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
1110
1111#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
1112/*
1113 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1114 */
1115static int ecp_mod_p384( mbedtls_mpi *N )
1116{
1117 INIT( 384 );
1118
1119 ADD( 12 ); ADD( 21 ); ADD( 20 );
1120 SUB( 23 ); NEXT; // A0
1121
1122 ADD( 13 ); ADD( 22 ); ADD( 23 );
1123 SUB( 12 ); SUB( 20 ); NEXT; // A2
1124
1125 ADD( 14 ); ADD( 23 );
1126 SUB( 13 ); SUB( 21 ); NEXT; // A2
1127
1128 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1129 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1130
1131 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1132 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1133
1134 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1135 SUB( 16 ); NEXT; // A5
1136
1137 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1138 SUB( 17 ); NEXT; // A6
1139
1140 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1141 SUB( 18 ); NEXT; // A7
1142
1143 ADD( 20 ); ADD( 17 ); ADD( 16 );
1144 SUB( 19 ); NEXT; // A8
1145
1146 ADD( 21 ); ADD( 18 ); ADD( 17 );
1147 SUB( 20 ); NEXT; // A9
1148
1149 ADD( 22 ); ADD( 19 ); ADD( 18 );
1150 SUB( 21 ); NEXT; // A10
1151
1152 ADD( 23 ); ADD( 20 ); ADD( 19 );
1153 SUB( 22 ); LAST; // A11
1154
1155cleanup:
1156 return( ret );
1157}
1158#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
1159
1160#undef A
1161#undef LOAD32
1162#undef STORE32
1163#undef MAX32
1164#undef INIT
1165#undef NEXT
1166#undef LAST
1167
1168#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1169 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1170 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
1171
1172#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
1173/*
1174 * Here we have an actual Mersenne prime, so things are more straightforward.
1175 * However, chunks are aligned on a 'weird' boundary (521 bits).
1176 */
1177
1178/* Size of p521 in terms of mbedtls_mpi_uint */
1179#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
1180
1181/* Bits to keep in the most significant mbedtls_mpi_uint */
1182#define P521_MASK 0x01FF
1183
1184/*
1185 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1186 * Write N as A1 + 2^521 A0, return A0 + A1
1187 */
1188static int ecp_mod_p521( mbedtls_mpi *N )
1189{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001190 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001191 size_t i;
1192 mbedtls_mpi M;
1193 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1194 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
1195 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1196 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1197
1198 if( N->n < P521_WIDTH )
1199 return( 0 );
1200
1201 /* M = A1 */
1202 M.s = 1;
1203 M.n = N->n - ( P521_WIDTH - 1 );
1204 if( M.n > P521_WIDTH + 1 )
1205 M.n = P521_WIDTH + 1;
1206 M.p = Mp;
1207 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1208 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
1209
1210 /* N = A0 */
1211 N->p[P521_WIDTH - 1] &= P521_MASK;
1212 for( i = P521_WIDTH; i < N->n; i++ )
1213 N->p[i] = 0;
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{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001239 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001240 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 /* M = A1 */
1248 M.s = 1;
1249 M.n = N->n - ( P255_WIDTH - 1 );
1250 if( M.n > P255_WIDTH + 1 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001251 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Jens Wiklander817466c2018-05-22 13:49:31 +02001252 M.p = Mp;
1253 memset( Mp, 0, sizeof Mp );
1254 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1255 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
1256 M.n++; /* Make room for multiplication by 19 */
1257
1258 /* N = A0 */
1259 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
1260 for( i = P255_WIDTH; i < N->n; i++ )
1261 N->p[i] = 0;
1262
1263 /* N = A0 + 19 * A1 */
1264 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1265 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
1266
1267cleanup:
1268 return( ret );
1269}
1270#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
1271
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001272#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1273
1274/* Size of p448 in terms of mbedtls_mpi_uint */
1275#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1276
1277/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1278#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1279#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1280#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1281#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1282
1283/*
1284 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1285 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1286 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1287 * implementation of Curve448, which uses its own special 56-bit limbs rather
1288 * than a generic bignum library. We could squeeze some extra speed out on
1289 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1290 * arithmetic using the limbs directly as we do for the NIST primes above,
1291 * but for 64-bit targets it should use half the number of operations if we do
1292 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1293 */
1294static int ecp_mod_p448( mbedtls_mpi *N )
1295{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001296 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001297 size_t i;
1298 mbedtls_mpi M, Q;
1299 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1300
1301 if( N->n <= P448_WIDTH )
1302 return( 0 );
1303
1304 /* M = A1 */
1305 M.s = 1;
1306 M.n = N->n - ( P448_WIDTH );
1307 if( M.n > P448_WIDTH )
1308 /* Shouldn't be called with N larger than 2^896! */
1309 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1310 M.p = Mp;
1311 memset( Mp, 0, sizeof( Mp ) );
1312 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1313
1314 /* N = A0 */
1315 for( i = P448_WIDTH; i < N->n; i++ )
1316 N->p[i] = 0;
1317
1318 /* N += A1 */
1319 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1320
1321 /* Q = B1, N += B1 */
1322 Q = M;
1323 Q.p = Qp;
1324 memcpy( Qp, Mp, sizeof( Qp ) );
1325 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1326 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1327
1328 /* M = (B0 + B1) * 2^224, N += M */
1329 if( sizeof( mbedtls_mpi_uint ) > 4 )
1330 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1331 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1332 Mp[i] = 0;
1333 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1334 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1335 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1336 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1337
1338cleanup:
1339 return( ret );
1340}
1341#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1342
Jens Wiklander817466c2018-05-22 13:49:31 +02001343#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1344 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1345 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1346/*
1347 * Fast quasi-reduction modulo P = 2^s - R,
1348 * with R about 33 bits, used by the Koblitz curves.
1349 *
1350 * Write N as A0 + 2^224 A1, return A0 + R * A1.
1351 * Actually do two passes, since R is big.
1352 */
1353#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1354#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1355static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1356 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
1357{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001358 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001359 size_t i;
1360 mbedtls_mpi M, R;
1361 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
1362
1363 if( N->n < p_limbs )
1364 return( 0 );
1365
1366 /* Init R */
1367 R.s = 1;
1368 R.p = Rp;
1369 R.n = P_KOBLITZ_R;
1370
1371 /* Common setup for M */
1372 M.s = 1;
1373 M.p = Mp;
1374
1375 /* M = A1 */
1376 M.n = N->n - ( p_limbs - adjust );
1377 if( M.n > p_limbs + adjust )
1378 M.n = p_limbs + adjust;
1379 memset( Mp, 0, sizeof Mp );
1380 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
1381 if( shift != 0 )
1382 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
1383 M.n += R.n; /* Make room for multiplication by R */
1384
1385 /* N = A0 */
1386 if( mask != 0 )
1387 N->p[p_limbs - 1] &= mask;
1388 for( i = p_limbs; i < N->n; i++ )
1389 N->p[i] = 0;
1390
1391 /* N = A0 + R * A1 */
1392 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1393 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
1394
1395 /* Second pass */
1396
1397 /* M = A1 */
1398 M.n = N->n - ( p_limbs - adjust );
1399 if( M.n > p_limbs + adjust )
1400 M.n = p_limbs + adjust;
1401 memset( Mp, 0, sizeof Mp );
1402 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
1403 if( shift != 0 )
1404 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
1405 M.n += R.n; /* Make room for multiplication by R */
1406
1407 /* N = A0 */
1408 if( mask != 0 )
1409 N->p[p_limbs - 1] &= mask;
1410 for( i = p_limbs; i < N->n; i++ )
1411 N->p[i] = 0;
1412
1413 /* N = A0 + R * A1 */
1414 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1415 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
1416
1417cleanup:
1418 return( ret );
1419}
1420#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1421 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1422 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
1423
1424#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
1425/*
1426 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1427 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1428 */
1429static int ecp_mod_p192k1( mbedtls_mpi *N )
1430{
1431 static mbedtls_mpi_uint Rp[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +02001432 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
1433 0x00 ) };
Jens Wiklander817466c2018-05-22 13:49:31 +02001434
Jerome Forissier3602df82021-07-28 10:24:04 +02001435 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1436 0 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001437}
1438#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
1439
1440#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
1441/*
1442 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1443 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1444 */
1445static int ecp_mod_p224k1( mbedtls_mpi *N )
1446{
1447 static mbedtls_mpi_uint Rp[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +02001448 MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
1449 0x00 ) };
Jens Wiklander817466c2018-05-22 13:49:31 +02001450
1451#if defined(MBEDTLS_HAVE_INT64)
1452 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1453#else
Jerome Forissier3602df82021-07-28 10:24:04 +02001454 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1455 0 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001456#endif
1457}
1458
1459#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
1460
1461#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1462/*
1463 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1464 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1465 */
1466static int ecp_mod_p256k1( mbedtls_mpi *N )
1467{
1468 static mbedtls_mpi_uint Rp[] = {
Jerome Forissier3602df82021-07-28 10:24:04 +02001469 MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
1470 0x00 ) };
1471 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1472 0 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001473}
1474#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
1475
1476#endif /* !MBEDTLS_ECP_ALT */
1477
1478#endif /* MBEDTLS_ECP_C */