blob: 6ce4f64c1636dd62c3812237a07e60d65fb73fdf [file] [log] [blame]
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001/*
2 * Elliptic curves over GF(p): curve-specific data and functions
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * 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.
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010023
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/ecp.h"
Hanno Becker4f8e8e52018-12-14 15:08:03 +000025#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000026#include "mbedtls/error.h"
Janos Follathbc96a792021-06-24 14:48:38 +010027#include "mbedtls/bn_mul.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010028
Gilles Peskine618be2e2021-04-03 21:47:53 +020029#include "ecp_invasive.h"
30
Rich Evans00ab4702015-02-06 13:43:58 +000031#include <string.h>
32
Janos Follathb0697532016-08-18 12:38:46 +010033#if !defined(MBEDTLS_ECP_ALT)
34
Hanno Becker4f8e8e52018-12-14 15:08:03 +000035/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010036#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)
Hanno Becker4f8e8e52018-12-14 15:08:03 +000040
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010041#define ECP_MPI_INIT(s, n, p) { s, (n), (mbedtls_mpi_uint *) (p) }
Manuel Pégourié-Gonnard10b8e5a2021-06-23 12:25:48 +020042
43#define ECP_MPI_INIT_ARRAY(x) \
44 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
45
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010046/*
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010047 * Note: the constants are in little-endian order
48 * to be directly usable in MPIs
49 */
50
51/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010052 * Domain parameters for secp192r1
53 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
55static const mbedtls_mpi_uint secp192r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010056 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010059};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060static const mbedtls_mpi_uint secp192r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010061 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010064};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065static const mbedtls_mpi_uint secp192r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010069};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070static const mbedtls_mpi_uint secp192r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010071 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010074};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075static const mbedtls_mpi_uint secp192r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010076 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010079};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010081
82/*
83 * Domain parameters for secp224r1
84 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
86static const mbedtls_mpi_uint secp224r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010087 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010091};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020092static const mbedtls_mpi_uint secp224r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010093 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010097};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098static const mbedtls_mpi_uint secp224r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010099 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100103};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104static const mbedtls_mpi_uint secp224r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100105 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100109};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110static const mbedtls_mpi_uint secp224r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100111 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100115};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100117
118/*
119 * Domain parameters for secp256r1
120 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
122static const mbedtls_mpi_uint secp256r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100123 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100127};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128static const mbedtls_mpi_uint secp256r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100133};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134static const mbedtls_mpi_uint secp256r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100135 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100139};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140static const mbedtls_mpi_uint secp256r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100145};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146static const mbedtls_mpi_uint secp256r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100151};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100153
154/*
155 * Domain parameters for secp384r1
156 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
158static const mbedtls_mpi_uint secp384r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100165};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200166static const mbedtls_mpi_uint secp384r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100173};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200174static const mbedtls_mpi_uint secp384r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100175 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100181};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200182static const mbedtls_mpi_uint secp384r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100183 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100189};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190static const mbedtls_mpi_uint secp384r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100191 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100197};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100199
200/*
201 * Domain parameters for secp521r1
202 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
204static const mbedtls_mpi_uint secp521r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100205 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100214};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215static const mbedtls_mpi_uint secp521r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100216 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100225};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200226static const mbedtls_mpi_uint secp521r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100227 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100236};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237static const mbedtls_mpi_uint secp521r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100247};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248static const mbedtls_mpi_uint secp521r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100249 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100258};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100260
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
262static const mbedtls_mpi_uint secp192k1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100263 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),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100266};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267static const mbedtls_mpi_uint secp192k1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100269};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270static const mbedtls_mpi_uint secp192k1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100271 MBEDTLS_BYTES_TO_T_UINT_2(0x03, 0x00),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100272};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273static const mbedtls_mpi_uint secp192k1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 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),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100277};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200278static const mbedtls_mpi_uint secp192k1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100279 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),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100282};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283static const mbedtls_mpi_uint secp192k1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100284 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),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100287};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100289
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
291static const mbedtls_mpi_uint secp224k1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292 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),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100296};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297static const mbedtls_mpi_uint secp224k1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100299};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300static const mbedtls_mpi_uint secp224k1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100301 MBEDTLS_BYTES_TO_T_UINT_2(0x05, 0x00),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100302};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303static const mbedtls_mpi_uint secp224k1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100304 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),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100308};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309static const mbedtls_mpi_uint secp224k1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310 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),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100314};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200315static const mbedtls_mpi_uint secp224k1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100316 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),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100320};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
324static const mbedtls_mpi_uint secp256k1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100325 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),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100329};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330static const mbedtls_mpi_uint secp256k1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100332};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333static const mbedtls_mpi_uint secp256k1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334 MBEDTLS_BYTES_TO_T_UINT_2(0x07, 0x00),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100335};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336static const mbedtls_mpi_uint secp256k1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337 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),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100341};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342static const mbedtls_mpi_uint secp256k1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100343 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),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100347};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348static const mbedtls_mpi_uint secp256k1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100349 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),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100353};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100355
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100356/*
357 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
358 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
360static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100361 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100365};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100367 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100371};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100377};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100379 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100383};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100389};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100395};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100397
398/*
399 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
400 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
402static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100409};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100411 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100417};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100425};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100427 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100433};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100435 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100441};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100443 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100449};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100451
452/*
453 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
454 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
456static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100457 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100465};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100467 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100475};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100477 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100485};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100495};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100505};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100507 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),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100515};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100517
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200518#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)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100534/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100535 * Create an MPI from embedded constants
Dave Rodgman18688702023-02-02 12:40:50 +0000536 * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint))
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100537 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100538static inline void ecp_mpi_load(mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len)
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100539{
540 X->s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100541 X->n = len / sizeof(mbedtls_mpi_uint);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 X->p = (mbedtls_mpi_uint *) p;
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100543}
544
545/*
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100546 * Set an MPI to static value 1
547 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100548static inline void ecp_mpi_set1(mbedtls_mpi *X)
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100549{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 static mbedtls_mpi_uint one[] = { 1 };
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100551 X->s = 1;
552 X->n = 1;
553 X->p = one;
554}
555
556/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100557 * Make group available from embedded constants
558 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100559static 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)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100566{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100567 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);
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100573
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100574 ecp_mpi_load(&grp->G.X, gx, gxlen);
575 ecp_mpi_load(&grp->G.Y, gy, gylen);
576 ecp_mpi_set1(&grp->G.Z);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100577
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100578 grp->pbits = mbedtls_mpi_bitlen(&grp->P);
579 grp->nbits = mbedtls_mpi_bitlen(&grp->N);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100580
Manuel Pégourié-Gonnard1f82b042013-12-06 12:51:50 +0100581 grp->h = 1;
582
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100583 return 0;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100584}
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200585#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100586
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100588/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100590static int ecp_mod_p192(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100591#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100593static int ecp_mod_p224(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100594#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100596static int ecp_mod_p256(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100597#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100599static int ecp_mod_p384(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100600#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100602static int ecp_mod_p521(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100603#endif
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100604
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100605#define NIST_MODP(P) grp->modp = ecp_mod_ ## P;
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100606#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100607#define NIST_MODP(P)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100609
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100610/* Additional forward declarations */
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200611#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100612static int ecp_mod_p255(mbedtls_mpi *);
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100613#endif
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000614#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100615static int ecp_mod_p448(mbedtls_mpi *);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000616#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100618static int ecp_mod_p192k1(mbedtls_mpi *);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100619#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100621static int ecp_mod_p224k1(mbedtls_mpi *);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100622#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624static int ecp_mod_p256k1(mbedtls_mpi *);
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100625#endif
626
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200627#if defined(ECP_LOAD_GROUP)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100628#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))
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100635
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100636#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))
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200643#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100644
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200645#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200646/* Constants used by ecp_use_curve25519() */
Janos Follath1c6a4392021-06-24 15:00:33 +0100647static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200648static 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
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100653/*
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100654 * Specialized function for creating the Curve25519 group
655 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100656static int ecp_use_curve25519(mbedtls_ecp_group *grp)
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100657{
Janos Follath24eed8d2019-11-22 13:21:35 +0000658 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100659
660 /* Actually ( A + 2 ) / 4 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100661 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24));
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100662
663 /* P = 2^255 - 19 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100664 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);
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100668
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100669 /* N = 2^252 + 27742317777372353535851937790883648493 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100670 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));
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100673
Manuel Pégourié-Gonnard18b78432018-03-28 11:14:06 +0200674 /* Y intentionally not set, since we use x/z coordinates.
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100675 * This is used as a marker to identify Montgomery curves! */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100676 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);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100679
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100680 /* Actually, the required msb for private keys */
681 grp->nbits = 254;
682
683cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100684 if (ret != 0) {
685 mbedtls_ecp_group_free(grp);
686 }
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100687
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100688 return ret;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100689}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200690#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100691
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000692#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200693/* Constants used by ecp_use_curve448() */
Janos Follath1c6a4392021-06-24 15:00:33 +0100694static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200695static 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
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000702/*
703 * Specialized function for creating the Curve448 group
704 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100705static int ecp_use_curve448(mbedtls_ecp_group *grp)
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000706{
707 mbedtls_mpi Ns;
Janos Follath24eed8d2019-11-22 13:21:35 +0000708 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000709
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100710 mbedtls_mpi_init(&Ns);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000711
712 /* Actually ( A + 2 ) / 4 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100713 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000714
715 /* P = 2^448 - 2^224 - 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100716 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);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000722
723 /* Y intentionally not set, since we use x/z coordinates.
724 * This is used as a marker to identify Montgomery curves! */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100725 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);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000728
729 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100730 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));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000734
735 /* Actually, the required msb for private keys */
736 grp->nbits = 447;
737
738cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100739 mbedtls_mpi_free(&Ns);
740 if (ret != 0) {
741 mbedtls_ecp_group_free(grp);
742 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000743
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100744 return ret;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000745}
746#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
747
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100748/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100749 * Set a group using well-known domain parameters
750 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100751int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100752{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100753 ECP_VALIDATE_RET(grp != NULL);
754 mbedtls_ecp_group_free(grp);
Pol Henarejosc46a2f62022-05-09 11:03:26 +0200755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756 mbedtls_ecp_group_init(grp);
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100757
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100758 grp->id = id;
759
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100760 switch (id) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
762 case MBEDTLS_ECP_DP_SECP192R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100763 NIST_MODP(p192);
764 return LOAD_GROUP(secp192r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200765#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100766
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
768 case MBEDTLS_ECP_DP_SECP224R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100769 NIST_MODP(p224);
770 return LOAD_GROUP(secp224r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100772
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
774 case MBEDTLS_ECP_DP_SECP256R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100775 NIST_MODP(p256);
776 return LOAD_GROUP(secp256r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100778
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
780 case MBEDTLS_ECP_DP_SECP384R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100781 NIST_MODP(p384);
782 return LOAD_GROUP(secp384r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
786 case MBEDTLS_ECP_DP_SECP521R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100787 NIST_MODP(p521);
788 return LOAD_GROUP(secp521r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
792 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100793 grp->modp = ecp_mod_p192k1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794 return LOAD_GROUP_A(secp192k1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100796
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
798 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100799 grp->modp = ecp_mod_p224k1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100800 return LOAD_GROUP_A(secp224k1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100802
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
804 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100805 grp->modp = ecp_mod_p256k1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100806 return LOAD_GROUP_A(secp256k1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100808
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
810 case MBEDTLS_ECP_DP_BP256R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100811 return LOAD_GROUP_A(brainpoolP256r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100813
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200814#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
815 case MBEDTLS_ECP_DP_BP384R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100816 return LOAD_GROUP_A(brainpoolP384r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100818
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200819#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
820 case MBEDTLS_ECP_DP_BP512R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100821 return LOAD_GROUP_A(brainpoolP512r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100823
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200824#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
825 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100826 grp->modp = ecp_mod_p255;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100827 return ecp_use_curve25519(grp);
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200828#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100829
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000830#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
831 case MBEDTLS_ECP_DP_CURVE448:
832 grp->modp = ecp_mod_p448;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100833 return ecp_use_curve448(grp);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000834#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
835
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100836 default:
Alexander K56a74cd2019-09-10 17:58:20 +0300837 grp->id = MBEDTLS_ECP_DP_NONE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100838 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100839 }
840}
841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100843/*
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100854/*
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.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 * 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.
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100864 */
865
866/* Add 64-bit chunks (dst += src) and update carry */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100867static inline void add64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100868{
869 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 mbedtls_mpi_uint c = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100871 for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++, src++) {
872 *dst += c; c = (*dst < c);
873 *dst += *src; c += (*dst < *src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100874 }
875 *carry += c;
876}
877
878/* Add carry to a 64-bit chunk and update carry */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100879static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100880{
881 unsigned char i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100882 for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100883 *dst += *carry;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 *carry = (*dst < *carry);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100885 }
886}
887
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100888#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
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100893
894/*
895 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
896 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100897static int ecp_mod_p192(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100898{
Janos Follath24eed8d2019-11-22 13:21:35 +0000899 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_mpi_uint c = 0;
901 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100902
903 /* Make sure we have enough blocks so that A(5) is legal */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, 6 * WIDTH));
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100905
906 p = N->p;
907 end = p + N->n;
908
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100909 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
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100912
913cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100915}
916
917#undef WIDTH
918#undef A
919#undef ADD
920#undef NEXT
921#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200922#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
925 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
926 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100927/*
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100943#define LOAD32 cur = A(i);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100944
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200945#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100946
947#define MAX32 N->n
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100948#define A(j) N->p[j]
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100949#define STORE32 N->p[i] = cur;
950
951#else /* 64-bit */
952
953#define MAX32 N->n * 2
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100954#define A(j) (j) % 2 ? (uint32_t) (N->p[(j)/2] >> 32) : \
955 (uint32_t) (N->p[(j)/2])
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100956#define STORE32 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100957 if (i % 2) { \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100958 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100960 } else { \
961 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100963 }
964
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100966
967/*
968 * Helpers for addition and subtraction of chunks, with signed carry.
969 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100970static inline void add32(uint32_t *dst, uint32_t src, signed char *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100971{
972 *dst += src;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100973 *carry += (*dst < src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100974}
975
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100976static inline void sub32(uint32_t *dst, uint32_t src, signed char *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100977{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100978 *carry -= (*dst < src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100979 *dst -= src;
980}
981
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100982#define ADD(j) add32(&cur, A(j), &c);
983#define SUB(j) sub32(&cur, A(j), &c);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100984
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200985#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
Gilles Peskineb76517b2021-03-10 23:44:28 +0100986#define biL (ciL << 3) /* bits in limb */
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200987
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100988/*
989 * Helpers for the main 'loop'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100990 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100991#define INIT(b) \
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200992 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100993 signed char c = 0, cc; \
994 uint32_t cur; \
995 size_t i = 0, bits = (b); \
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200996 /* N is the size of the product of two b-bit numbers, plus one */ \
997 /* limb for fix_negative */ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100998 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, (b) * 2 / biL + 1)); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100999 LOAD32;
1000
1001#define NEXT \
1002 STORE32; i++; LOAD32; \
1003 cc = c; c = 0; \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001004 if (cc < 0) \
1005 sub32(&cur, -cc, &c); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001006 else \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001007 add32(&cur, cc, &c); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001008
1009#define LAST \
1010 STORE32; i++; \
1011 cur = c > 0 ? c : 0; STORE32; \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001012 cur = 0; while (++i < MAX32) { STORE32; } \
1013 if (c < 0) mbedtls_ecp_fix_negative(N, c, bits);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001014
1015/*
1016 * If the result is negative, we get it in the form
Gilles Peskine349b3722021-04-03 21:40:11 +02001017 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001018 */
Gilles Peskine618be2e2021-04-03 21:47:53 +02001019MBEDTLS_STATIC_TESTABLE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001020void mbedtls_ecp_fix_negative(mbedtls_mpi *N, signed char c, size_t bits)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001021{
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001022 size_t i;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001023
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001024 /* 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. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001027 for (i = 0; i <= bits / 8 / sizeof(mbedtls_mpi_uint); i++) {
1028 N->p[i] = ~(mbedtls_mpi_uint) 0 - N->p[i];
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001029 }
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001030 /* Add 1, taking care of the carry. */
1031 i = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001032 do {
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001033 ++N->p[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001034 } while (N->p[i++] == 0 && i <= bits / 8 / sizeof(mbedtls_mpi_uint));
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001035 /* Invert the sign.
1036 * Now N = N0 - 2^bits where N0 is the initial value of N. */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001037 N->s = -1;
1038
Gilles Peskine349b3722021-04-03 21:40:11 +02001039 /* Add |c| * 2^bits to the absolute value. Since c and N are
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001040 * negative, this adds c * 2^bits. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001041 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1042#if defined(MBEDTLS_HAVE_INT64)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001043 if (bits == 224) {
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001044 msw <<= 32;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001045 }
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001046#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001047 N->p[bits / 8 / sizeof(mbedtls_mpi_uint)] += msw;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001048}
1049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001051/*
1052 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1053 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001054static int ecp_mod_p224(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001055{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001056 INIT(224);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001057
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001058 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
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001065
1066cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001067 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001068}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001072/*
1073 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1074 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001075static int ecp_mod_p256(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001076{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001077 INIT(256);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001078
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001079 ADD(8); ADD(9);
1080 SUB(11); SUB(12); SUB(13); SUB(14); NEXT; // A0
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001081
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001082 ADD(9); ADD(10);
1083 SUB(12); SUB(13); SUB(14); SUB(15); NEXT; // A1
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001085 ADD(10); ADD(11);
1086 SUB(13); SUB(14); SUB(15); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001087
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001088 ADD(11); ADD(11); ADD(12); ADD(12); ADD(13);
1089 SUB(15); SUB(8); SUB(9); NEXT; // A3
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001090
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001091 ADD(12); ADD(12); ADD(13); ADD(13); ADD(14);
1092 SUB(9); SUB(10); NEXT; // A4
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001093
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001094 ADD(13); ADD(13); ADD(14); ADD(14); ADD(15);
1095 SUB(10); SUB(11); NEXT; // A5
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001096
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001097 ADD(14); ADD(14); ADD(15); ADD(15); ADD(14); ADD(13);
1098 SUB(8); SUB(9); NEXT; // A6
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001099
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001100 ADD(15); ADD(15); ADD(15); ADD(8);
1101 SUB(10); SUB(11); SUB(12); SUB(13); LAST; // A7
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001102
1103cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001104 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001105}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001108#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001109/*
1110 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1111 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001112static int ecp_mod_p384(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001113{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001114 INIT(384);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001115
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001116 ADD(12); ADD(21); ADD(20);
1117 SUB(23); NEXT; // A0
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001118
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001119 ADD(13); ADD(22); ADD(23);
1120 SUB(12); SUB(20); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001121
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001122 ADD(14); ADD(23);
1123 SUB(13); SUB(21); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001124
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001125 ADD(15); ADD(12); ADD(20); ADD(21);
1126 SUB(14); SUB(22); SUB(23); NEXT; // A3
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001128 ADD(21); ADD(21); ADD(16); ADD(13); ADD(12); ADD(20); ADD(22);
1129 SUB(15); SUB(23); SUB(23); NEXT; // A4
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001131 ADD(22); ADD(22); ADD(17); ADD(14); ADD(13); ADD(21); ADD(23);
1132 SUB(16); NEXT; // A5
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001133
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001134 ADD(23); ADD(23); ADD(18); ADD(15); ADD(14); ADD(22);
1135 SUB(17); NEXT; // A6
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001136
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001137 ADD(19); ADD(16); ADD(15); ADD(23);
1138 SUB(18); NEXT; // A7
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001139
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001140 ADD(20); ADD(17); ADD(16);
1141 SUB(19); NEXT; // A8
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001142
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001143 ADD(21); ADD(18); ADD(17);
1144 SUB(20); NEXT; // A9
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001145
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001146 ADD(22); ADD(19); ADD(18);
1147 SUB(21); NEXT; // A10
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001149 ADD(23); ADD(20); ADD(19);
1150 SUB(22); LAST; // A11
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001151
1152cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001153 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001154}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001156
1157#undef A
1158#undef LOAD32
1159#undef STORE32
1160#undef MAX32
1161#undef INIT
1162#undef NEXT
1163#undef LAST
1164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001165#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1166 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1167 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001169#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001170/*
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001175/* Size of p521 in terms of mbedtls_mpi_uint */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001176#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001179#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001180
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001185static int ecp_mod_p521(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001186{
Janos Follath24eed8d2019-11-22 13:21:35 +00001187 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001188 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189 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:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001192 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1193 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001195 if (N->n < P521_WIDTH) {
1196 return 0;
1197 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001198
1199 /* M = A1 */
1200 M.s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001201 M.n = N->n - (P521_WIDTH - 1);
1202 if (M.n > P521_WIDTH + 1) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001203 M.n = P521_WIDTH + 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001204 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001205 M.p = Mp;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001206 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))));
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001208
1209 /* N = A0 */
1210 N->p[P521_WIDTH - 1] &= P521_MASK;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001211 for (i = P521_WIDTH; i < N->n; i++) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001212 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001213 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001214
1215 /* N = A0 + A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001216 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001217
1218cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001219 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001220}
1221
1222#undef P521_WIDTH
1223#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001225
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001226#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001227
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001228#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230/* Size of p255 in terms of mbedtls_mpi_uint */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001232
1233/*
1234 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001235 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001236 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001237static int ecp_mod_p255(mbedtls_mpi *N)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001238{
Janos Follath24eed8d2019-11-22 13:21:35 +00001239 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001240 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 mbedtls_mpi M;
1242 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001243
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001244 if (N->n < P255_WIDTH) {
1245 return 0;
1246 }
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001247
1248 /* M = A1 */
1249 M.s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001250 M.n = N->n - (P255_WIDTH - 1);
1251 if (M.n > P255_WIDTH + 1) {
1252 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1253 }
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001254 M.p = Mp;
Dave Rodgmanecb44202023-02-02 15:34:23 +00001255 memset(Mp, 0, sizeof(Mp));
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001256 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))));
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001258 M.n++; /* Make room for multiplication by 19 */
1259
1260 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001261 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(N, 255, 0));
1262 for (i = P255_WIDTH; i < N->n; i++) {
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001263 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001264 }
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001265
1266 /* N = A0 + 19 * A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001267 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&M, &M, 19));
1268 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001269
1270cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001271 return ret;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001272}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001273#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001274
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001275#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1276
1277/* Size of p448 in terms of mbedtls_mpi_uint */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001278#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint))
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001279
1280/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001281#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)
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001285
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001297static int ecp_mod_p448(mbedtls_mpi *N)
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001298{
Janos Follath24eed8d2019-11-22 13:21:35 +00001299 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001300 size_t i;
1301 mbedtls_mpi M, Q;
1302 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1303
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001304 if (N->n <= P448_WIDTH) {
1305 return 0;
1306 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001307
1308 /* M = A1 */
1309 M.s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001310 M.n = N->n - (P448_WIDTH);
1311 if (M.n > P448_WIDTH) {
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001312 /* Shouldn't be called with N larger than 2^896! */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001313 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1314 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001315 M.p = Mp;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001316 memset(Mp, 0, sizeof(Mp));
1317 memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001318
1319 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001320 for (i = P448_WIDTH; i < N->n; i++) {
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001321 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001322 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001323
1324 /* N += A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001325 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001326
1327 /* Q = B1, N += B1 */
1328 Q = M;
1329 Q.p = Qp;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001330 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));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001333
1334 /* M = (B0 + B1) * 2^224, N += M */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001335 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) {
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001339 Mp[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001340 }
1341 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001342 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001343 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224));
1344 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001345
1346cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001347 return ret;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001348}
1349#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1352 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1353 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001354/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001355 * Fast quasi-reduction modulo P = 2^s - R,
1356 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001357 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001358 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001359 * Actually do two passes, since R is big.
1360 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001361#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)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001365{
Janos Follath24eed8d2019-11-22 13:21:35 +00001366 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001367 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001369 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001370
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001371 if (N->n < p_limbs) {
1372 return 0;
1373 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001374
1375 /* Init R */
1376 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001377 R.p = Rp;
1378 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001379
1380 /* Common setup for M */
1381 M.s = 1;
1382 M.p = Mp;
1383
1384 /* M = A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001385 M.n = N->n - (p_limbs - adjust);
1386 if (M.n > p_limbs + adjust) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001387 M.n = p_limbs + adjust;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001388 }
Dave Rodgman18688702023-02-02 12:40:50 +00001389 memset(Mp, 0, sizeof(Mp));
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001390 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 }
Janos Follath7dadc2f2017-01-27 16:05:20 +00001394 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001395
1396 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001397 if (mask != 0) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001398 N->p[p_limbs - 1] &= mask;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001399 }
1400 for (i = p_limbs; i < N->n; i++) {
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001401 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001402 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001403
1404 /* N = A0 + R * A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001405 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
1406 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001407
1408 /* Second pass */
1409
1410 /* M = A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001411 M.n = N->n - (p_limbs - adjust);
1412 if (M.n > p_limbs + adjust) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001413 M.n = p_limbs + adjust;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001414 }
Dave Rodgman18688702023-02-02 12:40:50 +00001415 memset(Mp, 0, sizeof(Mp));
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001416 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 }
Janos Follath7dadc2f2017-01-27 16:05:20 +00001420 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001421
1422 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001423 if (mask != 0) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001424 N->p[p_limbs - 1] &= mask;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001425 }
1426 for (i = p_limbs; i < N->n; i++) {
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001427 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001428 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001429
1430 /* N = A0 + R * A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001431 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
1432 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001433
1434cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001435 return ret;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001436}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1438 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1439 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001441#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001442/*
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001446static int ecp_mod_p192k1(mbedtls_mpi *N)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001447{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448 static mbedtls_mpi_uint Rp[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001449 MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
1450 0x00)
1451 };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001452
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001453 return ecp_mod_koblitz(N, Rp, 192 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1454 0);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001455}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001456#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001458#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001459/*
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001463static int ecp_mod_p224k1(mbedtls_mpi *N)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001464{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465 static mbedtls_mpi_uint Rp[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001466 MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
1467 0x00)
1468 };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470#if defined(MBEDTLS_HAVE_INT64)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001471 return ecp_mod_koblitz(N, Rp, 4, 1, 32, 0xFFFFFFFF);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001472#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001473 return ecp_mod_koblitz(N, Rp, 224 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1474 0);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001475#endif
1476}
1477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001478#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001481/*
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 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001485static int ecp_mod_p256k1(mbedtls_mpi *N)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001486{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487 static mbedtls_mpi_uint Rp[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001488 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);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001493}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001495
Janos Follathb0697532016-08-18 12:38:46 +01001496#endif /* !MBEDTLS_ECP_ALT */
1497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001498#endif /* MBEDTLS_ECP_C */