blob: afa3b6324e3dd1992c1e156365bac7459625e608 [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útia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010045 */
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020049#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020051#endif
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/ecp.h"
Hanno Becker4f8e8e52018-12-14 15:08:03 +000056#include "mbedtls/platform_util.h"
Janos Follath7d34e2e2021-06-24 14:48:38 +010057#include "mbedtls/bn_mul.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010058
Rich Evans00ab4702015-02-06 13:43:58 +000059#include <string.h>
60
Janos Follathb0697532016-08-18 12:38:46 +010061#if !defined(MBEDTLS_ECP_ALT)
62
Hanno Becker4f8e8e52018-12-14 15:08:03 +000063/* Parameter validation macros based on platform_util.h */
64#define ECP_VALIDATE_RET( cond ) \
65 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
66#define ECP_VALIDATE( cond ) \
67 MBEDTLS_INTERNAL_VALIDATE( cond )
68
Manuel Pégourié-Gonnard0223ab92015-10-05 11:40:01 +010069#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
70 !defined(inline) && !defined(__cplusplus)
Paul Bakker498fd352013-12-02 22:17:24 +010071#define inline __inline
Manuel Pégourié-Gonnard20af64d2015-07-07 18:33:39 +020072#endif
Paul Bakker498fd352013-12-02 22:17:24 +010073
Manuel Pégourié-Gonnard6ec15352021-06-23 12:25:48 +020074#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
75
76#define ECP_MPI_INIT_ARRAY(x) \
77 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
78
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010079/*
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010080 * Note: the constants are in little-endian order
81 * to be directly usable in MPIs
82 */
83
84/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010085 * Domain parameters for secp192r1
86 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
88static const mbedtls_mpi_uint secp192r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +010089 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
90 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
91 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010092};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093static const mbedtls_mpi_uint secp192r1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +010094 MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
95 MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
96 MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010097};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098static const mbedtls_mpi_uint secp192r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +010099 MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
100 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
101 MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100102};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103static const mbedtls_mpi_uint secp192r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100104 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
105 MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
106 MBEDTLS_BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100107};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108static const mbedtls_mpi_uint secp192r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100109 MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
110 MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
111 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100112};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100114
115/*
116 * Domain parameters for secp224r1
117 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
119static const mbedtls_mpi_uint secp224r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100120 MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
121 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
122 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
123 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100124};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125static const mbedtls_mpi_uint secp224r1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100126 MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
127 MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
128 MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
129 MBEDTLS_BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100130};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131static const mbedtls_mpi_uint secp224r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100132 MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
133 MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
134 MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
135 MBEDTLS_BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100136};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200137static const mbedtls_mpi_uint secp224r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100138 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
139 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
140 MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
141 MBEDTLS_BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100142};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143static const mbedtls_mpi_uint secp224r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100144 MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
145 MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
146 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
147 MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100148};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100150
151/*
152 * Domain parameters for secp256r1
153 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
155static const mbedtls_mpi_uint secp256r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100156 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
157 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
158 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
159 MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100160};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161static const mbedtls_mpi_uint secp256r1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100162 MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
163 MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
164 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
165 MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100166};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167static const mbedtls_mpi_uint secp256r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100168 MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
169 MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
170 MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
171 MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100172};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173static const mbedtls_mpi_uint secp256r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100174 MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
175 MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
176 MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
177 MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100178};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179static const mbedtls_mpi_uint secp256r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100180 MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
181 MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
182 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
183 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100184};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100186
187/*
188 * Domain parameters for secp384r1
189 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
191static const mbedtls_mpi_uint secp384r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100192 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
193 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
194 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
195 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
196 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
197 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100198};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199static const mbedtls_mpi_uint secp384r1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100200 MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
201 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
202 MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
203 MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
204 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
205 MBEDTLS_BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100206};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207static const mbedtls_mpi_uint secp384r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100208 MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
209 MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
210 MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
211 MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
212 MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
213 MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100214};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215static const mbedtls_mpi_uint secp384r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100216 MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
217 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
218 MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
219 MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
220 MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
221 MBEDTLS_BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100222};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223static const mbedtls_mpi_uint secp384r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100224 MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
225 MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
226 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
227 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
228 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
229 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100230};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100232
233/*
234 * Domain parameters for secp521r1
235 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
237static const mbedtls_mpi_uint secp521r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100238 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
239 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
240 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
241 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
242 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
243 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
244 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
245 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
246 MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 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_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100249 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
250 MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
251 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
252 MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
253 MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
254 MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
255 MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
256 MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
257 MBEDTLS_BYTES_TO_T_UINT_2( 0x51, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100258};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259static const mbedtls_mpi_uint secp521r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100260 MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
261 MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
262 MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
263 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
264 MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
265 MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
266 MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
267 MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
268 MBEDTLS_BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100269};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270static const mbedtls_mpi_uint secp521r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100271 MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
272 MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
273 MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
274 MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
275 MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
276 MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
277 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
278 MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
279 MBEDTLS_BYTES_TO_T_UINT_2( 0x18, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100280};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281static const mbedtls_mpi_uint secp521r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100282 MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
283 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
284 MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
285 MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
286 MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
287 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
288 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
289 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
290 MBEDTLS_BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100291};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
295static const mbedtls_mpi_uint secp192k1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100296 MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
297 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
298 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100299};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300static const mbedtls_mpi_uint secp192k1_a[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100301 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100302};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303static const mbedtls_mpi_uint secp192k1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100304 MBEDTLS_BYTES_TO_T_UINT_2( 0x03, 0x00 ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100305};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306static const mbedtls_mpi_uint secp192k1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100307 MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
308 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
309 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100310};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311static const mbedtls_mpi_uint secp192k1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100312 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
313 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
314 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100315};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316static const mbedtls_mpi_uint secp192k1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100317 MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
318 MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
319 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100320};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
324static const mbedtls_mpi_uint secp224k1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100325 MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE5, 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_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100329};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330static const mbedtls_mpi_uint secp224k1_a[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100331 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100332};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333static const mbedtls_mpi_uint secp224k1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100334 MBEDTLS_BYTES_TO_T_UINT_2( 0x05, 0x00 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100335};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336static const mbedtls_mpi_uint secp224k1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100337 MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
338 MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
339 MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
340 MBEDTLS_BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100341};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342static const mbedtls_mpi_uint secp224k1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100343 MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
344 MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
345 MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
346 MBEDTLS_BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100347};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348static const mbedtls_mpi_uint secp224k1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100349 MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
350 MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
351 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
352 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100353};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
357static const mbedtls_mpi_uint secp256k1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100358 MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
359 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
360 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
361 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100362};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363static const mbedtls_mpi_uint secp256k1_a[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100364 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100365};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366static const mbedtls_mpi_uint secp256k1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100367 MBEDTLS_BYTES_TO_T_UINT_2( 0x07, 0x00 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100368};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369static const mbedtls_mpi_uint secp256k1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100370 MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
371 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
372 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
373 MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100374};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375static const mbedtls_mpi_uint secp256k1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100376 MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
377 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
378 MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
379 MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100380};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381static const mbedtls_mpi_uint secp256k1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100382 MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
383 MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
384 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
385 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100386};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100388
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100389/*
390 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
391 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
393static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100394 MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
395 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
396 MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
397 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100398};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100400 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
401 MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
402 MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
403 MBEDTLS_BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100404};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100406 MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
407 MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
408 MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
409 MBEDTLS_BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100410};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100412 MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
413 MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
414 MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
415 MBEDTLS_BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100416};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100418 MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
419 MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
420 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
421 MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100422};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100424 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
425 MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
426 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
427 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100428};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100430
431/*
432 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
433 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
435static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100436 MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
437 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
438 MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
439 MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
440 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
441 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100442};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100444 MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
445 MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
446 MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
447 MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
448 MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
449 MBEDTLS_BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100450};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100452 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
453 MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
454 MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
455 MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
456 MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
457 MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100458};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100460 MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
461 MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
462 MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
463 MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
464 MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
465 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100466};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100468 MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
469 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
470 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
471 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
472 MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
473 MBEDTLS_BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100474};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100476 MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
477 MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
478 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
479 MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
480 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
481 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100482};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100484
485/*
486 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
487 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
489static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100490 MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
491 MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
492 MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
493 MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
494 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
495 MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
496 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
497 MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100498};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100500 MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
501 MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
502 MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
503 MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
504 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
505 MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
506 MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
507 MBEDTLS_BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100508};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100510 MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
511 MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
512 MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
513 MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
514 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
515 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
516 MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
517 MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100518};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100520 MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
521 MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
522 MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
523 MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
524 MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
525 MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
526 MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
527 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100528};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100530 MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
531 MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
532 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
533 MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
534 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
535 MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
536 MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
537 MBEDTLS_BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100538};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +0100540 MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
541 MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
542 MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
543 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
544 MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
545 MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
546 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
547 MBEDTLS_BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100548};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100550
551/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100552 * Create an MPI from embedded constants
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100554 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555static 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 +0100556{
557 X->s = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 X->n = len / sizeof( mbedtls_mpi_uint );
559 X->p = (mbedtls_mpi_uint *) p;
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100560}
561
562/*
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100563 * Set an MPI to static value 1
564 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565static inline void ecp_mpi_set1( mbedtls_mpi *X )
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100566{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 static mbedtls_mpi_uint one[] = { 1 };
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100568 X->s = 1;
569 X->n = 1;
570 X->p = one;
571}
572
573/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100574 * Make group available from embedded constants
575 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576static int ecp_group_load( mbedtls_ecp_group *grp,
577 const mbedtls_mpi_uint *p, size_t plen,
578 const mbedtls_mpi_uint *a, size_t alen,
579 const mbedtls_mpi_uint *b, size_t blen,
580 const mbedtls_mpi_uint *gx, size_t gxlen,
581 const mbedtls_mpi_uint *gy, size_t gylen,
582 const mbedtls_mpi_uint *n, size_t nlen)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100583{
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100584 ecp_mpi_load( &grp->P, p, plen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100585 if( a != NULL )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100586 ecp_mpi_load( &grp->A, a, alen );
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100587 ecp_mpi_load( &grp->B, b, blen );
588 ecp_mpi_load( &grp->N, n, nlen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100589
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100590 ecp_mpi_load( &grp->G.X, gx, gxlen );
591 ecp_mpi_load( &grp->G.Y, gy, gylen );
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100592 ecp_mpi_set1( &grp->G.Z );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100593
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200594 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
595 grp->nbits = mbedtls_mpi_bitlen( &grp->N );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100596
Manuel Pégourié-Gonnard1f82b042013-12-06 12:51:50 +0100597 grp->h = 1;
598
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100599 return( 0 );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100600}
601
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100603/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
605static int ecp_mod_p192( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100606#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
608static int ecp_mod_p224( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100609#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
611static int ecp_mod_p256( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100612#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
614static int ecp_mod_p384( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100615#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
617static int ecp_mod_p521( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100618#endif
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100619
620#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
621#else
622#define NIST_MODP( P )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100624
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100625/* Additional forward declarations */
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200626#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627static int ecp_mod_p255( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100628#endif
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000629#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
630static int ecp_mod_p448( mbedtls_mpi * );
631#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
633static int ecp_mod_p192k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100634#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
636static int ecp_mod_p224k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100637#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
639static int ecp_mod_p256k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100640#endif
641
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100642#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
643 G ## _p, sizeof( G ## _p ), \
644 G ## _a, sizeof( G ## _a ), \
645 G ## _b, sizeof( G ## _b ), \
646 G ## _gx, sizeof( G ## _gx ), \
647 G ## _gy, sizeof( G ## _gy ), \
648 G ## _n, sizeof( G ## _n ) )
649
650#define LOAD_GROUP( G ) ecp_group_load( grp, \
651 G ## _p, sizeof( G ## _p ), \
652 NULL, 0, \
653 G ## _b, sizeof( G ## _b ), \
654 G ## _gx, sizeof( G ## _gx ), \
655 G ## _gy, sizeof( G ## _gy ), \
656 G ## _n, sizeof( G ## _n ) )
657
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200658#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200659/* Constants used by ecp_use_curve25519() */
Janos Follathb741e8d2021-06-24 15:00:33 +0100660static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200661static const unsigned char curve25519_part_of_n[] = {
662 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
663 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
664};
665
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100666/*
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100667 * Specialized function for creating the Curve25519 group
668 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669static int ecp_use_curve25519( mbedtls_ecp_group *grp )
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100670{
671 int ret;
672
673 /* Actually ( A + 2 ) / 4 */
Janos Follathb741e8d2021-06-24 15:00:33 +0100674 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100675
676 /* P = 2^255 - 19 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
678 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
679 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200680 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100681
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100682 /* N = 2^252 + 27742317777372353535851937790883648493 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200683 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
684 curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100685 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
686
Manuel Pégourié-Gonnard18b78432018-03-28 11:14:06 +0200687 /* Y intentionally not set, since we use x/z coordinates.
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100688 * This is used as a marker to identify Montgomery curves! */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
690 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
691 mbedtls_mpi_free( &grp->G.Y );
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100692
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100693 /* Actually, the required msb for private keys */
694 grp->nbits = 254;
695
696cleanup:
697 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100699
700 return( ret );
701}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200702#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100703
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000704#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200705/* Constants used by ecp_use_curve448() */
Janos Follathb741e8d2021-06-24 15:00:33 +0100706static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200707static const unsigned char curve448_part_of_n[] = {
708 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
709 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
710 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
711 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
712};
713
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000714/*
715 * Specialized function for creating the Curve448 group
716 */
717static int ecp_use_curve448( mbedtls_ecp_group *grp )
718{
719 mbedtls_mpi Ns;
720 int ret;
721
722 mbedtls_mpi_init( &Ns );
723
724 /* Actually ( A + 2 ) / 4 */
Janos Follathb741e8d2021-06-24 15:00:33 +0100725 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve448_a24 ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000726
727 /* P = 2^448 - 2^224 - 1 */
728 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
729 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
730 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
731 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
732 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
733 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
734
735 /* Y intentionally not set, since we use x/z coordinates.
736 * This is used as a marker to identify Montgomery curves! */
737 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
738 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
739 mbedtls_mpi_free( &grp->G.Y );
740
741 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
742 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200743 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
744 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000745 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
746
747 /* Actually, the required msb for private keys */
748 grp->nbits = 447;
749
750cleanup:
751 mbedtls_mpi_free( &Ns );
752 if( ret != 0 )
753 mbedtls_ecp_group_free( grp );
754
755 return( ret );
756}
757#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
758
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100759/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100760 * Set a group using well-known domain parameters
761 */
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200762int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100763{
Hanno Becker4f8e8e52018-12-14 15:08:03 +0000764 ECP_VALIDATE_RET( grp != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200765 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100766
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100767 grp->id = id;
768
769 switch( id )
770 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
772 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100773 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100774 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100776
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
778 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100779 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100780 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200781#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
784 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100785 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100786 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100788
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
790 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100791 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100792 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200793#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100794
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
796 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100797 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100798 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100800
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
802 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100803 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100804 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
808 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100809 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100810 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100812
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
814 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100815 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100816 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100818
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200819#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
820 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100821 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100823
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
825 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100826 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100828
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
830 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100831 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100833
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200834#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
835 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100836 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100837 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200838#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100839
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000840#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
841 case MBEDTLS_ECP_DP_CURVE448:
842 grp->modp = ecp_mod_p448;
843 return( ecp_use_curve448( grp ) );
844#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
845
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100846 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847 mbedtls_ecp_group_free( grp );
848 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100849 }
850}
851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100853/*
854 * Fast reduction modulo the primes used by the NIST curves.
855 *
856 * These functions are critical for speed, but not needed for correct
857 * operations. So, we make the choice to heavily rely on the internals of our
858 * bignum library, which creates a tight coupling between these functions and
859 * our MPI implementation. However, the coupling between the ECP module and
860 * MPI remains loose, since these functions can be deactivated at will.
861 */
862
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100864/*
865 * Compared to the way things are presented in FIPS 186-3 D.2,
866 * we proceed in columns, from right (least significant chunk) to left,
867 * adding chunks to N in place, and keeping a carry for the next chunk.
868 * This avoids moving things around in memory, and uselessly adding zeros,
869 * compared to the more straightforward, line-oriented approach.
870 *
871 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
873 * 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 +0100874 */
875
876/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100878{
879 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880 mbedtls_mpi_uint c = 0;
881 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100882 {
883 *dst += c; c = ( *dst < c );
884 *dst += *src; c += ( *dst < *src );
885 }
886 *carry += c;
887}
888
889/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100891{
892 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100894 {
895 *dst += *carry;
896 *carry = ( *dst < *carry );
897 }
898}
899
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Beckerd6028a12018-10-15 12:01:35 +0100901#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100902#define ADD( i ) add64( p, A( i ), &c )
903#define NEXT p += WIDTH; carry64( p, &c )
904#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
905
906/*
907 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
908 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100910{
911 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 mbedtls_mpi_uint c = 0;
913 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100914
915 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100917
918 p = N->p;
919 end = p + N->n;
920
921 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
922 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
923 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
924
925cleanup:
926 return( ret );
927}
928
929#undef WIDTH
930#undef A
931#undef ADD
932#undef NEXT
933#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
937 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
938 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100939/*
940 * The reader is advised to first understand ecp_mod_p192() since the same
941 * general structure is used here, but with additional complications:
942 * (1) chunks of 32 bits, and (2) subtractions.
943 */
944
945/*
946 * For these primes, we need to handle data in chunks of 32 bits.
947 * This makes it more complicated if we use 64 bits limbs in MPI,
948 * which prevents us from using a uniform access method as for p192.
949 *
950 * So, we define a mini abstraction layer to access 32 bit chunks,
951 * load them in 'cur' for work, and store them back from 'cur' when done.
952 *
953 * While at it, also define the size of N in terms of 32-bit chunks.
954 */
955#define LOAD32 cur = A( i );
956
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200957#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100958
959#define MAX32 N->n
960#define A( j ) N->p[j]
961#define STORE32 N->p[i] = cur;
962
963#else /* 64-bit */
964
965#define MAX32 N->n * 2
Hanno Beckerd6028a12018-10-15 12:01:35 +0100966#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
967 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100968#define STORE32 \
969 if( i % 2 ) { \
970 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100972 } else { \
973 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100975 }
976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100978
979/*
980 * Helpers for addition and subtraction of chunks, with signed carry.
981 */
982static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
983{
984 *dst += src;
985 *carry += ( *dst < src );
986}
987
988static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
989{
990 *carry -= ( *dst < src );
991 *dst -= src;
992}
993
994#define ADD( j ) add32( &cur, A( j ), &c );
995#define SUB( j ) sub32( &cur, A( j ), &c );
996
997/*
998 * Helpers for the main 'loop'
999 * (see fix_negative for the motivation of C)
1000 */
Hanno Beckerd6028a12018-10-15 12:01:35 +01001001#define INIT( b ) \
1002 int ret; \
1003 signed char c = 0, cc; \
1004 uint32_t cur; \
1005 size_t i = 0, bits = (b); \
1006 mbedtls_mpi C; \
1007 mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
1008 \
1009 C.s = 1; \
1010 C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \
1011 C.p = Cp; \
1012 memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
1013 \
1014 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \
1015 sizeof( mbedtls_mpi_uint ) ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001016 LOAD32;
1017
1018#define NEXT \
1019 STORE32; i++; LOAD32; \
1020 cc = c; c = 0; \
1021 if( cc < 0 ) \
1022 sub32( &cur, -cc, &c ); \
1023 else \
1024 add32( &cur, cc, &c ); \
1025
1026#define LAST \
1027 STORE32; i++; \
1028 cur = c > 0 ? c : 0; STORE32; \
1029 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine7d6326d2020-07-23 01:14:34 +02001030 if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001031
1032/*
1033 * If the result is negative, we get it in the form
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001034 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001035 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001037{
1038 int ret;
1039
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001040 /* C = - c * 2^bits */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041#if !defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001042 ((void) bits);
1043#else
1044 if( bits == 224 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001045 C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001046 else
1047#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001049
1050 /* N = - ( C - N ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001052 N->s = -1;
1053
1054cleanup:
1055
1056 return( ret );
1057}
1058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001060/*
1061 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1062 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001064{
1065 INIT( 224 );
1066
1067 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1068 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1069 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1070 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1071 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1072 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1073 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1074
1075cleanup:
1076 return( ret );
1077}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001081/*
1082 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1083 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001085{
1086 INIT( 256 );
1087
1088 ADD( 8 ); ADD( 9 );
1089 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1090
1091 ADD( 9 ); ADD( 10 );
1092 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1093
1094 ADD( 10 ); ADD( 11 );
1095 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1096
1097 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1098 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1099
1100 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1101 SUB( 9 ); SUB( 10 ); NEXT; // A4
1102
1103 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1104 SUB( 10 ); SUB( 11 ); NEXT; // A5
1105
1106 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1107 SUB( 8 ); SUB( 9 ); NEXT; // A6
1108
1109 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1110 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1111
1112cleanup:
1113 return( ret );
1114}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001118/*
1119 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1120 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001122{
1123 INIT( 384 );
1124
1125 ADD( 12 ); ADD( 21 ); ADD( 20 );
1126 SUB( 23 ); NEXT; // A0
1127
1128 ADD( 13 ); ADD( 22 ); ADD( 23 );
1129 SUB( 12 ); SUB( 20 ); NEXT; // A2
1130
1131 ADD( 14 ); ADD( 23 );
1132 SUB( 13 ); SUB( 21 ); NEXT; // A2
1133
1134 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1135 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1136
1137 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1138 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1139
1140 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1141 SUB( 16 ); NEXT; // A5
1142
1143 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1144 SUB( 17 ); NEXT; // A6
1145
1146 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1147 SUB( 18 ); NEXT; // A7
1148
1149 ADD( 20 ); ADD( 17 ); ADD( 16 );
1150 SUB( 19 ); NEXT; // A8
1151
1152 ADD( 21 ); ADD( 18 ); ADD( 17 );
1153 SUB( 20 ); NEXT; // A9
1154
1155 ADD( 22 ); ADD( 19 ); ADD( 18 );
1156 SUB( 21 ); NEXT; // A10
1157
1158 ADD( 23 ); ADD( 20 ); ADD( 19 );
1159 SUB( 22 ); LAST; // A11
1160
1161cleanup:
1162 return( ret );
1163}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001165
1166#undef A
1167#undef LOAD32
1168#undef STORE32
1169#undef MAX32
1170#undef INIT
1171#undef NEXT
1172#undef LAST
1173
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001174#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1175 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1176 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001179/*
1180 * Here we have an actual Mersenne prime, so things are more straightforward.
1181 * However, chunks are aligned on a 'weird' boundary (521 bits).
1182 */
1183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001184/* Size of p521 in terms of mbedtls_mpi_uint */
1185#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001187/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001188#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001189
1190/*
1191 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1192 * Write N as A1 + 2^521 A0, return A0 + A1
1193 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001194static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001195{
1196 int ret;
1197 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 mbedtls_mpi M;
1199 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1200 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001201 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1202 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1203
1204 if( N->n < P521_WIDTH )
1205 return( 0 );
1206
1207 /* M = A1 */
1208 M.s = 1;
1209 M.n = N->n - ( P521_WIDTH - 1 );
1210 if( M.n > P521_WIDTH + 1 )
1211 M.n = P521_WIDTH + 1;
1212 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001213 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1214 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001215
1216 /* N = A0 */
1217 N->p[P521_WIDTH - 1] &= P521_MASK;
1218 for( i = P521_WIDTH; i < N->n; i++ )
1219 N->p[i] = 0;
1220
1221 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001222 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001223
1224cleanup:
1225 return( ret );
1226}
1227
1228#undef P521_WIDTH
1229#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001233
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001234#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001236/* Size of p255 in terms of mbedtls_mpi_uint */
1237#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001238
1239/*
1240 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001241 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001242 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001244{
1245 int ret;
1246 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001247 mbedtls_mpi M;
1248 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001249
1250 if( N->n < P255_WIDTH )
1251 return( 0 );
1252
1253 /* M = A1 */
1254 M.s = 1;
1255 M.n = N->n - ( P255_WIDTH - 1 );
1256 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001257 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001258 M.p = Mp;
1259 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001260 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1261 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001262 M.n++; /* Make room for multiplication by 19 */
1263
1264 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001265 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001266 for( i = P255_WIDTH; i < N->n; i++ )
1267 N->p[i] = 0;
1268
1269 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1271 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001272
1273cleanup:
1274 return( ret );
1275}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001276#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001277
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001278#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1279
1280/* Size of p448 in terms of mbedtls_mpi_uint */
1281#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1282
1283/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1284#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1285#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1286#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1287#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1288
1289/*
1290 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1291 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1292 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1293 * implementation of Curve448, which uses its own special 56-bit limbs rather
1294 * than a generic bignum library. We could squeeze some extra speed out on
1295 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1296 * arithmetic using the limbs directly as we do for the NIST primes above,
1297 * but for 64-bit targets it should use half the number of operations if we do
1298 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1299 */
1300static int ecp_mod_p448( mbedtls_mpi *N )
1301{
1302 int ret;
1303 size_t i;
1304 mbedtls_mpi M, Q;
1305 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1306
1307 if( N->n <= P448_WIDTH )
1308 return( 0 );
1309
1310 /* M = A1 */
1311 M.s = 1;
1312 M.n = N->n - ( P448_WIDTH );
1313 if( M.n > P448_WIDTH )
1314 /* Shouldn't be called with N larger than 2^896! */
1315 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1316 M.p = Mp;
1317 memset( Mp, 0, sizeof( Mp ) );
1318 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1319
1320 /* N = A0 */
1321 for( i = P448_WIDTH; i < N->n; i++ )
1322 N->p[i] = 0;
1323
1324 /* N += A1 */
1325 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1326
1327 /* Q = B1, N += B1 */
1328 Q = M;
1329 Q.p = Qp;
1330 memcpy( Qp, Mp, sizeof( Qp ) );
1331 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1332 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1333
1334 /* M = (B0 + B1) * 2^224, N += M */
1335 if( sizeof( mbedtls_mpi_uint ) > 4 )
1336 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1337 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1338 Mp[i] = 0;
1339 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1340 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1341 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1342 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1343
1344cleanup:
1345 return( ret );
1346}
1347#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001349#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1350 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1351 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001352/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001353 * Fast quasi-reduction modulo P = 2^s - R,
1354 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001355 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001356 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001357 * Actually do two passes, since R is big.
1358 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1360#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1361static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1362 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001363{
1364 int ret;
1365 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001366 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001367 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001368
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001369 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001370 return( 0 );
1371
1372 /* Init R */
1373 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001374 R.p = Rp;
1375 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001376
1377 /* Common setup for M */
1378 M.s = 1;
1379 M.p = Mp;
1380
1381 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001382 M.n = N->n - ( p_limbs - adjust );
1383 if( M.n > p_limbs + adjust )
1384 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001385 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001386 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001387 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001389 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001390
1391 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001392 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001393 N->p[p_limbs - 1] &= mask;
1394 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001395 N->p[i] = 0;
1396
1397 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001398 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1399 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001400
1401 /* Second pass */
1402
1403 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001404 M.n = N->n - ( p_limbs - adjust );
1405 if( M.n > p_limbs + adjust )
1406 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001407 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001408 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001409 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001410 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001411 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001412
1413 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001414 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001415 N->p[p_limbs - 1] &= mask;
1416 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001417 N->p[i] = 0;
1418
1419 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1421 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001422
1423cleanup:
1424 return( ret );
1425}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001426#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1427 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1428 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001431/*
1432 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1433 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1434 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001436{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437 static mbedtls_mpi_uint Rp[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +01001438 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
1439 0x00 ) };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001440
Janos Follath9a64d3e2021-06-25 12:43:26 +01001441 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1442 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001443}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001446#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001447/*
1448 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1449 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1450 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001451static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001452{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453 static mbedtls_mpi_uint Rp[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +01001454 MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
1455 0x00 ) };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001456
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001457#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001458 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1459#else
Janos Follath9a64d3e2021-06-25 12:43:26 +01001460 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1461 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001462#endif
1463}
1464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001468/*
1469 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1470 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1471 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001473{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001474 static mbedtls_mpi_uint Rp[] = {
Janos Follath9a64d3e2021-06-25 12:43:26 +01001475 MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
1476 0x00 ) };
1477 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1478 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001479}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001481
Janos Follathb0697532016-08-18 12:38:46 +01001482#endif /* !MBEDTLS_ECP_ALT */
1483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484#endif /* MBEDTLS_ECP_C */