blob: 00bb895092c21da7a12f289f052db23d4160d451 [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é-Gonnard07894332015-06-23 00:18:41 +0200741#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100742
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000743#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200744/* Constants used by ecp_use_curve448() */
745static const unsigned char curve448_a24[] = { 0x98, 0xAA };
746static const unsigned char curve448_part_of_n[] = {
747 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
748 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
749 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
750 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
751};
752
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000753/*
754 * Specialized function for creating the Curve448 group
755 */
756static int ecp_use_curve448( mbedtls_ecp_group *grp )
757{
758 mbedtls_mpi Ns;
759 int ret;
760
761 mbedtls_mpi_init( &Ns );
762
763 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200764 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
765 curve448_a24, sizeof( curve448_a24 ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000766
767 /* P = 2^448 - 2^224 - 1 */
768 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
769 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
770 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
771 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
772 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
773 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
774
775 /* Y intentionally not set, since we use x/z coordinates.
776 * This is used as a marker to identify Montgomery curves! */
777 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
778 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
779 mbedtls_mpi_free( &grp->G.Y );
780
781 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
782 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200783 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
784 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000785 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
786
787 /* Actually, the required msb for private keys */
788 grp->nbits = 447;
789
790cleanup:
791 mbedtls_mpi_free( &Ns );
792 if( ret != 0 )
793 mbedtls_ecp_group_free( grp );
794
795 return( ret );
796}
797#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
798
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100799/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100800 * Set a group using well-known domain parameters
801 */
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200802int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100803{
Hanno Becker4f8e8e52018-12-14 15:08:03 +0000804 ECP_VALIDATE_RET( grp != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100806
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100807 grp->id = id;
808
809 switch( id )
810 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
812 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100813 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100814 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100816
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
818 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100819 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100820 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100822
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
824 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100825 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100826 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100828
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
830 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100831 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100832 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100834
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200835#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
836 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100837 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100838 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100840
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
842 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100843 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100844 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
848 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100849 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100850 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100852
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
854 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100855 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100856 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100858
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
860 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100861 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100863
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
865 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100866 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100868
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
870 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100871 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100873
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200874#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
875 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100876 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100877 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200878#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100879
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000880#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
881 case MBEDTLS_ECP_DP_CURVE448:
882 grp->modp = ecp_mod_p448;
883 return( ecp_use_curve448( grp ) );
884#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
885
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100886 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200887 mbedtls_ecp_group_free( grp );
888 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100889 }
890}
891
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100893/*
894 * Fast reduction modulo the primes used by the NIST curves.
895 *
896 * These functions are critical for speed, but not needed for correct
897 * operations. So, we make the choice to heavily rely on the internals of our
898 * bignum library, which creates a tight coupling between these functions and
899 * our MPI implementation. However, the coupling between the ECP module and
900 * MPI remains loose, since these functions can be deactivated at will.
901 */
902
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100904/*
905 * Compared to the way things are presented in FIPS 186-3 D.2,
906 * we proceed in columns, from right (least significant chunk) to left,
907 * adding chunks to N in place, and keeping a carry for the next chunk.
908 * This avoids moving things around in memory, and uselessly adding zeros,
909 * compared to the more straightforward, line-oriented approach.
910 *
911 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
913 * 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 +0100914 */
915
916/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200917static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100918{
919 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920 mbedtls_mpi_uint c = 0;
921 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100922 {
923 *dst += c; c = ( *dst < c );
924 *dst += *src; c += ( *dst < *src );
925 }
926 *carry += c;
927}
928
929/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100931{
932 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100934 {
935 *dst += *carry;
936 *carry = ( *dst < *carry );
937 }
938}
939
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Beckerd6028a12018-10-15 12:01:35 +0100941#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100942#define ADD( i ) add64( p, A( i ), &c )
943#define NEXT p += WIDTH; carry64( p, &c )
944#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
945
946/*
947 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
948 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100950{
951 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 mbedtls_mpi_uint c = 0;
953 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100954
955 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100957
958 p = N->p;
959 end = p + N->n;
960
961 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
962 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
963 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
964
965cleanup:
966 return( ret );
967}
968
969#undef WIDTH
970#undef A
971#undef ADD
972#undef NEXT
973#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100975
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
977 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
978 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100979/*
980 * The reader is advised to first understand ecp_mod_p192() since the same
981 * general structure is used here, but with additional complications:
982 * (1) chunks of 32 bits, and (2) subtractions.
983 */
984
985/*
986 * For these primes, we need to handle data in chunks of 32 bits.
987 * This makes it more complicated if we use 64 bits limbs in MPI,
988 * which prevents us from using a uniform access method as for p192.
989 *
990 * So, we define a mini abstraction layer to access 32 bit chunks,
991 * load them in 'cur' for work, and store them back from 'cur' when done.
992 *
993 * While at it, also define the size of N in terms of 32-bit chunks.
994 */
995#define LOAD32 cur = A( i );
996
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200997#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100998
999#define MAX32 N->n
1000#define A( j ) N->p[j]
1001#define STORE32 N->p[i] = cur;
1002
1003#else /* 64-bit */
1004
1005#define MAX32 N->n * 2
Hanno Beckerd6028a12018-10-15 12:01:35 +01001006#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
1007 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001008#define STORE32 \
1009 if( i % 2 ) { \
1010 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001011 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001012 } else { \
1013 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001015 }
1016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001018
1019/*
1020 * Helpers for addition and subtraction of chunks, with signed carry.
1021 */
1022static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
1023{
1024 *dst += src;
1025 *carry += ( *dst < src );
1026}
1027
1028static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
1029{
1030 *carry -= ( *dst < src );
1031 *dst -= src;
1032}
1033
1034#define ADD( j ) add32( &cur, A( j ), &c );
1035#define SUB( j ) sub32( &cur, A( j ), &c );
1036
1037/*
1038 * Helpers for the main 'loop'
1039 * (see fix_negative for the motivation of C)
1040 */
Hanno Beckerd6028a12018-10-15 12:01:35 +01001041#define INIT( b ) \
1042 int ret; \
1043 signed char c = 0, cc; \
1044 uint32_t cur; \
1045 size_t i = 0, bits = (b); \
1046 mbedtls_mpi C; \
1047 mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
1048 \
1049 C.s = 1; \
1050 C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \
1051 C.p = Cp; \
1052 memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
1053 \
1054 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \
1055 sizeof( mbedtls_mpi_uint ) ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001056 LOAD32;
1057
1058#define NEXT \
1059 STORE32; i++; LOAD32; \
1060 cc = c; c = 0; \
1061 if( cc < 0 ) \
1062 sub32( &cur, -cc, &c ); \
1063 else \
1064 add32( &cur, cc, &c ); \
1065
1066#define LAST \
1067 STORE32; i++; \
1068 cur = c > 0 ? c : 0; STORE32; \
1069 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine7d6326d2020-07-23 01:14:34 +02001070 if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001071
1072/*
1073 * If the result is negative, we get it in the form
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001074 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001075 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076static 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 +01001077{
1078 int ret;
1079
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001080 /* C = - c * 2^bits */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081#if !defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001082 ((void) bits);
1083#else
1084 if( bits == 224 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001086 else
1087#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001089
1090 /* N = - ( C - N ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001092 N->s = -1;
1093
1094cleanup:
1095
1096 return( ret );
1097}
1098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001100/*
1101 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1102 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001104{
1105 INIT( 224 );
1106
1107 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1108 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1109 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1110 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1111 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1112 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1113 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1114
1115cleanup:
1116 return( ret );
1117}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001121/*
1122 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1123 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001124static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001125{
1126 INIT( 256 );
1127
1128 ADD( 8 ); ADD( 9 );
1129 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1130
1131 ADD( 9 ); ADD( 10 );
1132 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1133
1134 ADD( 10 ); ADD( 11 );
1135 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1136
1137 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1138 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1139
1140 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1141 SUB( 9 ); SUB( 10 ); NEXT; // A4
1142
1143 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1144 SUB( 10 ); SUB( 11 ); NEXT; // A5
1145
1146 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1147 SUB( 8 ); SUB( 9 ); NEXT; // A6
1148
1149 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1150 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1151
1152cleanup:
1153 return( ret );
1154}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001158/*
1159 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1160 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001162{
1163 INIT( 384 );
1164
1165 ADD( 12 ); ADD( 21 ); ADD( 20 );
1166 SUB( 23 ); NEXT; // A0
1167
1168 ADD( 13 ); ADD( 22 ); ADD( 23 );
1169 SUB( 12 ); SUB( 20 ); NEXT; // A2
1170
1171 ADD( 14 ); ADD( 23 );
1172 SUB( 13 ); SUB( 21 ); NEXT; // A2
1173
1174 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1175 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1176
1177 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1178 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1179
1180 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1181 SUB( 16 ); NEXT; // A5
1182
1183 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1184 SUB( 17 ); NEXT; // A6
1185
1186 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1187 SUB( 18 ); NEXT; // A7
1188
1189 ADD( 20 ); ADD( 17 ); ADD( 16 );
1190 SUB( 19 ); NEXT; // A8
1191
1192 ADD( 21 ); ADD( 18 ); ADD( 17 );
1193 SUB( 20 ); NEXT; // A9
1194
1195 ADD( 22 ); ADD( 19 ); ADD( 18 );
1196 SUB( 21 ); NEXT; // A10
1197
1198 ADD( 23 ); ADD( 20 ); ADD( 19 );
1199 SUB( 22 ); LAST; // A11
1200
1201cleanup:
1202 return( ret );
1203}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001205
1206#undef A
1207#undef LOAD32
1208#undef STORE32
1209#undef MAX32
1210#undef INIT
1211#undef NEXT
1212#undef LAST
1213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001214#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1215 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1216 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001219/*
1220 * Here we have an actual Mersenne prime, so things are more straightforward.
1221 * However, chunks are aligned on a 'weird' boundary (521 bits).
1222 */
1223
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224/* Size of p521 in terms of mbedtls_mpi_uint */
1225#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001226
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001227/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001228#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001229
1230/*
1231 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1232 * Write N as A1 + 2^521 A0, return A0 + A1
1233 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001235{
1236 int ret;
1237 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238 mbedtls_mpi M;
1239 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1240 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001241 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1242 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1243
1244 if( N->n < P521_WIDTH )
1245 return( 0 );
1246
1247 /* M = A1 */
1248 M.s = 1;
1249 M.n = N->n - ( P521_WIDTH - 1 );
1250 if( M.n > P521_WIDTH + 1 )
1251 M.n = P521_WIDTH + 1;
1252 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001253 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1254 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001255
1256 /* N = A0 */
1257 N->p[P521_WIDTH - 1] &= P521_MASK;
1258 for( i = P521_WIDTH; i < N->n; i++ )
1259 N->p[i] = 0;
1260
1261 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001262 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001263
1264cleanup:
1265 return( ret );
1266}
1267
1268#undef P521_WIDTH
1269#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001271
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001273
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001274#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001276/* Size of p255 in terms of mbedtls_mpi_uint */
1277#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001278
1279/*
1280 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001281 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001282 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001283static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001284{
1285 int ret;
1286 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001287 mbedtls_mpi M;
1288 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001289
1290 if( N->n < P255_WIDTH )
1291 return( 0 );
1292
1293 /* M = A1 */
1294 M.s = 1;
1295 M.n = N->n - ( P255_WIDTH - 1 );
1296 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001297 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001298 M.p = Mp;
1299 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001300 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1301 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001302 M.n++; /* Make room for multiplication by 19 */
1303
1304 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001305 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001306 for( i = P255_WIDTH; i < N->n; i++ )
1307 N->p[i] = 0;
1308
1309 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001310 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1311 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001312
1313cleanup:
1314 return( ret );
1315}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001316#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001317
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001318#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1319
1320/* Size of p448 in terms of mbedtls_mpi_uint */
1321#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1322
1323/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1324#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1325#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1326#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1327#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1328
1329/*
1330 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1331 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1332 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1333 * implementation of Curve448, which uses its own special 56-bit limbs rather
1334 * than a generic bignum library. We could squeeze some extra speed out on
1335 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1336 * arithmetic using the limbs directly as we do for the NIST primes above,
1337 * but for 64-bit targets it should use half the number of operations if we do
1338 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1339 */
1340static int ecp_mod_p448( mbedtls_mpi *N )
1341{
1342 int ret;
1343 size_t i;
1344 mbedtls_mpi M, Q;
1345 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1346
1347 if( N->n <= P448_WIDTH )
1348 return( 0 );
1349
1350 /* M = A1 */
1351 M.s = 1;
1352 M.n = N->n - ( P448_WIDTH );
1353 if( M.n > P448_WIDTH )
1354 /* Shouldn't be called with N larger than 2^896! */
1355 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1356 M.p = Mp;
1357 memset( Mp, 0, sizeof( Mp ) );
1358 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1359
1360 /* N = A0 */
1361 for( i = P448_WIDTH; i < N->n; i++ )
1362 N->p[i] = 0;
1363
1364 /* N += A1 */
1365 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1366
1367 /* Q = B1, N += B1 */
1368 Q = M;
1369 Q.p = Qp;
1370 memcpy( Qp, Mp, sizeof( Qp ) );
1371 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1372 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1373
1374 /* M = (B0 + B1) * 2^224, N += M */
1375 if( sizeof( mbedtls_mpi_uint ) > 4 )
1376 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1377 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1378 Mp[i] = 0;
1379 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1380 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1381 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1382 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1383
1384cleanup:
1385 return( ret );
1386}
1387#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001389#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1390 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1391 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001392/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001393 * Fast quasi-reduction modulo P = 2^s - R,
1394 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001395 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001396 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001397 * Actually do two passes, since R is big.
1398 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001399#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1400#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1401static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1402 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001403{
1404 int ret;
1405 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001406 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001407 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001408
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001409 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001410 return( 0 );
1411
1412 /* Init R */
1413 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001414 R.p = Rp;
1415 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001416
1417 /* Common setup for M */
1418 M.s = 1;
1419 M.p = Mp;
1420
1421 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001422 M.n = N->n - ( p_limbs - adjust );
1423 if( M.n > p_limbs + adjust )
1424 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001425 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001426 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001427 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001428 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001429 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001430
1431 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001432 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001433 N->p[p_limbs - 1] &= mask;
1434 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001435 N->p[i] = 0;
1436
1437 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001438 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1439 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001440
1441 /* Second pass */
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
1463cleanup:
1464 return( ret );
1465}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1467 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1468 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001471/*
1472 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1473 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1474 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001476{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001477 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001478 BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001481}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001485/*
1486 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1487 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1488 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001490{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001492 BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001495 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1496#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001498#endif
1499}
1500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001501#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001503#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001504/*
1505 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1506 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1507 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001509{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001510 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001511 BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001512 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001513}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001514#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001515
Janos Follathb0697532016-08-18 12:38:46 +01001516#endif /* !MBEDTLS_ECP_ALT */
1517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518#endif /* MBEDTLS_ECP_C */