blob: 4671e756241e96ecca33ace5b07fad728b79de7e [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"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010057
Rich Evans00ab4702015-02-06 13:43:58 +000058#include <string.h>
59
Janos Follathb0697532016-08-18 12:38:46 +010060#if !defined(MBEDTLS_ECP_ALT)
61
Hanno Becker4f8e8e52018-12-14 15:08:03 +000062/* Parameter validation macros based on platform_util.h */
63#define ECP_VALIDATE_RET( cond ) \
64 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
65#define ECP_VALIDATE( cond ) \
66 MBEDTLS_INTERNAL_VALIDATE( cond )
67
Manuel Pégourié-Gonnard0223ab92015-10-05 11:40:01 +010068#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
69 !defined(inline) && !defined(__cplusplus)
Paul Bakker498fd352013-12-02 22:17:24 +010070#define inline __inline
Manuel Pégourié-Gonnard20af64d2015-07-07 18:33:39 +020071#endif
Paul Bakker498fd352013-12-02 22:17:24 +010072
Manuel Pégourié-Gonnardbaee5d42013-12-06 13:38:41 +010073/*
74 * Conversion macros for embedded constants:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075 * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
Manuel Pégourié-Gonnardbaee5d42013-12-06 13:38:41 +010076 */
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +020077#if defined(MBEDTLS_HAVE_INT32)
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010078
Hanno Beckerd6028a12018-10-15 12:01:35 +010079#define BYTES_TO_T_UINT_4( a, b, c, d ) \
80 ( (mbedtls_mpi_uint) (a) << 0 ) | \
81 ( (mbedtls_mpi_uint) (b) << 8 ) | \
82 ( (mbedtls_mpi_uint) (c) << 16 ) | \
83 ( (mbedtls_mpi_uint) (d) << 24 )
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010084
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010085#define BYTES_TO_T_UINT_2( a, b ) \
86 BYTES_TO_T_UINT_4( a, b, 0, 0 )
87
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010088#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
Manuel Pégourié-Gonnard69ab3542013-12-12 15:50:08 +010089 BYTES_TO_T_UINT_4( a, b, c, d ), \
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010090 BYTES_TO_T_UINT_4( e, f, g, h )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010091
92#else /* 64-bits */
93
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010094#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
Hanno Beckerd6028a12018-10-15 12:01:35 +010095 ( (mbedtls_mpi_uint) (a) << 0 ) | \
96 ( (mbedtls_mpi_uint) (b) << 8 ) | \
97 ( (mbedtls_mpi_uint) (c) << 16 ) | \
98 ( (mbedtls_mpi_uint) (d) << 24 ) | \
99 ( (mbedtls_mpi_uint) (e) << 32 ) | \
100 ( (mbedtls_mpi_uint) (f) << 40 ) | \
101 ( (mbedtls_mpi_uint) (g) << 48 ) | \
102 ( (mbedtls_mpi_uint) (h) << 56 )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100103
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100104#define BYTES_TO_T_UINT_4( a, b, c, d ) \
105 BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
106
107#define BYTES_TO_T_UINT_2( a, b ) \
108 BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110#endif /* bits in mbedtls_mpi_uint */
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100111
Manuel Pégourié-Gonnard6ec15352021-06-23 12:25:48 +0200112#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
113
114#define ECP_MPI_INIT_ARRAY(x) \
115 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
116
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100117/*
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100118 * Note: the constants are in little-endian order
119 * to be directly usable in MPIs
120 */
121
122/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100123 * Domain parameters for secp192r1
124 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
126static const mbedtls_mpi_uint secp192r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100127 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
128 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
129 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100130};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131static const mbedtls_mpi_uint secp192r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100132 BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
133 BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
134 BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100135};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200136static const mbedtls_mpi_uint secp192r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100137 BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
138 BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
139 BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100140};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141static const mbedtls_mpi_uint secp192r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100142 BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
143 BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
144 BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100145};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146static const mbedtls_mpi_uint secp192r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100147 BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
148 BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
149 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100150};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100152
153/*
154 * Domain parameters for secp224r1
155 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
157static const mbedtls_mpi_uint secp224r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100158 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
159 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
160 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
161 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100162};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163static const mbedtls_mpi_uint secp224r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100164 BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
165 BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
166 BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100167 BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100168};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169static const mbedtls_mpi_uint secp224r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100170 BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
171 BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
172 BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100173 BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100174};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175static const mbedtls_mpi_uint secp224r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100176 BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
177 BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
178 BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100179 BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100180};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181static const mbedtls_mpi_uint secp224r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100182 BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
183 BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
184 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100185 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100186};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100188
189/*
190 * Domain parameters for secp256r1
191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
193static const mbedtls_mpi_uint secp256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100194 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
195 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
196 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
197 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 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 secp256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100200 BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
201 BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
202 BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
203 BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100204};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205static const mbedtls_mpi_uint secp256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100206 BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
207 BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
208 BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
209 BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100210};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211static const mbedtls_mpi_uint secp256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100212 BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
213 BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
214 BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
215 BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100216};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217static const mbedtls_mpi_uint secp256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100218 BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
219 BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
220 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
221 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100222};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100224
225/*
226 * Domain parameters for secp384r1
227 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200228#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
229static const mbedtls_mpi_uint secp384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100230 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
231 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
232 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
233 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
234 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
235 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100236};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237static const mbedtls_mpi_uint secp384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100238 BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
239 BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
240 BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
241 BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
242 BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
243 BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100244};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200245static const mbedtls_mpi_uint secp384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100246 BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
247 BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
248 BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
249 BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
250 BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
251 BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100252};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253static const mbedtls_mpi_uint secp384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100254 BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
255 BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
256 BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
257 BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
258 BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
259 BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100260};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261static const mbedtls_mpi_uint secp384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100262 BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
263 BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
264 BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
265 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
266 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
267 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100268};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100270
271/*
272 * Domain parameters for secp521r1
273 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
275static const mbedtls_mpi_uint secp521r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100276 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
277 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
278 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
279 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
280 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
281 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
282 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
283 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100284 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100285};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286static const mbedtls_mpi_uint secp521r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100287 BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
288 BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
289 BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
290 BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
291 BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
292 BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
293 BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
294 BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100295 BYTES_TO_T_UINT_2( 0x51, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100296};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297static const mbedtls_mpi_uint secp521r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100298 BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
299 BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
300 BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
301 BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
302 BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
303 BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
304 BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
305 BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100306 BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100307};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308static const mbedtls_mpi_uint secp521r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100309 BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
310 BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
311 BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
312 BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
313 BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
314 BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
315 BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
316 BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100317 BYTES_TO_T_UINT_2( 0x18, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100318};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319static const mbedtls_mpi_uint secp521r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100320 BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
321 BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
322 BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
323 BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
324 BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
325 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
326 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
327 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100328 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100329};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100331
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
333static const mbedtls_mpi_uint secp192k1_p[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100334 BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
335 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
336 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
337};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338static const mbedtls_mpi_uint secp192k1_a[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100339 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
340};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341static const mbedtls_mpi_uint secp192k1_b[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100342 BYTES_TO_T_UINT_2( 0x03, 0x00 ),
343};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344static const mbedtls_mpi_uint secp192k1_gx[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100345 BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
346 BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
347 BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
348};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349static const mbedtls_mpi_uint secp192k1_gy[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100350 BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
351 BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
352 BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
353};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354static const mbedtls_mpi_uint secp192k1_n[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100355 BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
356 BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
357 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
358};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
362static const mbedtls_mpi_uint secp224k1_p[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100363 BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
364 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
365 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
366 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
367};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368static const mbedtls_mpi_uint secp224k1_a[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100369 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
370};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371static const mbedtls_mpi_uint secp224k1_b[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100372 BYTES_TO_T_UINT_2( 0x05, 0x00 ),
373};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374static const mbedtls_mpi_uint secp224k1_gx[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100375 BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
376 BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
377 BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
378 BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
379};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380static const mbedtls_mpi_uint secp224k1_gy[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100381 BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
382 BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
383 BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
384 BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
385};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386static const mbedtls_mpi_uint secp224k1_n[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100387 BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
388 BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
389 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
390 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
391};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
395static const mbedtls_mpi_uint secp256k1_p[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100396 BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
397 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
398 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
399 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
400};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401static const mbedtls_mpi_uint secp256k1_a[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100402 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
403};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404static const mbedtls_mpi_uint secp256k1_b[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100405 BYTES_TO_T_UINT_2( 0x07, 0x00 ),
406};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407static const mbedtls_mpi_uint secp256k1_gx[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100408 BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
409 BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
410 BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
411 BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
412};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413static const mbedtls_mpi_uint secp256k1_gy[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100414 BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
415 BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
416 BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
417 BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
418};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419static const mbedtls_mpi_uint secp256k1_n[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100420 BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
421 BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
422 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
423 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
424};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100426
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100427/*
428 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
429 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
431static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100432 BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
433 BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
434 BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
435 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100436};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100438 BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
439 BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
440 BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
441 BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100442};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100444 BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
445 BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
446 BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
447 BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100448};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100450 BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
451 BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
452 BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
453 BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100454};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100456 BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
457 BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
458 BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
459 BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100460};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100462 BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
463 BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
464 BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
465 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100466};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100468
469/*
470 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
471 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
473static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100474 BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
475 BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
476 BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
477 BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
478 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
479 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100480};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100482 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
483 BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
484 BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
485 BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
486 BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
487 BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100488};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100490 BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
491 BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
492 BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
493 BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
494 BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
495 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100496};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100498 BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
499 BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
500 BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
501 BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
502 BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
503 BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100504};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100506 BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
507 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
508 BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
509 BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
510 BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
511 BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100512};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200513static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100514 BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
515 BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
516 BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
517 BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
518 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
519 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100520};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100522
523/*
524 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
525 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
527static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100528 BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
529 BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
530 BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
531 BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
532 BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
533 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
534 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
535 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100536};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100538 BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
539 BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
540 BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
541 BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
542 BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
543 BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
544 BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
545 BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100546};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100548 BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
549 BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
550 BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
551 BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
552 BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
553 BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
554 BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
555 BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100556};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100558 BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
559 BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
560 BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
561 BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
562 BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
563 BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
564 BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
565 BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100566};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100568 BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
569 BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
570 BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
571 BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
572 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
573 BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
574 BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
575 BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100576};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100578 BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
579 BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
580 BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
581 BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
582 BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
583 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
584 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
585 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100586};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100588
589/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100590 * Create an MPI from embedded constants
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100592 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593static 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 +0100594{
595 X->s = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 X->n = len / sizeof( mbedtls_mpi_uint );
597 X->p = (mbedtls_mpi_uint *) p;
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100598}
599
600/*
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100601 * Set an MPI to static value 1
602 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603static inline void ecp_mpi_set1( mbedtls_mpi *X )
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100604{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 static mbedtls_mpi_uint one[] = { 1 };
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100606 X->s = 1;
607 X->n = 1;
608 X->p = one;
609}
610
611/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100612 * Make group available from embedded constants
613 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614static int ecp_group_load( mbedtls_ecp_group *grp,
615 const mbedtls_mpi_uint *p, size_t plen,
616 const mbedtls_mpi_uint *a, size_t alen,
617 const mbedtls_mpi_uint *b, size_t blen,
618 const mbedtls_mpi_uint *gx, size_t gxlen,
619 const mbedtls_mpi_uint *gy, size_t gylen,
620 const mbedtls_mpi_uint *n, size_t nlen)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100621{
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100622 ecp_mpi_load( &grp->P, p, plen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100623 if( a != NULL )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100624 ecp_mpi_load( &grp->A, a, alen );
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100625 ecp_mpi_load( &grp->B, b, blen );
626 ecp_mpi_load( &grp->N, n, nlen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100627
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100628 ecp_mpi_load( &grp->G.X, gx, gxlen );
629 ecp_mpi_load( &grp->G.Y, gy, gylen );
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100630 ecp_mpi_set1( &grp->G.Z );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100631
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200632 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
633 grp->nbits = mbedtls_mpi_bitlen( &grp->N );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100634
Manuel Pégourié-Gonnard1f82b042013-12-06 12:51:50 +0100635 grp->h = 1;
636
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100637 return( 0 );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100638}
639
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100641/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
643static int ecp_mod_p192( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100644#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
646static int ecp_mod_p224( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100647#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
649static int ecp_mod_p256( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100650#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
652static int ecp_mod_p384( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100653#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
655static int ecp_mod_p521( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100656#endif
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100657
658#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
659#else
660#define NIST_MODP( P )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100662
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100663/* Additional forward declarations */
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200664#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665static int ecp_mod_p255( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100666#endif
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000667#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
668static int ecp_mod_p448( mbedtls_mpi * );
669#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200670#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
671static int ecp_mod_p192k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100672#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
674static int ecp_mod_p224k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100675#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
677static int ecp_mod_p256k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100678#endif
679
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100680#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
681 G ## _p, sizeof( G ## _p ), \
682 G ## _a, sizeof( G ## _a ), \
683 G ## _b, sizeof( G ## _b ), \
684 G ## _gx, sizeof( G ## _gx ), \
685 G ## _gy, sizeof( G ## _gy ), \
686 G ## _n, sizeof( G ## _n ) )
687
688#define LOAD_GROUP( G ) ecp_group_load( grp, \
689 G ## _p, sizeof( G ## _p ), \
690 NULL, 0, \
691 G ## _b, sizeof( G ## _b ), \
692 G ## _gx, sizeof( G ## _gx ), \
693 G ## _gy, sizeof( G ## _gy ), \
694 G ## _n, sizeof( G ## _n ) )
695
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200696#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200697/* Constants used by ecp_use_curve25519() */
698static const unsigned char curve25519_a24[] = { 0x01, 0xDB, 0x42 };
699static const unsigned char curve25519_part_of_n[] = {
700 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
701 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
702};
703
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100704/*
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100705 * Specialized function for creating the Curve25519 group
706 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707static int ecp_use_curve25519( mbedtls_ecp_group *grp )
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100708{
709 int ret;
710
711 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200712 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
713 curve25519_a24, sizeof( curve25519_a24 ) ) );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100714
715 /* P = 2^255 - 19 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
717 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
718 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200719 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100720
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100721 /* N = 2^252 + 27742317777372353535851937790883648493 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200722 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
723 curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100724 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
725
Manuel Pégourié-Gonnard18b78432018-03-28 11:14:06 +0200726 /* Y intentionally not set, since we use x/z coordinates.
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100727 * This is used as a marker to identify Montgomery curves! */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
729 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
730 mbedtls_mpi_free( &grp->G.Y );
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100731
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100732 /* Actually, the required msb for private keys */
733 grp->nbits = 254;
734
735cleanup:
736 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100738
739 return( ret );
740}
Manuel Pégourié-Gonnard6ec15352021-06-23 12:25:48 +0200741
742/*
743 * Constants for the two points other than 0, 1, -1 (mod p) in
744 * https://cr.yp.to/ecdh.html#validate
745 * See ecp_check_pubkey_x25519().
746 */
747static const mbedtls_mpi_uint x25519_bad_point_1[] = {
748 BYTES_TO_T_UINT_8( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae ),
749 BYTES_TO_T_UINT_8( 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a ),
750 BYTES_TO_T_UINT_8( 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd ),
751 BYTES_TO_T_UINT_8( 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ),
752};
753static const mbedtls_mpi_uint x25519_bad_point_2[] = {
754 BYTES_TO_T_UINT_8( 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24 ),
755 BYTES_TO_T_UINT_8( 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b ),
756 BYTES_TO_T_UINT_8( 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86 ),
757 BYTES_TO_T_UINT_8( 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ),
758};
759const mbedtls_mpi mbedtls_ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY(
760 x25519_bad_point_1 );
761const mbedtls_mpi mbedtls_ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY(
762 x25519_bad_point_2 );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200763#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100764
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000765#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200766/* Constants used by ecp_use_curve448() */
767static const unsigned char curve448_a24[] = { 0x98, 0xAA };
768static const unsigned char curve448_part_of_n[] = {
769 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
770 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
771 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
772 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
773};
774
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000775/*
776 * Specialized function for creating the Curve448 group
777 */
778static int ecp_use_curve448( mbedtls_ecp_group *grp )
779{
780 mbedtls_mpi Ns;
781 int ret;
782
783 mbedtls_mpi_init( &Ns );
784
785 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200786 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
787 curve448_a24, sizeof( curve448_a24 ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000788
789 /* P = 2^448 - 2^224 - 1 */
790 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
791 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
792 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
793 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
794 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
795 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
796
797 /* Y intentionally not set, since we use x/z coordinates.
798 * This is used as a marker to identify Montgomery curves! */
799 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
800 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
801 mbedtls_mpi_free( &grp->G.Y );
802
803 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
804 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200805 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
806 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000807 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
808
809 /* Actually, the required msb for private keys */
810 grp->nbits = 447;
811
812cleanup:
813 mbedtls_mpi_free( &Ns );
814 if( ret != 0 )
815 mbedtls_ecp_group_free( grp );
816
817 return( ret );
818}
819#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
820
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100821/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100822 * Set a group using well-known domain parameters
823 */
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200824int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100825{
Hanno Becker4f8e8e52018-12-14 15:08:03 +0000826 ECP_VALIDATE_RET( grp != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100828
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100829 grp->id = id;
830
831 switch( id )
832 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
834 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100835 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100836 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100838
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
840 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100841 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100842 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
846 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100847 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100848 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100850
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
852 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100853 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100854 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100856
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
858 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100859 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100860 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200861#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100862
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
864 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100865 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100866 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100868
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
870 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100871 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100872 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
876 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100877 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100878 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100880
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
882 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100883 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200886#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
887 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100888 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
892 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100893 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100895
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200896#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
897 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100898 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100899 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200900#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100901
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000902#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
903 case MBEDTLS_ECP_DP_CURVE448:
904 grp->modp = ecp_mod_p448;
905 return( ecp_use_curve448( grp ) );
906#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
907
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100908 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 mbedtls_ecp_group_free( grp );
910 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100911 }
912}
913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100915/*
916 * Fast reduction modulo the primes used by the NIST curves.
917 *
918 * These functions are critical for speed, but not needed for correct
919 * operations. So, we make the choice to heavily rely on the internals of our
920 * bignum library, which creates a tight coupling between these functions and
921 * our MPI implementation. However, the coupling between the ECP module and
922 * MPI remains loose, since these functions can be deactivated at will.
923 */
924
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100926/*
927 * Compared to the way things are presented in FIPS 186-3 D.2,
928 * we proceed in columns, from right (least significant chunk) to left,
929 * adding chunks to N in place, and keeping a carry for the next chunk.
930 * This avoids moving things around in memory, and uselessly adding zeros,
931 * compared to the more straightforward, line-oriented approach.
932 *
933 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200934 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
935 * 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 +0100936 */
937
938/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100940{
941 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942 mbedtls_mpi_uint c = 0;
943 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100944 {
945 *dst += c; c = ( *dst < c );
946 *dst += *src; c += ( *dst < *src );
947 }
948 *carry += c;
949}
950
951/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100953{
954 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100956 {
957 *dst += *carry;
958 *carry = ( *dst < *carry );
959 }
960}
961
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Beckerd6028a12018-10-15 12:01:35 +0100963#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100964#define ADD( i ) add64( p, A( i ), &c )
965#define NEXT p += WIDTH; carry64( p, &c )
966#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
967
968/*
969 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
970 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100972{
973 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 mbedtls_mpi_uint c = 0;
975 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100976
977 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100979
980 p = N->p;
981 end = p + N->n;
982
983 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
984 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
985 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
986
987cleanup:
988 return( ret );
989}
990
991#undef WIDTH
992#undef A
993#undef ADD
994#undef NEXT
995#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100997
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
999 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
1000 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001001/*
1002 * The reader is advised to first understand ecp_mod_p192() since the same
1003 * general structure is used here, but with additional complications:
1004 * (1) chunks of 32 bits, and (2) subtractions.
1005 */
1006
1007/*
1008 * For these primes, we need to handle data in chunks of 32 bits.
1009 * This makes it more complicated if we use 64 bits limbs in MPI,
1010 * which prevents us from using a uniform access method as for p192.
1011 *
1012 * So, we define a mini abstraction layer to access 32 bit chunks,
1013 * load them in 'cur' for work, and store them back from 'cur' when done.
1014 *
1015 * While at it, also define the size of N in terms of 32-bit chunks.
1016 */
1017#define LOAD32 cur = A( i );
1018
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +02001019#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001020
1021#define MAX32 N->n
1022#define A( j ) N->p[j]
1023#define STORE32 N->p[i] = cur;
1024
1025#else /* 64-bit */
1026
1027#define MAX32 N->n * 2
Hanno Beckerd6028a12018-10-15 12:01:35 +01001028#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
1029 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001030#define STORE32 \
1031 if( i % 2 ) { \
1032 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001034 } else { \
1035 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001037 }
1038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001040
1041/*
1042 * Helpers for addition and subtraction of chunks, with signed carry.
1043 */
1044static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
1045{
1046 *dst += src;
1047 *carry += ( *dst < src );
1048}
1049
1050static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
1051{
1052 *carry -= ( *dst < src );
1053 *dst -= src;
1054}
1055
1056#define ADD( j ) add32( &cur, A( j ), &c );
1057#define SUB( j ) sub32( &cur, A( j ), &c );
1058
1059/*
1060 * Helpers for the main 'loop'
1061 * (see fix_negative for the motivation of C)
1062 */
Hanno Beckerd6028a12018-10-15 12:01:35 +01001063#define INIT( b ) \
1064 int ret; \
1065 signed char c = 0, cc; \
1066 uint32_t cur; \
1067 size_t i = 0, bits = (b); \
1068 mbedtls_mpi C; \
1069 mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
1070 \
1071 C.s = 1; \
1072 C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \
1073 C.p = Cp; \
1074 memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
1075 \
1076 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \
1077 sizeof( mbedtls_mpi_uint ) ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001078 LOAD32;
1079
1080#define NEXT \
1081 STORE32; i++; LOAD32; \
1082 cc = c; c = 0; \
1083 if( cc < 0 ) \
1084 sub32( &cur, -cc, &c ); \
1085 else \
1086 add32( &cur, cc, &c ); \
1087
1088#define LAST \
1089 STORE32; i++; \
1090 cur = c > 0 ? c : 0; STORE32; \
1091 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine7d6326d2020-07-23 01:14:34 +02001092 if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001093
1094/*
1095 * If the result is negative, we get it in the form
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001096 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001097 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098static 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 +01001099{
1100 int ret;
1101
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001102 /* C = - c * 2^bits */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103#if !defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001104 ((void) bits);
1105#else
1106 if( bits == 224 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107 C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001108 else
1109#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001110 C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001111
1112 /* N = - ( C - N ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001114 N->s = -1;
1115
1116cleanup:
1117
1118 return( ret );
1119}
1120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001122/*
1123 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1124 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001125static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001126{
1127 INIT( 224 );
1128
1129 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1130 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1131 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1132 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1133 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1134 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1135 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1136
1137cleanup:
1138 return( ret );
1139}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001142#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001143/*
1144 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1145 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001147{
1148 INIT( 256 );
1149
1150 ADD( 8 ); ADD( 9 );
1151 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1152
1153 ADD( 9 ); ADD( 10 );
1154 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1155
1156 ADD( 10 ); ADD( 11 );
1157 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1158
1159 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1160 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1161
1162 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1163 SUB( 9 ); SUB( 10 ); NEXT; // A4
1164
1165 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1166 SUB( 10 ); SUB( 11 ); NEXT; // A5
1167
1168 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1169 SUB( 8 ); SUB( 9 ); NEXT; // A6
1170
1171 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1172 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1173
1174cleanup:
1175 return( ret );
1176}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001177#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001178
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001179#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001180/*
1181 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1182 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001183static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001184{
1185 INIT( 384 );
1186
1187 ADD( 12 ); ADD( 21 ); ADD( 20 );
1188 SUB( 23 ); NEXT; // A0
1189
1190 ADD( 13 ); ADD( 22 ); ADD( 23 );
1191 SUB( 12 ); SUB( 20 ); NEXT; // A2
1192
1193 ADD( 14 ); ADD( 23 );
1194 SUB( 13 ); SUB( 21 ); NEXT; // A2
1195
1196 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1197 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1198
1199 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1200 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1201
1202 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1203 SUB( 16 ); NEXT; // A5
1204
1205 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1206 SUB( 17 ); NEXT; // A6
1207
1208 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1209 SUB( 18 ); NEXT; // A7
1210
1211 ADD( 20 ); ADD( 17 ); ADD( 16 );
1212 SUB( 19 ); NEXT; // A8
1213
1214 ADD( 21 ); ADD( 18 ); ADD( 17 );
1215 SUB( 20 ); NEXT; // A9
1216
1217 ADD( 22 ); ADD( 19 ); ADD( 18 );
1218 SUB( 21 ); NEXT; // A10
1219
1220 ADD( 23 ); ADD( 20 ); ADD( 19 );
1221 SUB( 22 ); LAST; // A11
1222
1223cleanup:
1224 return( ret );
1225}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001226#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001227
1228#undef A
1229#undef LOAD32
1230#undef STORE32
1231#undef MAX32
1232#undef INIT
1233#undef NEXT
1234#undef LAST
1235
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001236#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1237 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1238 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001240#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001241/*
1242 * Here we have an actual Mersenne prime, so things are more straightforward.
1243 * However, chunks are aligned on a 'weird' boundary (521 bits).
1244 */
1245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001246/* Size of p521 in terms of mbedtls_mpi_uint */
1247#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001248
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001249/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001250#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001251
1252/*
1253 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1254 * Write N as A1 + 2^521 A0, return A0 + A1
1255 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001256static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001257{
1258 int ret;
1259 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001260 mbedtls_mpi M;
1261 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1262 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001263 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1264 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1265
1266 if( N->n < P521_WIDTH )
1267 return( 0 );
1268
1269 /* M = A1 */
1270 M.s = 1;
1271 M.n = N->n - ( P521_WIDTH - 1 );
1272 if( M.n > P521_WIDTH + 1 )
1273 M.n = P521_WIDTH + 1;
1274 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001275 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1276 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001277
1278 /* N = A0 */
1279 N->p[P521_WIDTH - 1] &= P521_MASK;
1280 for( i = P521_WIDTH; i < N->n; i++ )
1281 N->p[i] = 0;
1282
1283 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001284 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001285
1286cleanup:
1287 return( ret );
1288}
1289
1290#undef P521_WIDTH
1291#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001295
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001296#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001297
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001298/* Size of p255 in terms of mbedtls_mpi_uint */
1299#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001300
1301/*
1302 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001303 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001304 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001305static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001306{
1307 int ret;
1308 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001309 mbedtls_mpi M;
1310 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001311
1312 if( N->n < P255_WIDTH )
1313 return( 0 );
1314
1315 /* M = A1 */
1316 M.s = 1;
1317 M.n = N->n - ( P255_WIDTH - 1 );
1318 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001319 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001320 M.p = Mp;
1321 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001322 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1323 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001324 M.n++; /* Make room for multiplication by 19 */
1325
1326 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001327 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001328 for( i = P255_WIDTH; i < N->n; i++ )
1329 N->p[i] = 0;
1330
1331 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001332 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1333 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001334
1335cleanup:
1336 return( ret );
1337}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001338#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001339
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001340#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1341
1342/* Size of p448 in terms of mbedtls_mpi_uint */
1343#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1344
1345/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1346#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1347#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1348#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1349#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1350
1351/*
1352 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1353 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1354 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1355 * implementation of Curve448, which uses its own special 56-bit limbs rather
1356 * than a generic bignum library. We could squeeze some extra speed out on
1357 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1358 * arithmetic using the limbs directly as we do for the NIST primes above,
1359 * but for 64-bit targets it should use half the number of operations if we do
1360 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1361 */
1362static int ecp_mod_p448( mbedtls_mpi *N )
1363{
1364 int ret;
1365 size_t i;
1366 mbedtls_mpi M, Q;
1367 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1368
1369 if( N->n <= P448_WIDTH )
1370 return( 0 );
1371
1372 /* M = A1 */
1373 M.s = 1;
1374 M.n = N->n - ( P448_WIDTH );
1375 if( M.n > P448_WIDTH )
1376 /* Shouldn't be called with N larger than 2^896! */
1377 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1378 M.p = Mp;
1379 memset( Mp, 0, sizeof( Mp ) );
1380 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1381
1382 /* N = A0 */
1383 for( i = P448_WIDTH; i < N->n; i++ )
1384 N->p[i] = 0;
1385
1386 /* N += A1 */
1387 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1388
1389 /* Q = B1, N += B1 */
1390 Q = M;
1391 Q.p = Qp;
1392 memcpy( Qp, Mp, sizeof( Qp ) );
1393 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1394 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1395
1396 /* M = (B0 + B1) * 2^224, N += M */
1397 if( sizeof( mbedtls_mpi_uint ) > 4 )
1398 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1399 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1400 Mp[i] = 0;
1401 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1402 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1403 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1404 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1405
1406cleanup:
1407 return( ret );
1408}
1409#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1412 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1413 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001414/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001415 * Fast quasi-reduction modulo P = 2^s - R,
1416 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001417 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001418 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001419 * Actually do two passes, since R is big.
1420 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001421#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1422#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1423static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1424 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001425{
1426 int ret;
1427 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001428 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001429 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001430
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001431 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001432 return( 0 );
1433
1434 /* Init R */
1435 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001436 R.p = Rp;
1437 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001438
1439 /* Common setup for M */
1440 M.s = 1;
1441 M.p = Mp;
1442
1443 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001444 M.n = N->n - ( p_limbs - adjust );
1445 if( M.n > p_limbs + adjust )
1446 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001447 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001449 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001450 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001451 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001452
1453 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001454 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001455 N->p[p_limbs - 1] &= mask;
1456 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001457 N->p[i] = 0;
1458
1459 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001460 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1461 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001462
1463 /* Second pass */
1464
1465 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001466 M.n = N->n - ( p_limbs - adjust );
1467 if( M.n > p_limbs + adjust )
1468 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001469 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001471 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001473 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001474
1475 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001476 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001477 N->p[p_limbs - 1] &= mask;
1478 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001479 N->p[i] = 0;
1480
1481 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1483 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001484
1485cleanup:
1486 return( ret );
1487}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001488#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1489 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1490 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001493/*
1494 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1495 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1496 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001498{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001499 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001500 BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001503}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001505
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001507/*
1508 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1509 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1510 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001511static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001512{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001514 BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001517 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1518#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001520#endif
1521}
1522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001526/*
1527 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1528 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1529 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001531{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001532 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001533 BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001535}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001536#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001537
Janos Follathb0697532016-08-18 12:38:46 +01001538#endif /* !MBEDTLS_ECP_ALT */
1539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540#endif /* MBEDTLS_ECP_C */