blob: 8a9f79e2e04e546bddf2f5dfd9d67245d2b0f08c [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 */
David Horstmannceeaeb92023-01-05 15:44:23 +000036#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
David Horstmannceeaeb92023-01-05 15:44:23 +000041#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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000056 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000061 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000066 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000071 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000076 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000087 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000093 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +000099 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000105 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000111 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000123 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000129 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000135 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000141 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000147 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000159 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000167 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000175 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000183 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000191 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000205 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000216 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000227 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000238 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000249 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000263 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000268 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000271 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000274 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000279 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000284 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000292 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000298 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000301 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000304 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000310 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000316 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000325 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000331 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000334 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000337 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000343 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000349 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000361 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000367 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000373 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000379 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000385 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000391 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000403 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000411 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000419 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000427 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000435 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000443 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000457 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000467 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000477 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000487 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000497 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000507 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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100537 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000538static 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000541 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000548static 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000559static 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{
David Horstmannceeaeb92023-01-05 15:44:23 +0000567 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
David Horstmannceeaeb92023-01-05 15:44:23 +0000574 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
David Horstmannceeaeb92023-01-05 15:44:23 +0000578 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
David Horstmannceeaeb92023-01-05 15:44:23 +0000583 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000590static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000593static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000596static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000599static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000602static 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
David Horstmannceeaeb92023-01-05 15:44:23 +0000605#define NIST_MODP(P) grp->modp = ecp_mod_ ## P;
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100606#else
David Horstmannceeaeb92023-01-05 15:44:23 +0000607#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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000612static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000615static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000618static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000621static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000624static 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)
David Horstmannceeaeb92023-01-05 15:44:23 +0000628#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
David Horstmannceeaeb92023-01-05 15:44:23 +0000636#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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000656static 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000661 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000664 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000670 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! */
David Horstmannceeaeb92023-01-05 15:44:23 +0000676 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000684 if (ret != 0) {
685 mbedtls_ecp_group_free(grp);
686 }
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100687
David Horstmannceeaeb92023-01-05 15:44:23 +0000688 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000705static 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
David Horstmannceeaeb92023-01-05 15:44:23 +0000710 mbedtls_mpi_init(&Ns);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000711
712 /* Actually ( A + 2 ) / 4 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000713 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000716 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! */
David Horstmannceeaeb92023-01-05 15:44:23 +0000725 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000730 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000739 mbedtls_mpi_free(&Ns);
740 if (ret != 0) {
741 mbedtls_ecp_group_free(grp);
742 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000743
David Horstmannceeaeb92023-01-05 15:44:23 +0000744 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000751int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100752{
David Horstmannceeaeb92023-01-05 15:44:23 +0000753 ECP_VALIDATE_RET(grp != NULL);
754 mbedtls_ecp_group_free(grp);
Pol Henarejosc46a2f62022-05-09 11:03:26 +0200755
David Horstmannceeaeb92023-01-05 15:44:23 +0000756 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
David Horstmannceeaeb92023-01-05 15:44:23 +0000760 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000763 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000769 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000775 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000781 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000787 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000794 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000800 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000806 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000811 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000816 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000821 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000827 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000833 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000838 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000867static 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000871 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000879static 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000882 for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100883 *dst += *carry;
David Horstmannceeaeb92023-01-05 15:44:23 +0000884 *carry = (*dst < *carry);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100885 }
886}
887
David Horstmannceeaeb92023-01-05 15:44:23 +0000888#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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000897static 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000904 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
David Horstmannceeaeb92023-01-05 15:44:23 +0000909 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:
David Horstmannceeaeb92023-01-05 15:44:23 +0000914 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000943#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
David Horstmannceeaeb92023-01-05 15:44:23 +0000948#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
David Horstmannceeaeb92023-01-05 15:44:23 +0000954#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 \
David Horstmannceeaeb92023-01-05 15:44:23 +0000957 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000970static 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;
David Horstmannceeaeb92023-01-05 15:44:23 +0000973 *carry += (*dst < src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100974}
975
David Horstmannceeaeb92023-01-05 15:44:23 +0000976static inline void sub32(uint32_t *dst, uint32_t src, signed char *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100977{
David Horstmannceeaeb92023-01-05 15:44:23 +0000978 *carry -= (*dst < src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100979 *dst -= src;
980}
981
David Horstmannceeaeb92023-01-05 15:44:23 +0000982#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 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000991#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 */ \
David Horstmannceeaeb92023-01-05 15:44:23 +0000998 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; \
David Horstmannceeaeb92023-01-05 15:44:23 +00001004 if (cc < 0) \
1005 sub32(&cur, -cc, &c); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001006 else \
David Horstmannceeaeb92023-01-05 15:44:23 +00001007 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; \
David Horstmannceeaeb92023-01-05 15:44:23 +00001012 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001020void 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. */
David Horstmannceeaeb92023-01-05 15:44:23 +00001027 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001032 do {
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001033 ++N->p[i];
David Horstmannceeaeb92023-01-05 15:44:23 +00001034 } 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001040 * 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)
David Horstmannceeaeb92023-01-05 15:44:23 +00001043 if (bits == 224) {
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001044 msw <<= 32;
David Horstmannceeaeb92023-01-05 15:44:23 +00001045 }
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001046#endif
David Horstmannceeaeb92023-01-05 15:44:23 +00001047 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001054static int ecp_mod_p224(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001055{
David Horstmannceeaeb92023-01-05 15:44:23 +00001056 INIT(224);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001057
David Horstmannceeaeb92023-01-05 15:44:23 +00001058 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:
David Horstmannceeaeb92023-01-05 15:44:23 +00001067 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001075static int ecp_mod_p256(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001076{
David Horstmannceeaeb92023-01-05 15:44:23 +00001077 INIT(256);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001078
David Horstmannceeaeb92023-01-05 15:44:23 +00001079 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001082 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001085 ADD(10); ADD(11);
1086 SUB(13); SUB(14); SUB(15); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001087
David Horstmannceeaeb92023-01-05 15:44:23 +00001088 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001091 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001094 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001097 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001100 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:
David Horstmannceeaeb92023-01-05 15:44:23 +00001104 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001112static int ecp_mod_p384(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001113{
David Horstmannceeaeb92023-01-05 15:44:23 +00001114 INIT(384);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001115
David Horstmannceeaeb92023-01-05 15:44:23 +00001116 ADD(12); ADD(21); ADD(20);
1117 SUB(23); NEXT; // A0
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001118
David Horstmannceeaeb92023-01-05 15:44:23 +00001119 ADD(13); ADD(22); ADD(23);
1120 SUB(12); SUB(20); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001121
David Horstmannceeaeb92023-01-05 15:44:23 +00001122 ADD(14); ADD(23);
1123 SUB(13); SUB(21); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001124
David Horstmannceeaeb92023-01-05 15:44:23 +00001125 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001128 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001131 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001134 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001137 ADD(19); ADD(16); ADD(15); ADD(23);
1138 SUB(18); NEXT; // A7
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001139
David Horstmannceeaeb92023-01-05 15:44:23 +00001140 ADD(20); ADD(17); ADD(16);
1141 SUB(19); NEXT; // A8
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001142
David Horstmannceeaeb92023-01-05 15:44:23 +00001143 ADD(21); ADD(18); ADD(17);
1144 SUB(20); NEXT; // A9
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001145
David Horstmannceeaeb92023-01-05 15:44:23 +00001146 ADD(22); ADD(19); ADD(18);
1147 SUB(21); NEXT; // A10
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001148
David Horstmannceeaeb92023-01-05 15:44:23 +00001149 ADD(23); ADD(20); ADD(19);
1150 SUB(22); LAST; // A11
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001151
1152cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +00001153 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001176#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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001185static 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001195 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001201 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001204 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001205 M.p = Mp;
David Horstmannceeaeb92023-01-05 15:44:23 +00001206 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001211 for (i = P521_WIDTH; i < N->n; i++) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001212 N->p[i] = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +00001213 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001214
1215 /* N = A0 + A1 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001216 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001217
1218cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +00001219 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001231#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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001237static 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001244 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001250 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001255 memset(Mp, 0, sizeof Mp);
1256 memcpy(Mp, N->p + P255_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint));
1257 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 255 % (8 * sizeof(mbedtls_mpi_uint))));
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001258 M.n++; /* Make room for multiplication by 19 */
1259
1260 /* N = A0 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001261 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001264 }
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001265
1266 /* N = A0 + 19 * A1 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001267 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:
David Horstmannceeaeb92023-01-05 15:44:23 +00001271 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001278#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) */
David Horstmannceeaeb92023-01-05 15:44:23 +00001281#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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001297static 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001304 if (N->n <= P448_WIDTH) {
1305 return 0;
1306 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001307
1308 /* M = A1 */
1309 M.s = 1;
David Horstmannceeaeb92023-01-05 15:44:23 +00001310 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! */
David Horstmannceeaeb92023-01-05 15:44:23 +00001313 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1314 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001315 M.p = Mp;
David Horstmannceeaeb92023-01-05 15:44:23 +00001316 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001320 for (i = P448_WIDTH; i < N->n; i++) {
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001321 N->p[i] = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +00001322 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001323
1324 /* N += A1 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001325 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001330 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001335 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001340 }
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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001343 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:
David Horstmannceeaeb92023-01-05 15:44:23 +00001347 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001361#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
David Horstmannceeaeb92023-01-05 15:44:23 +00001371 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001385 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001388 }
1389 memset(Mp, 0, sizeof Mp);
1390 memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
1391 if (shift != 0) {
1392 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
1393 }
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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001397 if (mask != 0) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001398 N->p[p_limbs - 1] &= mask;
David Horstmannceeaeb92023-01-05 15:44:23 +00001399 }
1400 for (i = p_limbs; i < N->n; i++) {
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001401 N->p[i] = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +00001402 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001403
1404 /* N = A0 + R * A1 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001405 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001411 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;
David Horstmannceeaeb92023-01-05 15:44:23 +00001414 }
1415 memset(Mp, 0, sizeof Mp);
1416 memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
1417 if (shift != 0) {
1418 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
1419 }
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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001423 if (mask != 0) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001424 N->p[p_limbs - 1] &= mask;
David Horstmannceeaeb92023-01-05 15:44:23 +00001425 }
1426 for (i = p_limbs; i < N->n; i++) {
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001427 N->p[i] = 0;
David Horstmannceeaeb92023-01-05 15:44:23 +00001428 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001429
1430 /* N = A0 + R * A1 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001431 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:
David Horstmannceeaeb92023-01-05 15:44:23 +00001435 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001446static 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +00001449 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
David Horstmannceeaeb92023-01-05 15:44:23 +00001453 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001463static 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +00001466 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)
David Horstmannceeaeb92023-01-05 15:44:23 +00001471 return ecp_mod_koblitz(N, Rp, 4, 1, 32, 0xFFFFFFFF);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001472#else
David Horstmannceeaeb92023-01-05 15:44:23 +00001473 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 */
David Horstmannceeaeb92023-01-05 15:44:23 +00001485static 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[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +00001488 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 */