blob: 3acc5a4968e2d06365a494ab8df91529fdbb049a [file] [log] [blame]
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001/*
2 * Elliptic curves over GF(p): curve-specific data and functions
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010023
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000024#include "mbedtls/ecp.h"
Hanno Becker4f8e8e52018-12-14 15:08:03 +000025#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000026#include "mbedtls/error.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010027
Gilles Peskine618be2e2021-04-03 21:47:53 +020028#include "ecp_invasive.h"
29
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Janos Follathb0697532016-08-18 12:38:46 +010032#if !defined(MBEDTLS_ECP_ALT)
33
Hanno Becker4f8e8e52018-12-14 15:08:03 +000034/* Parameter validation macros based on platform_util.h */
35#define ECP_VALIDATE_RET( cond ) \
36 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
37#define ECP_VALIDATE( cond ) \
38 MBEDTLS_INTERNAL_VALIDATE( cond )
39
Manuel Pégourié-Gonnard0223ab92015-10-05 11:40:01 +010040#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
41 !defined(inline) && !defined(__cplusplus)
Paul Bakker498fd352013-12-02 22:17:24 +010042#define inline __inline
Manuel Pégourié-Gonnard20af64d2015-07-07 18:33:39 +020043#endif
Paul Bakker498fd352013-12-02 22:17:24 +010044
Manuel Pégourié-Gonnardbaee5d42013-12-06 13:38:41 +010045/*
46 * Conversion macros for embedded constants:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047 * 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 +010048 */
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +020049#if defined(MBEDTLS_HAVE_INT32)
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010050
Hanno Becker1eeca412018-10-15 12:01:35 +010051#define BYTES_TO_T_UINT_4( a, b, c, d ) \
52 ( (mbedtls_mpi_uint) (a) << 0 ) | \
53 ( (mbedtls_mpi_uint) (b) << 8 ) | \
54 ( (mbedtls_mpi_uint) (c) << 16 ) | \
55 ( (mbedtls_mpi_uint) (d) << 24 )
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010056
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010057#define BYTES_TO_T_UINT_2( a, b ) \
58 BYTES_TO_T_UINT_4( a, b, 0, 0 )
59
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010060#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
Manuel Pégourié-Gonnard69ab3542013-12-12 15:50:08 +010061 BYTES_TO_T_UINT_4( a, b, c, d ), \
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010062 BYTES_TO_T_UINT_4( e, f, g, h )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010063
64#else /* 64-bits */
65
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010066#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
Hanno Becker1eeca412018-10-15 12:01:35 +010067 ( (mbedtls_mpi_uint) (a) << 0 ) | \
68 ( (mbedtls_mpi_uint) (b) << 8 ) | \
69 ( (mbedtls_mpi_uint) (c) << 16 ) | \
70 ( (mbedtls_mpi_uint) (d) << 24 ) | \
71 ( (mbedtls_mpi_uint) (e) << 32 ) | \
72 ( (mbedtls_mpi_uint) (f) << 40 ) | \
73 ( (mbedtls_mpi_uint) (g) << 48 ) | \
74 ( (mbedtls_mpi_uint) (h) << 56 )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010075
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010076#define BYTES_TO_T_UINT_4( a, b, c, d ) \
77 BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )
78
79#define BYTES_TO_T_UINT_2( a, b ) \
80 BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )
81
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082#endif /* bits in mbedtls_mpi_uint */
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010083
Manuel Pégourié-Gonnard10b8e5a2021-06-23 12:25:48 +020084#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
85
86#define ECP_MPI_INIT_ARRAY(x) \
87 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
88
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010089/*
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010090 * Note: the constants are in little-endian order
91 * to be directly usable in MPIs
92 */
93
94/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010095 * Domain parameters for secp192r1
96 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
98static const mbedtls_mpi_uint secp192r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010099 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
100 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
101 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
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_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100104 BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
105 BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
106 BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
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_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100109 BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
110 BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
111 BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100112};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113static const mbedtls_mpi_uint secp192r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100114 BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
115 BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
116 BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100117};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118static const mbedtls_mpi_uint secp192r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100119 BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
120 BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
121 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100122};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200123#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100124
125/*
126 * Domain parameters for secp224r1
127 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
129static const mbedtls_mpi_uint secp224r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100130 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
131 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
132 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
133 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100134};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200135static const mbedtls_mpi_uint secp224r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100136 BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
137 BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
138 BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100139 BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100140};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141static const mbedtls_mpi_uint secp224r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100142 BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
143 BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
144 BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100145 BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100146};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147static const mbedtls_mpi_uint secp224r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100148 BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
149 BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
150 BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100151 BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100152};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200153static const mbedtls_mpi_uint secp224r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100154 BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
155 BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
156 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100157 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100158};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100160
161/*
162 * Domain parameters for secp256r1
163 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
165static const mbedtls_mpi_uint secp256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100166 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
167 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
168 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
169 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100170};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200171static const mbedtls_mpi_uint secp256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100172 BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
173 BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
174 BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
175 BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100176};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177static const mbedtls_mpi_uint secp256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100178 BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
179 BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
180 BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
181 BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100182};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183static const mbedtls_mpi_uint secp256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100184 BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
185 BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
186 BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
187 BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100188};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189static const mbedtls_mpi_uint secp256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100190 BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
191 BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
192 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
193 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100194};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100196
197/*
198 * Domain parameters for secp384r1
199 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
201static const mbedtls_mpi_uint secp384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100202 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
203 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
204 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
205 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
206 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
207 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100208};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209static const mbedtls_mpi_uint secp384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100210 BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
211 BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
212 BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
213 BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
214 BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
215 BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100216};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217static const mbedtls_mpi_uint secp384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100218 BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
219 BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
220 BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
221 BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
222 BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
223 BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100224};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225static const mbedtls_mpi_uint secp384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100226 BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
227 BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
228 BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
229 BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
230 BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
231 BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100232};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233static const mbedtls_mpi_uint secp384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100234 BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
235 BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
236 BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
237 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
238 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 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100240};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200241#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100242
243/*
244 * Domain parameters for secp521r1
245 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
247static const mbedtls_mpi_uint secp521r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100248 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
249 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
250 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
251 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
252 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
253 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
254 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
255 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100256 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100257};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258static const mbedtls_mpi_uint secp521r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100259 BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
260 BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
261 BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
262 BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
263 BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
264 BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
265 BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
266 BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100267 BYTES_TO_T_UINT_2( 0x51, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100268};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269static const mbedtls_mpi_uint secp521r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100270 BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
271 BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
272 BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
273 BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
274 BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
275 BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
276 BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
277 BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100278 BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100279};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280static const mbedtls_mpi_uint secp521r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100281 BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
282 BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
283 BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
284 BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
285 BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
286 BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
287 BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
288 BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100289 BYTES_TO_T_UINT_2( 0x18, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100290};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291static const mbedtls_mpi_uint secp521r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100292 BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
293 BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
294 BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
295 BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
296 BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 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 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100300 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100301};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100303
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
305static const mbedtls_mpi_uint secp192k1_p[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100306 BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
307 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
308 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
309};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200310static const mbedtls_mpi_uint secp192k1_a[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100311 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
312};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313static const mbedtls_mpi_uint secp192k1_b[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100314 BYTES_TO_T_UINT_2( 0x03, 0x00 ),
315};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316static const mbedtls_mpi_uint secp192k1_gx[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100317 BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
318 BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
319 BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
320};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321static const mbedtls_mpi_uint secp192k1_gy[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100322 BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
323 BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
324 BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
325};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326static const mbedtls_mpi_uint secp192k1_n[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100327 BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
328 BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
329 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
330};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
334static const mbedtls_mpi_uint secp224k1_p[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100335 BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
336 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
337 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
338 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
339};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340static const mbedtls_mpi_uint secp224k1_a[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100341 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
342};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343static const mbedtls_mpi_uint secp224k1_b[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100344 BYTES_TO_T_UINT_2( 0x05, 0x00 ),
345};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346static const mbedtls_mpi_uint secp224k1_gx[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100347 BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
348 BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
349 BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
350 BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
351};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352static const mbedtls_mpi_uint secp224k1_gy[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100353 BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
354 BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
355 BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
356 BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
357};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358static const mbedtls_mpi_uint secp224k1_n[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100359 BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
360 BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
361 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
362 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
363};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
367static const mbedtls_mpi_uint secp256k1_p[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100368 BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
369 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
370 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
371 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
372};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373static const mbedtls_mpi_uint secp256k1_a[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100374 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
375};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376static const mbedtls_mpi_uint secp256k1_b[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100377 BYTES_TO_T_UINT_2( 0x07, 0x00 ),
378};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379static const mbedtls_mpi_uint secp256k1_gx[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100380 BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
381 BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
382 BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
383 BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
384};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385static const mbedtls_mpi_uint secp256k1_gy[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100386 BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
387 BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
388 BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
389 BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
390};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391static const mbedtls_mpi_uint secp256k1_n[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100392 BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
393 BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
394 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
395 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
396};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100398
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100399/*
400 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
401 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
403static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100404 BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
405 BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
406 BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
407 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100408};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100410 BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
411 BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
412 BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
413 BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100414};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100416 BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
417 BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
418 BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
419 BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100420};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100422 BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
423 BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
424 BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
425 BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100426};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100428 BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
429 BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
430 BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
431 BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100432};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100434 BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
435 BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
436 BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
437 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100438};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100440
441/*
442 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
443 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
445static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100446 BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
447 BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
448 BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
449 BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
450 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
451 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100452};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100454 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
455 BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
456 BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
457 BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
458 BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
459 BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100460};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100462 BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
463 BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
464 BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
465 BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
466 BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
467 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100468};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100470 BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
471 BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
472 BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
473 BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
474 BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
475 BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100476};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100478 BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
479 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
480 BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
481 BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
482 BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
483 BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100484};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100486 BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
487 BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
488 BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
489 BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
490 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
491 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100492};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100494
495/*
496 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
497 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
499static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100500 BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
501 BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
502 BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
503 BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
504 BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
505 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
506 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
507 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
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_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100510 BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
511 BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
512 BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
513 BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
514 BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
515 BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
516 BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
517 BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
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_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100520 BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
521 BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
522 BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
523 BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
524 BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
525 BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
526 BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
527 BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
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_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100530 BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
531 BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
532 BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
533 BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
534 BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
535 BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
536 BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
537 BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
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_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100540 BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
541 BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
542 BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
543 BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
544 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
545 BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
546 BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
547 BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100548};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100550 BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
551 BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
552 BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
553 BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
554 BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
555 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
556 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
557 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100558};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100560
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200561#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
562 defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
563 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
564 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
565 defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
566 defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
567 defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
568 defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
569 defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
570 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
571 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
572/* For these curves, we build the group parameters dynamically. */
573#define ECP_LOAD_GROUP
574#endif
575
576#if defined(ECP_LOAD_GROUP)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100577/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100578 * Create an MPI from embedded constants
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100580 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581static 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 +0100582{
583 X->s = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 X->n = len / sizeof( mbedtls_mpi_uint );
585 X->p = (mbedtls_mpi_uint *) p;
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100586}
587
588/*
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100589 * Set an MPI to static value 1
590 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591static inline void ecp_mpi_set1( mbedtls_mpi *X )
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100592{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 static mbedtls_mpi_uint one[] = { 1 };
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100594 X->s = 1;
595 X->n = 1;
596 X->p = one;
597}
598
599/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100600 * Make group available from embedded constants
601 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602static int ecp_group_load( mbedtls_ecp_group *grp,
603 const mbedtls_mpi_uint *p, size_t plen,
604 const mbedtls_mpi_uint *a, size_t alen,
605 const mbedtls_mpi_uint *b, size_t blen,
606 const mbedtls_mpi_uint *gx, size_t gxlen,
607 const mbedtls_mpi_uint *gy, size_t gylen,
608 const mbedtls_mpi_uint *n, size_t nlen)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100609{
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100610 ecp_mpi_load( &grp->P, p, plen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100611 if( a != NULL )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100612 ecp_mpi_load( &grp->A, a, alen );
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100613 ecp_mpi_load( &grp->B, b, blen );
614 ecp_mpi_load( &grp->N, n, nlen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100615
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100616 ecp_mpi_load( &grp->G.X, gx, gxlen );
617 ecp_mpi_load( &grp->G.Y, gy, gylen );
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100618 ecp_mpi_set1( &grp->G.Z );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100619
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200620 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
621 grp->nbits = mbedtls_mpi_bitlen( &grp->N );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100622
Manuel Pégourié-Gonnard1f82b042013-12-06 12:51:50 +0100623 grp->h = 1;
624
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100625 return( 0 );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100626}
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200627#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100628
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100630/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
632static int ecp_mod_p192( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100633#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
635static int ecp_mod_p224( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100636#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
638static int ecp_mod_p256( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100639#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
641static int ecp_mod_p384( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100642#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
644static int ecp_mod_p521( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100645#endif
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100646
647#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
648#else
649#define NIST_MODP( P )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100651
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100652/* Additional forward declarations */
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200653#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654static int ecp_mod_p255( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100655#endif
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000656#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
657static int ecp_mod_p448( mbedtls_mpi * );
658#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
660static int ecp_mod_p192k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100661#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
663static int ecp_mod_p224k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100664#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
666static int ecp_mod_p256k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100667#endif
668
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200669#if defined(ECP_LOAD_GROUP)
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100670#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
671 G ## _p, sizeof( G ## _p ), \
672 G ## _a, sizeof( G ## _a ), \
673 G ## _b, sizeof( G ## _b ), \
674 G ## _gx, sizeof( G ## _gx ), \
675 G ## _gy, sizeof( G ## _gy ), \
676 G ## _n, sizeof( G ## _n ) )
677
678#define LOAD_GROUP( G ) ecp_group_load( grp, \
679 G ## _p, sizeof( G ## _p ), \
680 NULL, 0, \
681 G ## _b, sizeof( G ## _b ), \
682 G ## _gx, sizeof( G ## _gx ), \
683 G ## _gy, sizeof( G ## _gy ), \
684 G ## _n, sizeof( G ## _n ) )
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200685#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100686
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200687#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200688/* Constants used by ecp_use_curve25519() */
689static const unsigned char curve25519_a24[] = { 0x01, 0xDB, 0x42 };
690static const unsigned char curve25519_part_of_n[] = {
691 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
692 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
693};
694
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100695/*
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100696 * Specialized function for creating the Curve25519 group
697 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698static int ecp_use_curve25519( mbedtls_ecp_group *grp )
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100699{
Janos Follath24eed8d2019-11-22 13:21:35 +0000700 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100701
702 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200703 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
704 curve25519_a24, sizeof( curve25519_a24 ) ) );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100705
706 /* P = 2^255 - 19 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
708 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
709 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200710 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100711
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100712 /* N = 2^252 + 27742317777372353535851937790883648493 */
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200713 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
714 curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100715 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
716
Manuel Pégourié-Gonnard18b78432018-03-28 11:14:06 +0200717 /* Y intentionally not set, since we use x/z coordinates.
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100718 * This is used as a marker to identify Montgomery curves! */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
720 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
721 mbedtls_mpi_free( &grp->G.Y );
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100722
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100723 /* Actually, the required msb for private keys */
724 grp->nbits = 254;
725
726cleanup:
727 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100729
730 return( ret );
731}
Manuel Pégourié-Gonnard10b8e5a2021-06-23 12:25:48 +0200732
733/*
734 * Constants for the two points other than 0, 1, -1 (mod p) in
735 * https://cr.yp.to/ecdh.html#validate
736 * See ecp_check_pubkey_x25519().
737 */
738static const mbedtls_mpi_uint x25519_bad_point_1[] = {
739 BYTES_TO_T_UINT_8( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae ),
740 BYTES_TO_T_UINT_8( 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a ),
741 BYTES_TO_T_UINT_8( 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd ),
742 BYTES_TO_T_UINT_8( 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 ),
743};
744static const mbedtls_mpi_uint x25519_bad_point_2[] = {
745 BYTES_TO_T_UINT_8( 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24 ),
746 BYTES_TO_T_UINT_8( 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b ),
747 BYTES_TO_T_UINT_8( 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86 ),
748 BYTES_TO_T_UINT_8( 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 ),
749};
750const mbedtls_mpi mbedtls_ecp_x25519_bad_point_1 = ECP_MPI_INIT_ARRAY(
751 x25519_bad_point_1 );
752const mbedtls_mpi mbedtls_ecp_x25519_bad_point_2 = ECP_MPI_INIT_ARRAY(
753 x25519_bad_point_2 );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200754#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100755
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000756#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200757/* Constants used by ecp_use_curve448() */
758static const unsigned char curve448_a24[] = { 0x98, 0xAA };
759static const unsigned char curve448_part_of_n[] = {
760 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
761 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
762 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
763 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
764};
765
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000766/*
767 * Specialized function for creating the Curve448 group
768 */
769static int ecp_use_curve448( mbedtls_ecp_group *grp )
770{
771 mbedtls_mpi Ns;
Janos Follath24eed8d2019-11-22 13:21:35 +0000772 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000773
774 mbedtls_mpi_init( &Ns );
775
776 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200777 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
778 curve448_a24, sizeof( curve448_a24 ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000779
780 /* P = 2^448 - 2^224 - 1 */
781 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
782 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
783 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
784 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
785 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
786 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
787
788 /* Y intentionally not set, since we use x/z coordinates.
789 * This is used as a marker to identify Montgomery curves! */
790 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
791 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
792 mbedtls_mpi_free( &grp->G.Y );
793
794 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
795 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200796 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
797 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000798 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
799
800 /* Actually, the required msb for private keys */
801 grp->nbits = 447;
802
803cleanup:
804 mbedtls_mpi_free( &Ns );
805 if( ret != 0 )
806 mbedtls_ecp_group_free( grp );
807
808 return( ret );
809}
810#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
811
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100812/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100813 * Set a group using well-known domain parameters
814 */
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200815int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100816{
Hanno Becker4f8e8e52018-12-14 15:08:03 +0000817 ECP_VALIDATE_RET( grp != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100819
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100820 grp->id = id;
821
822 switch( id )
823 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
825 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100826 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100827 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200828#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100829
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
831 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100832 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100833 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200834#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100835
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200836#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
837 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100838 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100839 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200840#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100841
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
843 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100844 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100845 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100847
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
849 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100850 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100851 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100853
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
855 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100856 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100857 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100859
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
861 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100862 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100863 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
867 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100868 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100869 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100871
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
873 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100874 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100876
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
878 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100879 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100881
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
883 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100884 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100886
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200887#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
888 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100889 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100890 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200891#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100892
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000893#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
894 case MBEDTLS_ECP_DP_CURVE448:
895 grp->modp = ecp_mod_p448;
896 return( ecp_use_curve448( grp ) );
897#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
898
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100899 default:
Alexander K56a74cd2019-09-10 17:58:20 +0300900 grp->id = MBEDTLS_ECP_DP_NONE;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100902 }
903}
904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100906/*
907 * Fast reduction modulo the primes used by the NIST curves.
908 *
909 * These functions are critical for speed, but not needed for correct
910 * operations. So, we make the choice to heavily rely on the internals of our
911 * bignum library, which creates a tight coupling between these functions and
912 * our MPI implementation. However, the coupling between the ECP module and
913 * MPI remains loose, since these functions can be deactivated at will.
914 */
915
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200916#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100917/*
918 * Compared to the way things are presented in FIPS 186-3 D.2,
919 * we proceed in columns, from right (least significant chunk) to left,
920 * adding chunks to N in place, and keeping a carry for the next chunk.
921 * This avoids moving things around in memory, and uselessly adding zeros,
922 * compared to the more straightforward, line-oriented approach.
923 *
924 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
926 * 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 +0100927 */
928
929/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, 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 mbedtls_mpi_uint c = 0;
934 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100935 {
936 *dst += c; c = ( *dst < c );
937 *dst += *src; c += ( *dst < *src );
938 }
939 *carry += c;
940}
941
942/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100944{
945 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100947 {
948 *dst += *carry;
949 *carry = ( *dst < *carry );
950 }
951}
952
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Becker1eeca412018-10-15 12:01:35 +0100954#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100955#define ADD( i ) add64( p, A( i ), &c )
956#define NEXT p += WIDTH; carry64( p, &c )
957#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
958
959/*
960 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
961 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100963{
Janos Follath24eed8d2019-11-22 13:21:35 +0000964 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 mbedtls_mpi_uint c = 0;
966 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100967
968 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100970
971 p = N->p;
972 end = p + N->n;
973
974 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
975 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
976 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
977
978cleanup:
979 return( ret );
980}
981
982#undef WIDTH
983#undef A
984#undef ADD
985#undef NEXT
986#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
990 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
991 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100992/*
993 * The reader is advised to first understand ecp_mod_p192() since the same
994 * general structure is used here, but with additional complications:
995 * (1) chunks of 32 bits, and (2) subtractions.
996 */
997
998/*
999 * For these primes, we need to handle data in chunks of 32 bits.
1000 * This makes it more complicated if we use 64 bits limbs in MPI,
1001 * which prevents us from using a uniform access method as for p192.
1002 *
1003 * So, we define a mini abstraction layer to access 32 bit chunks,
1004 * load them in 'cur' for work, and store them back from 'cur' when done.
1005 *
1006 * While at it, also define the size of N in terms of 32-bit chunks.
1007 */
1008#define LOAD32 cur = A( i );
1009
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +02001010#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001011
1012#define MAX32 N->n
1013#define A( j ) N->p[j]
1014#define STORE32 N->p[i] = cur;
1015
1016#else /* 64-bit */
1017
1018#define MAX32 N->n * 2
Hanno Becker1eeca412018-10-15 12:01:35 +01001019#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
1020 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001021#define STORE32 \
1022 if( i % 2 ) { \
1023 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001025 } else { \
1026 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001028 }
1029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001031
1032/*
1033 * Helpers for addition and subtraction of chunks, with signed carry.
1034 */
1035static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
1036{
1037 *dst += src;
1038 *carry += ( *dst < src );
1039}
1040
1041static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
1042{
1043 *carry -= ( *dst < src );
1044 *dst -= src;
1045}
1046
1047#define ADD( j ) add32( &cur, A( j ), &c );
1048#define SUB( j ) sub32( &cur, A( j ), &c );
1049
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001050#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
Gilles Peskineb76517b2021-03-10 23:44:28 +01001051#define biL (ciL << 3) /* bits in limb */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001052
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001053/*
1054 * Helpers for the main 'loop'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001055 */
Hanno Becker1eeca412018-10-15 12:01:35 +01001056#define INIT( b ) \
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001057 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
Hanno Becker1eeca412018-10-15 12:01:35 +01001058 signed char c = 0, cc; \
1059 uint32_t cur; \
1060 size_t i = 0, bits = (b); \
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001061 /* N is the size of the product of two b-bit numbers, plus one */ \
1062 /* limb for fix_negative */ \
1063 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, ( b ) * 2 / biL + 1 ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001064 LOAD32;
1065
1066#define NEXT \
1067 STORE32; i++; LOAD32; \
1068 cc = c; c = 0; \
1069 if( cc < 0 ) \
1070 sub32( &cur, -cc, &c ); \
1071 else \
1072 add32( &cur, cc, &c ); \
1073
1074#define LAST \
1075 STORE32; i++; \
1076 cur = c > 0 ? c : 0; STORE32; \
1077 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine618be2e2021-04-03 21:47:53 +02001078 if( c < 0 ) mbedtls_ecp_fix_negative( N, c, bits );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001079
1080/*
1081 * If the result is negative, we get it in the form
Gilles Peskine349b3722021-04-03 21:40:11 +02001082 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001083 */
Gilles Peskine618be2e2021-04-03 21:47:53 +02001084MBEDTLS_STATIC_TESTABLE
1085void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001086{
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001087 size_t i;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001088
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001089 /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
1090 * set the absolute value to 0xfff...fff - N. There is no carry
1091 * since we're subtracting from all-bits-one. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001092 for( i = 0; i <= bits / 8 / sizeof( mbedtls_mpi_uint ); i++ )
1093 {
1094 N->p[i] = ~(mbedtls_mpi_uint)0 - N->p[i];
1095 }
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001096 /* Add 1, taking care of the carry. */
1097 i = 0;
1098 do
1099 ++N->p[i];
1100 while( N->p[i++] == 0 && i <= bits / 8 / sizeof( mbedtls_mpi_uint ) );
1101 /* Invert the sign.
1102 * Now N = N0 - 2^bits where N0 is the initial value of N. */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001103 N->s = -1;
1104
Gilles Peskine349b3722021-04-03 21:40:11 +02001105 /* Add |c| * 2^bits to the absolute value. Since c and N are
1106 * negative, this adds c * 2^bits. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001107 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1108#if defined(MBEDTLS_HAVE_INT64)
1109 if( bits == 224 )
1110 msw <<= 32;
1111#endif
1112 N->p[bits / 8 / sizeof( mbedtls_mpi_uint)] += msw;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001113}
1114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001116/*
1117 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1118 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001119static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001120{
1121 INIT( 224 );
1122
1123 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1124 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1125 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1126 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1127 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1128 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1129 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1130
1131cleanup:
1132 return( ret );
1133}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001134#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001137/*
1138 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1139 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001141{
1142 INIT( 256 );
1143
1144 ADD( 8 ); ADD( 9 );
1145 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1146
1147 ADD( 9 ); ADD( 10 );
1148 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1149
1150 ADD( 10 ); ADD( 11 );
1151 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1152
1153 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1154 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1155
1156 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1157 SUB( 9 ); SUB( 10 ); NEXT; // A4
1158
1159 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1160 SUB( 10 ); SUB( 11 ); NEXT; // A5
1161
1162 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1163 SUB( 8 ); SUB( 9 ); NEXT; // A6
1164
1165 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1166 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1167
1168cleanup:
1169 return( ret );
1170}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001171#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001173#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001174/*
1175 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1176 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001177static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001178{
1179 INIT( 384 );
1180
1181 ADD( 12 ); ADD( 21 ); ADD( 20 );
1182 SUB( 23 ); NEXT; // A0
1183
1184 ADD( 13 ); ADD( 22 ); ADD( 23 );
1185 SUB( 12 ); SUB( 20 ); NEXT; // A2
1186
1187 ADD( 14 ); ADD( 23 );
1188 SUB( 13 ); SUB( 21 ); NEXT; // A2
1189
1190 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1191 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1192
1193 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1194 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1195
1196 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1197 SUB( 16 ); NEXT; // A5
1198
1199 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1200 SUB( 17 ); NEXT; // A6
1201
1202 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1203 SUB( 18 ); NEXT; // A7
1204
1205 ADD( 20 ); ADD( 17 ); ADD( 16 );
1206 SUB( 19 ); NEXT; // A8
1207
1208 ADD( 21 ); ADD( 18 ); ADD( 17 );
1209 SUB( 20 ); NEXT; // A9
1210
1211 ADD( 22 ); ADD( 19 ); ADD( 18 );
1212 SUB( 21 ); NEXT; // A10
1213
1214 ADD( 23 ); ADD( 20 ); ADD( 19 );
1215 SUB( 22 ); LAST; // A11
1216
1217cleanup:
1218 return( ret );
1219}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001220#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001221
1222#undef A
1223#undef LOAD32
1224#undef STORE32
1225#undef MAX32
1226#undef INIT
1227#undef NEXT
1228#undef LAST
1229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1231 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1232 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001235/*
1236 * Here we have an actual Mersenne prime, so things are more straightforward.
1237 * However, chunks are aligned on a 'weird' boundary (521 bits).
1238 */
1239
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001240/* Size of p521 in terms of mbedtls_mpi_uint */
1241#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001244#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001245
1246/*
1247 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1248 * Write N as A1 + 2^521 A0, return A0 + A1
1249 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001250static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001251{
Janos Follath24eed8d2019-11-22 13:21:35 +00001252 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001253 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001254 mbedtls_mpi M;
1255 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1256 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001257 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1258 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1259
1260 if( N->n < P521_WIDTH )
1261 return( 0 );
1262
1263 /* M = A1 */
1264 M.s = 1;
1265 M.n = N->n - ( P521_WIDTH - 1 );
1266 if( M.n > P521_WIDTH + 1 )
1267 M.n = P521_WIDTH + 1;
1268 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001269 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1270 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001271
1272 /* N = A0 */
1273 N->p[P521_WIDTH - 1] &= P521_MASK;
1274 for( i = P521_WIDTH; i < N->n; i++ )
1275 N->p[i] = 0;
1276
1277 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001278 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001279
1280cleanup:
1281 return( ret );
1282}
1283
1284#undef P521_WIDTH
1285#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001287
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001289
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001290#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292/* Size of p255 in terms of mbedtls_mpi_uint */
1293#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001294
1295/*
1296 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001297 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001298 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001300{
Janos Follath24eed8d2019-11-22 13:21:35 +00001301 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001302 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001303 mbedtls_mpi M;
1304 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001305
1306 if( N->n < P255_WIDTH )
1307 return( 0 );
1308
1309 /* M = A1 */
1310 M.s = 1;
1311 M.n = N->n - ( P255_WIDTH - 1 );
1312 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001313 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001314 M.p = Mp;
1315 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001316 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1317 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001318 M.n++; /* Make room for multiplication by 19 */
1319
1320 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001322 for( i = P255_WIDTH; i < N->n; i++ )
1323 N->p[i] = 0;
1324
1325 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001326 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1327 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001328
1329cleanup:
1330 return( ret );
1331}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001332#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001333
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001334#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1335
1336/* Size of p448 in terms of mbedtls_mpi_uint */
1337#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1338
1339/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1340#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1341#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1342#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1343#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1344
1345/*
1346 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1347 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1348 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1349 * implementation of Curve448, which uses its own special 56-bit limbs rather
1350 * than a generic bignum library. We could squeeze some extra speed out on
1351 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1352 * arithmetic using the limbs directly as we do for the NIST primes above,
1353 * but for 64-bit targets it should use half the number of operations if we do
1354 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1355 */
1356static int ecp_mod_p448( mbedtls_mpi *N )
1357{
Janos Follath24eed8d2019-11-22 13:21:35 +00001358 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001359 size_t i;
1360 mbedtls_mpi M, Q;
1361 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1362
1363 if( N->n <= P448_WIDTH )
1364 return( 0 );
1365
1366 /* M = A1 */
1367 M.s = 1;
1368 M.n = N->n - ( P448_WIDTH );
1369 if( M.n > P448_WIDTH )
1370 /* Shouldn't be called with N larger than 2^896! */
1371 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1372 M.p = Mp;
1373 memset( Mp, 0, sizeof( Mp ) );
1374 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1375
1376 /* N = A0 */
1377 for( i = P448_WIDTH; i < N->n; i++ )
1378 N->p[i] = 0;
1379
1380 /* N += A1 */
1381 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1382
1383 /* Q = B1, N += B1 */
1384 Q = M;
1385 Q.p = Qp;
1386 memcpy( Qp, Mp, sizeof( Qp ) );
1387 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1388 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1389
1390 /* M = (B0 + B1) * 2^224, N += M */
1391 if( sizeof( mbedtls_mpi_uint ) > 4 )
1392 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1393 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1394 Mp[i] = 0;
1395 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1396 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1397 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1398 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1399
1400cleanup:
1401 return( ret );
1402}
1403#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001405#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1406 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1407 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001408/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001409 * Fast quasi-reduction modulo P = 2^s - R,
1410 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001411 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001412 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001413 * Actually do two passes, since R is big.
1414 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1416#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1417static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1418 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001419{
Janos Follath24eed8d2019-11-22 13:21:35 +00001420 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001421 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001423 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001424
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001425 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001426 return( 0 );
1427
1428 /* Init R */
1429 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001430 R.p = Rp;
1431 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001432
1433 /* Common setup for M */
1434 M.s = 1;
1435 M.p = Mp;
1436
1437 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001438 M.n = N->n - ( p_limbs - adjust );
1439 if( M.n > p_limbs + adjust )
1440 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001441 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001443 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001445 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001446
1447 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001448 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001449 N->p[p_limbs - 1] &= mask;
1450 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001451 N->p[i] = 0;
1452
1453 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001454 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1455 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001456
1457 /* Second pass */
1458
1459 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001460 M.n = N->n - ( p_limbs - adjust );
1461 if( M.n > p_limbs + adjust )
1462 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001463 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001464 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001465 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001467 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001468
1469 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001470 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001471 N->p[p_limbs - 1] &= mask;
1472 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001473 N->p[i] = 0;
1474
1475 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1477 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001478
1479cleanup:
1480 return( ret );
1481}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1483 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1484 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001485
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001487/*
1488 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1489 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1490 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001492{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001494 BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001496 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001497}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001498#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001501/*
1502 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1503 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1504 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001505static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001506{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001507 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001508 BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1509
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001510#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001511 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1512#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001514#endif
1515}
1516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001517#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001520/*
1521 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1522 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1523 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001525{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001527 BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001529}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001531
Janos Follathb0697532016-08-18 12:38:46 +01001532#endif /* !MBEDTLS_ECP_ALT */
1533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534#endif /* MBEDTLS_ECP_C */