blob: f060ac664bc19318d6abc6a5b6131e400a63cc96 [file] [log] [blame]
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001/*
2 * Elliptic curves over GF(p): curve-specific data and functions
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010045 */
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020049#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020051#endif
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/ecp.h"
Hanno Becker4f8e8e52018-12-14 15:08:03 +000056#include "mbedtls/platform_util.h"
Janos Follath7d34e2e2021-06-24 14:48:38 +010057#include "mbedtls/bn_mul.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010058
Rich Evans00ab4702015-02-06 13:43:58 +000059#include <string.h>
60
Janos Follathb0697532016-08-18 12:38:46 +010061#if !defined(MBEDTLS_ECP_ALT)
62
Hanno Becker4f8e8e52018-12-14 15:08:03 +000063/* Parameter validation macros based on platform_util.h */
64#define ECP_VALIDATE_RET( cond ) \
65 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
66#define ECP_VALIDATE( cond ) \
67 MBEDTLS_INTERNAL_VALIDATE( cond )
68
Manuel Pégourié-Gonnard0223ab92015-10-05 11:40:01 +010069#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
70 !defined(inline) && !defined(__cplusplus)
Paul Bakker498fd352013-12-02 22:17:24 +010071#define inline __inline
Manuel Pégourié-Gonnard20af64d2015-07-07 18:33:39 +020072#endif
Paul Bakker498fd352013-12-02 22:17:24 +010073
Manuel Pégourié-Gonnard6ec15352021-06-23 12:25:48 +020074#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
75
76#define ECP_MPI_INIT_ARRAY(x) \
77 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
78
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010079/*
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010080 * Note: the constants are in little-endian order
81 * to be directly usable in MPIs
82 */
83
84/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010085 * Domain parameters for secp192r1
86 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
88static const mbedtls_mpi_uint secp192r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010089 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
90 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
91 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010092};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093static const mbedtls_mpi_uint secp192r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010094 BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
95 BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
96 BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010097};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098static const mbedtls_mpi_uint secp192r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010099 BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
100 BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
101 BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100102};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103static const mbedtls_mpi_uint secp192r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100104 BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
105 BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
106 BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100107};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108static const mbedtls_mpi_uint secp192r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100109 BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
110 BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
111 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100112};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100114
115/*
116 * Domain parameters for secp224r1
117 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
119static const mbedtls_mpi_uint secp224r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100120 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
121 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
122 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
123 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100124};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125static const mbedtls_mpi_uint secp224r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100126 BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
127 BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
128 BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100129 BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100130};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131static const mbedtls_mpi_uint secp224r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100132 BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
133 BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
134 BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100135 BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100136};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200137static const mbedtls_mpi_uint secp224r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100138 BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
139 BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
140 BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100141 BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100142};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200143static const mbedtls_mpi_uint secp224r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100144 BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
145 BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
146 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100147 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100148};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100150
151/*
152 * Domain parameters for secp256r1
153 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
155static const mbedtls_mpi_uint secp256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100156 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
157 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
158 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
159 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100160};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161static const mbedtls_mpi_uint secp256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100162 BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
163 BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
164 BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
165 BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100166};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167static const mbedtls_mpi_uint secp256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100168 BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
169 BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
170 BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
171 BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100172};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173static const mbedtls_mpi_uint secp256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100174 BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
175 BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
176 BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
177 BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100178};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179static const mbedtls_mpi_uint secp256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100180 BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
181 BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
182 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
183 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100184};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100186
187/*
188 * Domain parameters for secp384r1
189 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
191static const mbedtls_mpi_uint secp384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100192 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
193 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
194 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
195 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
196 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
197 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100198};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199static const mbedtls_mpi_uint secp384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100200 BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
201 BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
202 BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
203 BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
204 BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
205 BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100206};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207static const mbedtls_mpi_uint secp384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100208 BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
209 BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
210 BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
211 BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
212 BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
213 BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100214};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215static const mbedtls_mpi_uint secp384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100216 BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
217 BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
218 BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
219 BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
220 BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
221 BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100222};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223static const mbedtls_mpi_uint secp384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100224 BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
225 BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
226 BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
227 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
228 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
229 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100230};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100232
233/*
234 * Domain parameters for secp521r1
235 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
237static const mbedtls_mpi_uint secp521r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100238 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
239 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
240 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
241 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
242 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
243 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
244 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
245 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100246 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100247};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248static const mbedtls_mpi_uint secp521r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100249 BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
250 BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
251 BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
252 BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
253 BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
254 BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
255 BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
256 BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100257 BYTES_TO_T_UINT_2( 0x51, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100258};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259static const mbedtls_mpi_uint secp521r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100260 BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
261 BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
262 BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
263 BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
264 BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
265 BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
266 BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
267 BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100268 BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100269};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270static const mbedtls_mpi_uint secp521r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100271 BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
272 BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
273 BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
274 BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
275 BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
276 BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
277 BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
278 BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100279 BYTES_TO_T_UINT_2( 0x18, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100280};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281static const mbedtls_mpi_uint secp521r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100282 BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
283 BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
284 BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
285 BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
286 BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
287 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
288 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
289 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100290 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100291};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
295static const mbedtls_mpi_uint secp192k1_p[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100296 BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
297 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
298 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
299};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300static const mbedtls_mpi_uint secp192k1_a[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100301 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
302};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303static const mbedtls_mpi_uint secp192k1_b[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100304 BYTES_TO_T_UINT_2( 0x03, 0x00 ),
305};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306static const mbedtls_mpi_uint secp192k1_gx[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100307 BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
308 BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
309 BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
310};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311static const mbedtls_mpi_uint secp192k1_gy[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100312 BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
313 BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
314 BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
315};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316static const mbedtls_mpi_uint secp192k1_n[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100317 BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
318 BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
319 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
320};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
324static const mbedtls_mpi_uint secp224k1_p[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100325 BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 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 ),
328 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
329};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330static const mbedtls_mpi_uint secp224k1_a[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100331 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
332};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333static const mbedtls_mpi_uint secp224k1_b[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100334 BYTES_TO_T_UINT_2( 0x05, 0x00 ),
335};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336static const mbedtls_mpi_uint secp224k1_gx[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100337 BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
338 BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
339 BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
340 BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
341};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342static const mbedtls_mpi_uint secp224k1_gy[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100343 BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
344 BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
345 BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
346 BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
347};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348static const mbedtls_mpi_uint secp224k1_n[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100349 BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
350 BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
351 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
352 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
353};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
357static const mbedtls_mpi_uint secp256k1_p[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100358 BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
359 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
360 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
361 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
362};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363static const mbedtls_mpi_uint secp256k1_a[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100364 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
365};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366static const mbedtls_mpi_uint secp256k1_b[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100367 BYTES_TO_T_UINT_2( 0x07, 0x00 ),
368};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369static const mbedtls_mpi_uint secp256k1_gx[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100370 BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
371 BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
372 BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
373 BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
374};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375static const mbedtls_mpi_uint secp256k1_gy[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100376 BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
377 BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
378 BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
379 BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
380};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381static const mbedtls_mpi_uint secp256k1_n[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100382 BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
383 BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
384 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
385 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
386};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100388
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100389/*
390 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
391 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
393static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100394 BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
395 BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
396 BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
397 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100398};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100400 BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
401 BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
402 BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
403 BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100404};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100406 BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
407 BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
408 BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
409 BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100410};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100412 BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
413 BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
414 BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
415 BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100416};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100418 BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
419 BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
420 BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
421 BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100422};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100424 BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
425 BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
426 BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
427 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100428};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100430
431/*
432 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
433 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
435static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100436 BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
437 BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
438 BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
439 BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
440 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
441 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100442};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100444 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
445 BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
446 BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
447 BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
448 BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
449 BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100450};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100452 BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
453 BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
454 BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
455 BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
456 BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
457 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100458};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100460 BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
461 BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
462 BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
463 BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
464 BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
465 BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100466};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100468 BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
469 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
470 BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
471 BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
472 BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
473 BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100474};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100476 BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
477 BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
478 BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
479 BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
480 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
481 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100482};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100484
485/*
486 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
487 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
489static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100490 BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
491 BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
492 BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
493 BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
494 BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
495 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
496 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
497 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100498};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100500 BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
501 BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
502 BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
503 BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
504 BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
505 BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
506 BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
507 BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100508};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100510 BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
511 BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
512 BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
513 BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
514 BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
515 BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
516 BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
517 BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100518};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200519static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100520 BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
521 BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
522 BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
523 BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
524 BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
525 BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
526 BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
527 BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100528};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100530 BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
531 BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
532 BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
533 BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
534 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
535 BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
536 BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
537 BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100538};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100540 BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
541 BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
542 BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
543 BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
544 BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
545 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
546 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
547 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100548};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100550
551/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100552 * Create an MPI from embedded constants
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100554 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100556{
557 X->s = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 X->n = len / sizeof( mbedtls_mpi_uint );
559 X->p = (mbedtls_mpi_uint *) p;
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100560}
561
562/*
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100563 * Set an MPI to static value 1
564 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565static inline void ecp_mpi_set1( mbedtls_mpi *X )
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100566{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 static mbedtls_mpi_uint one[] = { 1 };
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100568 X->s = 1;
569 X->n = 1;
570 X->p = one;
571}
572
573/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100574 * Make group available from embedded constants
575 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576static int ecp_group_load( mbedtls_ecp_group *grp,
577 const mbedtls_mpi_uint *p, size_t plen,
578 const mbedtls_mpi_uint *a, size_t alen,
579 const mbedtls_mpi_uint *b, size_t blen,
580 const mbedtls_mpi_uint *gx, size_t gxlen,
581 const mbedtls_mpi_uint *gy, size_t gylen,
582 const mbedtls_mpi_uint *n, size_t nlen)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100583{
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100584 ecp_mpi_load( &grp->P, p, plen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100585 if( a != NULL )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100586 ecp_mpi_load( &grp->A, a, alen );
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100587 ecp_mpi_load( &grp->B, b, blen );
588 ecp_mpi_load( &grp->N, n, nlen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100589
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100590 ecp_mpi_load( &grp->G.X, gx, gxlen );
591 ecp_mpi_load( &grp->G.Y, gy, gylen );
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100592 ecp_mpi_set1( &grp->G.Z );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100593
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200594 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
595 grp->nbits = mbedtls_mpi_bitlen( &grp->N );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100596
Manuel Pégourié-Gonnard1f82b042013-12-06 12:51:50 +0100597 grp->h = 1;
598
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100599 return( 0 );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100600}
601
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100603/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
605static int ecp_mod_p192( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100606#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
608static int ecp_mod_p224( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100609#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
611static int ecp_mod_p256( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100612#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
614static int ecp_mod_p384( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100615#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
617static int ecp_mod_p521( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100618#endif
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100619
620#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
621#else
622#define NIST_MODP( P )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100624
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100625/* Additional forward declarations */
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200626#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627static int ecp_mod_p255( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100628#endif
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000629#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
630static int ecp_mod_p448( mbedtls_mpi * );
631#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
633static int ecp_mod_p192k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100634#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
636static int ecp_mod_p224k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100637#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
639static int ecp_mod_p256k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100640#endif
641
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100642#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
643 G ## _p, sizeof( G ## _p ), \
644 G ## _a, sizeof( G ## _a ), \
645 G ## _b, sizeof( G ## _b ), \
646 G ## _gx, sizeof( G ## _gx ), \
647 G ## _gy, sizeof( G ## _gy ), \
648 G ## _n, sizeof( G ## _n ) )
649
650#define LOAD_GROUP( G ) ecp_group_load( grp, \
651 G ## _p, sizeof( G ## _p ), \
652 NULL, 0, \
653 G ## _b, sizeof( G ## _b ), \
654 G ## _gx, sizeof( G ## _gx ), \
655 G ## _gy, sizeof( G ## _gy ), \
656 G ## _n, sizeof( G ## _n ) )
657
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200658#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200659/* Constants used by ecp_use_curve25519() */
660static const unsigned char curve25519_a24[] = { 0x01, 0xDB, 0x42 };
661static const unsigned char curve25519_part_of_n[] = {
662 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
663 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
664};
665
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100666/*
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100667 * Specialized function for creating the Curve25519 group
668 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669static int ecp_use_curve25519( mbedtls_ecp_group *grp )
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100670{
671 int ret;
672
673 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200674 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
675 curve25519_a24, sizeof( curve25519_a24 ) ) );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100676
677 /* P = 2^255 - 19 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200678 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
679 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
680 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200681 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100682
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100683 /* N = 2^252 + 27742317777372353535851937790883648493 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200684 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
685 curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100686 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
687
Manuel Pégourié-Gonnard18b78432018-03-28 11:14:06 +0200688 /* Y intentionally not set, since we use x/z coordinates.
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100689 * This is used as a marker to identify Montgomery curves! */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
691 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
692 mbedtls_mpi_free( &grp->G.Y );
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100693
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100694 /* Actually, the required msb for private keys */
695 grp->nbits = 254;
696
697cleanup:
698 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100700
701 return( ret );
702}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200703#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100704
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000705#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200706/* Constants used by ecp_use_curve448() */
707static const unsigned char curve448_a24[] = { 0x98, 0xAA };
708static const unsigned char curve448_part_of_n[] = {
709 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
710 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
711 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
712 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
713};
714
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000715/*
716 * Specialized function for creating the Curve448 group
717 */
718static int ecp_use_curve448( mbedtls_ecp_group *grp )
719{
720 mbedtls_mpi Ns;
721 int ret;
722
723 mbedtls_mpi_init( &Ns );
724
725 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200726 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
727 curve448_a24, sizeof( curve448_a24 ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000728
729 /* P = 2^448 - 2^224 - 1 */
730 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
731 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
732 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
733 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
734 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
735 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
736
737 /* Y intentionally not set, since we use x/z coordinates.
738 * This is used as a marker to identify Montgomery curves! */
739 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
740 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
741 mbedtls_mpi_free( &grp->G.Y );
742
743 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
744 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Manuel Pégourié-Gonnard89ce7d22021-06-23 12:43:34 +0200745 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
746 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000747 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
748
749 /* Actually, the required msb for private keys */
750 grp->nbits = 447;
751
752cleanup:
753 mbedtls_mpi_free( &Ns );
754 if( ret != 0 )
755 mbedtls_ecp_group_free( grp );
756
757 return( ret );
758}
759#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
760
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100761/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100762 * Set a group using well-known domain parameters
763 */
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200764int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100765{
Hanno Becker4f8e8e52018-12-14 15:08:03 +0000766 ECP_VALIDATE_RET( grp != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100768
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100769 grp->id = id;
770
771 switch( id )
772 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
774 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100775 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100776 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100778
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
780 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100781 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100782 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
786 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100787 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100788 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
792 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100793 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100794 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100796
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
798 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100799 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100800 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100802
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200803#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
804 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100805 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100806 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100808
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
810 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100811 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100812 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100814
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
816 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100817 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100818 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200819#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100820
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
822 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100823 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
827 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100828 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100830
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200831#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
832 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100833 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200834#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100835
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200836#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
837 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100838 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100839 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200840#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100841
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000842#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
843 case MBEDTLS_ECP_DP_CURVE448:
844 grp->modp = ecp_mod_p448;
845 return( ecp_use_curve448( grp ) );
846#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
847
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100848 default:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_ecp_group_free( grp );
850 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100851 }
852}
853
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100855/*
856 * Fast reduction modulo the primes used by the NIST curves.
857 *
858 * These functions are critical for speed, but not needed for correct
859 * operations. So, we make the choice to heavily rely on the internals of our
860 * bignum library, which creates a tight coupling between these functions and
861 * our MPI implementation. However, the coupling between the ECP module and
862 * MPI remains loose, since these functions can be deactivated at will.
863 */
864
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100866/*
867 * Compared to the way things are presented in FIPS 186-3 D.2,
868 * we proceed in columns, from right (least significant chunk) to left,
869 * adding chunks to N in place, and keeping a carry for the next chunk.
870 * This avoids moving things around in memory, and uselessly adding zeros,
871 * compared to the more straightforward, line-oriented approach.
872 *
873 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
875 * 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 +0100876 */
877
878/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100880{
881 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 mbedtls_mpi_uint c = 0;
883 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100884 {
885 *dst += c; c = ( *dst < c );
886 *dst += *src; c += ( *dst < *src );
887 }
888 *carry += c;
889}
890
891/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100893{
894 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100896 {
897 *dst += *carry;
898 *carry = ( *dst < *carry );
899 }
900}
901
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Beckerd6028a12018-10-15 12:01:35 +0100903#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100904#define ADD( i ) add64( p, A( i ), &c )
905#define NEXT p += WIDTH; carry64( p, &c )
906#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
907
908/*
909 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
910 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100912{
913 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 mbedtls_mpi_uint c = 0;
915 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100916
917 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100919
920 p = N->p;
921 end = p + N->n;
922
923 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
924 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
925 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
926
927cleanup:
928 return( ret );
929}
930
931#undef WIDTH
932#undef A
933#undef ADD
934#undef NEXT
935#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
939 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
940 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100941/*
942 * The reader is advised to first understand ecp_mod_p192() since the same
943 * general structure is used here, but with additional complications:
944 * (1) chunks of 32 bits, and (2) subtractions.
945 */
946
947/*
948 * For these primes, we need to handle data in chunks of 32 bits.
949 * This makes it more complicated if we use 64 bits limbs in MPI,
950 * which prevents us from using a uniform access method as for p192.
951 *
952 * So, we define a mini abstraction layer to access 32 bit chunks,
953 * load them in 'cur' for work, and store them back from 'cur' when done.
954 *
955 * While at it, also define the size of N in terms of 32-bit chunks.
956 */
957#define LOAD32 cur = A( i );
958
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200959#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100960
961#define MAX32 N->n
962#define A( j ) N->p[j]
963#define STORE32 N->p[i] = cur;
964
965#else /* 64-bit */
966
967#define MAX32 N->n * 2
Hanno Beckerd6028a12018-10-15 12:01:35 +0100968#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
969 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100970#define STORE32 \
971 if( i % 2 ) { \
972 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100974 } else { \
975 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100977 }
978
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100980
981/*
982 * Helpers for addition and subtraction of chunks, with signed carry.
983 */
984static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
985{
986 *dst += src;
987 *carry += ( *dst < src );
988}
989
990static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
991{
992 *carry -= ( *dst < src );
993 *dst -= src;
994}
995
996#define ADD( j ) add32( &cur, A( j ), &c );
997#define SUB( j ) sub32( &cur, A( j ), &c );
998
999/*
1000 * Helpers for the main 'loop'
1001 * (see fix_negative for the motivation of C)
1002 */
Hanno Beckerd6028a12018-10-15 12:01:35 +01001003#define INIT( b ) \
1004 int ret; \
1005 signed char c = 0, cc; \
1006 uint32_t cur; \
1007 size_t i = 0, bits = (b); \
1008 mbedtls_mpi C; \
1009 mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
1010 \
1011 C.s = 1; \
1012 C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \
1013 C.p = Cp; \
1014 memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
1015 \
1016 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \
1017 sizeof( mbedtls_mpi_uint ) ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001018 LOAD32;
1019
1020#define NEXT \
1021 STORE32; i++; LOAD32; \
1022 cc = c; c = 0; \
1023 if( cc < 0 ) \
1024 sub32( &cur, -cc, &c ); \
1025 else \
1026 add32( &cur, cc, &c ); \
1027
1028#define LAST \
1029 STORE32; i++; \
1030 cur = c > 0 ? c : 0; STORE32; \
1031 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine7d6326d2020-07-23 01:14:34 +02001032 if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001033
1034/*
1035 * If the result is negative, we get it in the form
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001036 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001037 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038static 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 +01001039{
1040 int ret;
1041
Gilles Peskine2c8cfcf2021-04-03 21:40:11 +02001042 /* C = - c * 2^bits */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043#if !defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001044 ((void) bits);
1045#else
1046 if( bits == 224 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001048 else
1049#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050 C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001051
1052 /* N = - ( C - N ) */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001054 N->s = -1;
1055
1056cleanup:
1057
1058 return( ret );
1059}
1060
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001062/*
1063 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1064 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001066{
1067 INIT( 224 );
1068
1069 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1070 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1071 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1072 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1073 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1074 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1075 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1076
1077cleanup:
1078 return( ret );
1079}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001081
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001083/*
1084 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1085 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001087{
1088 INIT( 256 );
1089
1090 ADD( 8 ); ADD( 9 );
1091 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1092
1093 ADD( 9 ); ADD( 10 );
1094 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1095
1096 ADD( 10 ); ADD( 11 );
1097 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1098
1099 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1100 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1101
1102 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1103 SUB( 9 ); SUB( 10 ); NEXT; // A4
1104
1105 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1106 SUB( 10 ); SUB( 11 ); NEXT; // A5
1107
1108 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1109 SUB( 8 ); SUB( 9 ); NEXT; // A6
1110
1111 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1112 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1113
1114cleanup:
1115 return( ret );
1116}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001119#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001120/*
1121 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1122 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001123static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001124{
1125 INIT( 384 );
1126
1127 ADD( 12 ); ADD( 21 ); ADD( 20 );
1128 SUB( 23 ); NEXT; // A0
1129
1130 ADD( 13 ); ADD( 22 ); ADD( 23 );
1131 SUB( 12 ); SUB( 20 ); NEXT; // A2
1132
1133 ADD( 14 ); ADD( 23 );
1134 SUB( 13 ); SUB( 21 ); NEXT; // A2
1135
1136 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1137 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1138
1139 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1140 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1141
1142 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1143 SUB( 16 ); NEXT; // A5
1144
1145 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1146 SUB( 17 ); NEXT; // A6
1147
1148 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1149 SUB( 18 ); NEXT; // A7
1150
1151 ADD( 20 ); ADD( 17 ); ADD( 16 );
1152 SUB( 19 ); NEXT; // A8
1153
1154 ADD( 21 ); ADD( 18 ); ADD( 17 );
1155 SUB( 20 ); NEXT; // A9
1156
1157 ADD( 22 ); ADD( 19 ); ADD( 18 );
1158 SUB( 21 ); NEXT; // A10
1159
1160 ADD( 23 ); ADD( 20 ); ADD( 19 );
1161 SUB( 22 ); LAST; // A11
1162
1163cleanup:
1164 return( ret );
1165}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001167
1168#undef A
1169#undef LOAD32
1170#undef STORE32
1171#undef MAX32
1172#undef INIT
1173#undef NEXT
1174#undef LAST
1175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1177 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1178 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001181/*
1182 * Here we have an actual Mersenne prime, so things are more straightforward.
1183 * However, chunks are aligned on a 'weird' boundary (521 bits).
1184 */
1185
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001186/* Size of p521 in terms of mbedtls_mpi_uint */
1187#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001190#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001191
1192/*
1193 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1194 * Write N as A1 + 2^521 A0, return A0 + A1
1195 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001196static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001197{
1198 int ret;
1199 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001200 mbedtls_mpi M;
1201 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1202 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001203 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1204 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1205
1206 if( N->n < P521_WIDTH )
1207 return( 0 );
1208
1209 /* M = A1 */
1210 M.s = 1;
1211 M.n = N->n - ( P521_WIDTH - 1 );
1212 if( M.n > P521_WIDTH + 1 )
1213 M.n = P521_WIDTH + 1;
1214 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1216 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001217
1218 /* N = A0 */
1219 N->p[P521_WIDTH - 1] &= P521_MASK;
1220 for( i = P521_WIDTH; i < N->n; i++ )
1221 N->p[i] = 0;
1222
1223 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001225
1226cleanup:
1227 return( ret );
1228}
1229
1230#undef P521_WIDTH
1231#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001235
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001236#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238/* Size of p255 in terms of mbedtls_mpi_uint */
1239#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001240
1241/*
1242 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001243 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001244 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001245static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001246{
1247 int ret;
1248 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001249 mbedtls_mpi M;
1250 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001251
1252 if( N->n < P255_WIDTH )
1253 return( 0 );
1254
1255 /* M = A1 */
1256 M.s = 1;
1257 M.n = N->n - ( P255_WIDTH - 1 );
1258 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001259 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001260 M.p = Mp;
1261 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001262 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1263 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001264 M.n++; /* Make room for multiplication by 19 */
1265
1266 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001267 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001268 for( i = P255_WIDTH; i < N->n; i++ )
1269 N->p[i] = 0;
1270
1271 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1273 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001274
1275cleanup:
1276 return( ret );
1277}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001278#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001279
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001280#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1281
1282/* Size of p448 in terms of mbedtls_mpi_uint */
1283#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1284
1285/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1286#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1287#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1288#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1289#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1290
1291/*
1292 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1293 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1294 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1295 * implementation of Curve448, which uses its own special 56-bit limbs rather
1296 * than a generic bignum library. We could squeeze some extra speed out on
1297 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1298 * arithmetic using the limbs directly as we do for the NIST primes above,
1299 * but for 64-bit targets it should use half the number of operations if we do
1300 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1301 */
1302static int ecp_mod_p448( mbedtls_mpi *N )
1303{
1304 int ret;
1305 size_t i;
1306 mbedtls_mpi M, Q;
1307 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1308
1309 if( N->n <= P448_WIDTH )
1310 return( 0 );
1311
1312 /* M = A1 */
1313 M.s = 1;
1314 M.n = N->n - ( P448_WIDTH );
1315 if( M.n > P448_WIDTH )
1316 /* Shouldn't be called with N larger than 2^896! */
1317 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1318 M.p = Mp;
1319 memset( Mp, 0, sizeof( Mp ) );
1320 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1321
1322 /* N = A0 */
1323 for( i = P448_WIDTH; i < N->n; i++ )
1324 N->p[i] = 0;
1325
1326 /* N += A1 */
1327 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1328
1329 /* Q = B1, N += B1 */
1330 Q = M;
1331 Q.p = Qp;
1332 memcpy( Qp, Mp, sizeof( Qp ) );
1333 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1334 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1335
1336 /* M = (B0 + B1) * 2^224, N += M */
1337 if( sizeof( mbedtls_mpi_uint ) > 4 )
1338 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1339 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1340 Mp[i] = 0;
1341 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1342 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1343 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1344 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1345
1346cleanup:
1347 return( ret );
1348}
1349#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001351#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1352 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1353 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001354/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001355 * Fast quasi-reduction modulo P = 2^s - R,
1356 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001357 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001358 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001359 * Actually do two passes, since R is big.
1360 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001361#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1362#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1363static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1364 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001365{
1366 int ret;
1367 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001369 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001370
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001371 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001372 return( 0 );
1373
1374 /* Init R */
1375 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001376 R.p = Rp;
1377 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001378
1379 /* Common setup for M */
1380 M.s = 1;
1381 M.p = Mp;
1382
1383 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001384 M.n = N->n - ( p_limbs - adjust );
1385 if( M.n > p_limbs + adjust )
1386 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001387 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001389 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001390 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001391 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001392
1393 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001394 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001395 N->p[p_limbs - 1] &= mask;
1396 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001397 N->p[i] = 0;
1398
1399 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1401 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001402
1403 /* Second pass */
1404
1405 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001406 M.n = N->n - ( p_limbs - adjust );
1407 if( M.n > p_limbs + adjust )
1408 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001409 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001410 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001411 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001412 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001413 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001414
1415 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001416 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001417 N->p[p_limbs - 1] &= mask;
1418 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001419 N->p[i] = 0;
1420
1421 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1423 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001424
1425cleanup:
1426 return( ret );
1427}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001428#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1429 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1430 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001433/*
1434 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1435 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1436 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001438{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001439 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001440 BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001443}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001446#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001447/*
1448 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1449 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1450 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001451static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001452{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001454 BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001456#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001457 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1458#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001460#endif
1461}
1462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001463#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001466/*
1467 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1468 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1469 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001471{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001473 BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001474 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001475}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001477
Janos Follathb0697532016-08-18 12:38:46 +01001478#endif /* !MBEDTLS_ECP_ALT */
1479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480#endif /* MBEDTLS_ECP_C */