blob: 0fa8825a221b3011e437cc999a094b3a3f6942df [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é-Gonnard07894332015-06-23 00:18:41 +0200732#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100733
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000734#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200735/* Constants used by ecp_use_curve448() */
736static const unsigned char curve448_a24[] = { 0x98, 0xAA };
737static const unsigned char curve448_part_of_n[] = {
738 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
739 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
740 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
741 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
742};
743
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000744/*
745 * Specialized function for creating the Curve448 group
746 */
747static int ecp_use_curve448( mbedtls_ecp_group *grp )
748{
749 mbedtls_mpi Ns;
Janos Follath24eed8d2019-11-22 13:21:35 +0000750 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000751
752 mbedtls_mpi_init( &Ns );
753
754 /* Actually ( A + 2 ) / 4 */
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200755 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->A,
756 curve448_a24, sizeof( curve448_a24 ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000757
758 /* P = 2^448 - 2^224 - 1 */
759 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
760 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
761 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
762 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
763 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
764 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
765
766 /* Y intentionally not set, since we use x/z coordinates.
767 * This is used as a marker to identify Montgomery curves! */
768 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
769 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
770 mbedtls_mpi_free( &grp->G.Y );
771
772 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
773 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200774 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
775 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000776 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
777
778 /* Actually, the required msb for private keys */
779 grp->nbits = 447;
780
781cleanup:
782 mbedtls_mpi_free( &Ns );
783 if( ret != 0 )
784 mbedtls_ecp_group_free( grp );
785
786 return( ret );
787}
788#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
789
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100790/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100791 * Set a group using well-known domain parameters
792 */
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200793int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100794{
Hanno Becker4f8e8e52018-12-14 15:08:03 +0000795 ECP_VALIDATE_RET( grp != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100797
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100798 grp->id = id;
799
800 switch( id )
801 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200802#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
803 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100804 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100805 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100807
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
809 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100810 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100811 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100813
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200814#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
815 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100816 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100817 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100819
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
821 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100822 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100823 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100825
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
827 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100828 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100829 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
833 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100834 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100835 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200836#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100837
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
839 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100840 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100841 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100843
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
845 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100846 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100847 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
851 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100852 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100854
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
856 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100857 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100859
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
861 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100862 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100864
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200865#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
866 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100867 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100868 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200869#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100870
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000871#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
872 case MBEDTLS_ECP_DP_CURVE448:
873 grp->modp = ecp_mod_p448;
874 return( ecp_use_curve448( grp ) );
875#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
876
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100877 default:
Alexander K56a74cd2019-09-10 17:58:20 +0300878 grp->id = MBEDTLS_ECP_DP_NONE;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100880 }
881}
882
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100884/*
885 * Fast reduction modulo the primes used by the NIST curves.
886 *
887 * These functions are critical for speed, but not needed for correct
888 * operations. So, we make the choice to heavily rely on the internals of our
889 * bignum library, which creates a tight coupling between these functions and
890 * our MPI implementation. However, the coupling between the ECP module and
891 * MPI remains loose, since these functions can be deactivated at will.
892 */
893
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100895/*
896 * Compared to the way things are presented in FIPS 186-3 D.2,
897 * we proceed in columns, from right (least significant chunk) to left,
898 * adding chunks to N in place, and keeping a carry for the next chunk.
899 * This avoids moving things around in memory, and uselessly adding zeros,
900 * compared to the more straightforward, line-oriented approach.
901 *
902 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
904 * 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 +0100905 */
906
907/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100909{
910 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 mbedtls_mpi_uint c = 0;
912 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100913 {
914 *dst += c; c = ( *dst < c );
915 *dst += *src; c += ( *dst < *src );
916 }
917 *carry += c;
918}
919
920/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100922{
923 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100925 {
926 *dst += *carry;
927 *carry = ( *dst < *carry );
928 }
929}
930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Becker1eeca412018-10-15 12:01:35 +0100932#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100933#define ADD( i ) add64( p, A( i ), &c )
934#define NEXT p += WIDTH; carry64( p, &c )
935#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
936
937/*
938 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
939 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200940static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100941{
Janos Follath24eed8d2019-11-22 13:21:35 +0000942 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 mbedtls_mpi_uint c = 0;
944 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100945
946 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100948
949 p = N->p;
950 end = p + N->n;
951
952 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
953 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
954 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
955
956cleanup:
957 return( ret );
958}
959
960#undef WIDTH
961#undef A
962#undef ADD
963#undef NEXT
964#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100966
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
968 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
969 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100970/*
971 * The reader is advised to first understand ecp_mod_p192() since the same
972 * general structure is used here, but with additional complications:
973 * (1) chunks of 32 bits, and (2) subtractions.
974 */
975
976/*
977 * For these primes, we need to handle data in chunks of 32 bits.
978 * This makes it more complicated if we use 64 bits limbs in MPI,
979 * which prevents us from using a uniform access method as for p192.
980 *
981 * So, we define a mini abstraction layer to access 32 bit chunks,
982 * load them in 'cur' for work, and store them back from 'cur' when done.
983 *
984 * While at it, also define the size of N in terms of 32-bit chunks.
985 */
986#define LOAD32 cur = A( i );
987
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200988#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100989
990#define MAX32 N->n
991#define A( j ) N->p[j]
992#define STORE32 N->p[i] = cur;
993
994#else /* 64-bit */
995
996#define MAX32 N->n * 2
Hanno Becker1eeca412018-10-15 12:01:35 +0100997#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
998 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100999#define STORE32 \
1000 if( i % 2 ) { \
1001 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001003 } else { \
1004 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001006 }
1007
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001009
1010/*
1011 * Helpers for addition and subtraction of chunks, with signed carry.
1012 */
1013static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
1014{
1015 *dst += src;
1016 *carry += ( *dst < src );
1017}
1018
1019static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
1020{
1021 *carry -= ( *dst < src );
1022 *dst -= src;
1023}
1024
1025#define ADD( j ) add32( &cur, A( j ), &c );
1026#define SUB( j ) sub32( &cur, A( j ), &c );
1027
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001028#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
Gilles Peskineb76517b2021-03-10 23:44:28 +01001029#define biL (ciL << 3) /* bits in limb */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001030
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001031/*
1032 * Helpers for the main 'loop'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001033 */
Hanno Becker1eeca412018-10-15 12:01:35 +01001034#define INIT( b ) \
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001035 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
Hanno Becker1eeca412018-10-15 12:01:35 +01001036 signed char c = 0, cc; \
1037 uint32_t cur; \
1038 size_t i = 0, bits = (b); \
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001039 /* N is the size of the product of two b-bit numbers, plus one */ \
1040 /* limb for fix_negative */ \
1041 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, ( b ) * 2 / biL + 1 ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001042 LOAD32;
1043
1044#define NEXT \
1045 STORE32; i++; LOAD32; \
1046 cc = c; c = 0; \
1047 if( cc < 0 ) \
1048 sub32( &cur, -cc, &c ); \
1049 else \
1050 add32( &cur, cc, &c ); \
1051
1052#define LAST \
1053 STORE32; i++; \
1054 cur = c > 0 ? c : 0; STORE32; \
1055 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine618be2e2021-04-03 21:47:53 +02001056 if( c < 0 ) mbedtls_ecp_fix_negative( N, c, bits );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001057
1058/*
1059 * If the result is negative, we get it in the form
Gilles Peskine349b3722021-04-03 21:40:11 +02001060 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001061 */
Gilles Peskine618be2e2021-04-03 21:47:53 +02001062MBEDTLS_STATIC_TESTABLE
1063void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001064{
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001065 size_t i;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001066
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001067 /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
1068 * set the absolute value to 0xfff...fff - N. There is no carry
1069 * since we're subtracting from all-bits-one. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001070 for( i = 0; i <= bits / 8 / sizeof( mbedtls_mpi_uint ); i++ )
1071 {
1072 N->p[i] = ~(mbedtls_mpi_uint)0 - N->p[i];
1073 }
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001074 /* Add 1, taking care of the carry. */
1075 i = 0;
1076 do
1077 ++N->p[i];
1078 while( N->p[i++] == 0 && i <= bits / 8 / sizeof( mbedtls_mpi_uint ) );
1079 /* Invert the sign.
1080 * Now N = N0 - 2^bits where N0 is the initial value of N. */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001081 N->s = -1;
1082
Gilles Peskine349b3722021-04-03 21:40:11 +02001083 /* Add |c| * 2^bits to the absolute value. Since c and N are
1084 * negative, this adds c * 2^bits. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001085 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1086#if defined(MBEDTLS_HAVE_INT64)
1087 if( bits == 224 )
1088 msw <<= 32;
1089#endif
1090 N->p[bits / 8 / sizeof( mbedtls_mpi_uint)] += msw;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001091}
1092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001094/*
1095 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1096 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001098{
1099 INIT( 224 );
1100
1101 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1102 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1103 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1104 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1105 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1106 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1107 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1108
1109cleanup:
1110 return( ret );
1111}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001115/*
1116 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1117 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001119{
1120 INIT( 256 );
1121
1122 ADD( 8 ); ADD( 9 );
1123 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1124
1125 ADD( 9 ); ADD( 10 );
1126 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1127
1128 ADD( 10 ); ADD( 11 );
1129 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1130
1131 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1132 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1133
1134 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1135 SUB( 9 ); SUB( 10 ); NEXT; // A4
1136
1137 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1138 SUB( 10 ); SUB( 11 ); NEXT; // A5
1139
1140 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1141 SUB( 8 ); SUB( 9 ); NEXT; // A6
1142
1143 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1144 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1145
1146cleanup:
1147 return( ret );
1148}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001149#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001150
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001152/*
1153 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1154 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001156{
1157 INIT( 384 );
1158
1159 ADD( 12 ); ADD( 21 ); ADD( 20 );
1160 SUB( 23 ); NEXT; // A0
1161
1162 ADD( 13 ); ADD( 22 ); ADD( 23 );
1163 SUB( 12 ); SUB( 20 ); NEXT; // A2
1164
1165 ADD( 14 ); ADD( 23 );
1166 SUB( 13 ); SUB( 21 ); NEXT; // A2
1167
1168 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1169 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1170
1171 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1172 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1173
1174 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1175 SUB( 16 ); NEXT; // A5
1176
1177 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1178 SUB( 17 ); NEXT; // A6
1179
1180 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1181 SUB( 18 ); NEXT; // A7
1182
1183 ADD( 20 ); ADD( 17 ); ADD( 16 );
1184 SUB( 19 ); NEXT; // A8
1185
1186 ADD( 21 ); ADD( 18 ); ADD( 17 );
1187 SUB( 20 ); NEXT; // A9
1188
1189 ADD( 22 ); ADD( 19 ); ADD( 18 );
1190 SUB( 21 ); NEXT; // A10
1191
1192 ADD( 23 ); ADD( 20 ); ADD( 19 );
1193 SUB( 22 ); LAST; // A11
1194
1195cleanup:
1196 return( ret );
1197}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001199
1200#undef A
1201#undef LOAD32
1202#undef STORE32
1203#undef MAX32
1204#undef INIT
1205#undef NEXT
1206#undef LAST
1207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001208#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1209 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1210 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001212#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001213/*
1214 * Here we have an actual Mersenne prime, so things are more straightforward.
1215 * However, chunks are aligned on a 'weird' boundary (521 bits).
1216 */
1217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218/* Size of p521 in terms of mbedtls_mpi_uint */
1219#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001220
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001221/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001222#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001223
1224/*
1225 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1226 * Write N as A1 + 2^521 A0, return A0 + A1
1227 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001228static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001229{
Janos Follath24eed8d2019-11-22 13:21:35 +00001230 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001231 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232 mbedtls_mpi M;
1233 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1234 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001235 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1236 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1237
1238 if( N->n < P521_WIDTH )
1239 return( 0 );
1240
1241 /* M = A1 */
1242 M.s = 1;
1243 M.n = N->n - ( P521_WIDTH - 1 );
1244 if( M.n > P521_WIDTH + 1 )
1245 M.n = P521_WIDTH + 1;
1246 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001247 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1248 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001249
1250 /* N = A0 */
1251 N->p[P521_WIDTH - 1] &= P521_MASK;
1252 for( i = P521_WIDTH; i < N->n; i++ )
1253 N->p[i] = 0;
1254
1255 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001256 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001257
1258cleanup:
1259 return( ret );
1260}
1261
1262#undef P521_WIDTH
1263#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001264#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001266#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001267
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001268#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270/* Size of p255 in terms of mbedtls_mpi_uint */
1271#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001272
1273/*
1274 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001275 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001276 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001277static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001278{
Janos Follath24eed8d2019-11-22 13:21:35 +00001279 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001280 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001281 mbedtls_mpi M;
1282 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001283
1284 if( N->n < P255_WIDTH )
1285 return( 0 );
1286
1287 /* M = A1 */
1288 M.s = 1;
1289 M.n = N->n - ( P255_WIDTH - 1 );
1290 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001291 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001292 M.p = Mp;
1293 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1295 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001296 M.n++; /* Make room for multiplication by 19 */
1297
1298 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001300 for( i = P255_WIDTH; i < N->n; i++ )
1301 N->p[i] = 0;
1302
1303 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001304 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1305 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001306
1307cleanup:
1308 return( ret );
1309}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001310#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001311
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001312#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1313
1314/* Size of p448 in terms of mbedtls_mpi_uint */
1315#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1316
1317/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1318#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1319#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1320#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1321#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1322
1323/*
1324 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1325 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1326 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1327 * implementation of Curve448, which uses its own special 56-bit limbs rather
1328 * than a generic bignum library. We could squeeze some extra speed out on
1329 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1330 * arithmetic using the limbs directly as we do for the NIST primes above,
1331 * but for 64-bit targets it should use half the number of operations if we do
1332 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1333 */
1334static int ecp_mod_p448( mbedtls_mpi *N )
1335{
Janos Follath24eed8d2019-11-22 13:21:35 +00001336 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001337 size_t i;
1338 mbedtls_mpi M, Q;
1339 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1340
1341 if( N->n <= P448_WIDTH )
1342 return( 0 );
1343
1344 /* M = A1 */
1345 M.s = 1;
1346 M.n = N->n - ( P448_WIDTH );
1347 if( M.n > P448_WIDTH )
1348 /* Shouldn't be called with N larger than 2^896! */
1349 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1350 M.p = Mp;
1351 memset( Mp, 0, sizeof( Mp ) );
1352 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1353
1354 /* N = A0 */
1355 for( i = P448_WIDTH; i < N->n; i++ )
1356 N->p[i] = 0;
1357
1358 /* N += A1 */
1359 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1360
1361 /* Q = B1, N += B1 */
1362 Q = M;
1363 Q.p = Qp;
1364 memcpy( Qp, Mp, sizeof( Qp ) );
1365 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1366 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1367
1368 /* M = (B0 + B1) * 2^224, N += M */
1369 if( sizeof( mbedtls_mpi_uint ) > 4 )
1370 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1371 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1372 Mp[i] = 0;
1373 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1374 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1375 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1376 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1377
1378cleanup:
1379 return( ret );
1380}
1381#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001383#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1384 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1385 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001386/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001387 * Fast quasi-reduction modulo P = 2^s - R,
1388 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001389 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001390 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001391 * Actually do two passes, since R is big.
1392 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001393#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1394#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1395static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1396 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001397{
Janos Follath24eed8d2019-11-22 13:21:35 +00001398 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001399 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001401 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001402
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001403 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001404 return( 0 );
1405
1406 /* Init R */
1407 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001408 R.p = Rp;
1409 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001410
1411 /* Common setup for M */
1412 M.s = 1;
1413 M.p = Mp;
1414
1415 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001416 M.n = N->n - ( p_limbs - adjust );
1417 if( M.n > p_limbs + adjust )
1418 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001419 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001421 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001423 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001424
1425 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001426 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001427 N->p[p_limbs - 1] &= mask;
1428 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001429 N->p[i] = 0;
1430
1431 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1433 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001434
1435 /* Second pass */
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
1457cleanup:
1458 return( ret );
1459}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001460#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1461 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1462 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001464#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001465/*
1466 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1467 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1468 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001469static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001470{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001471 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001472 BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001474 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001475}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001478#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001479/*
1480 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1481 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1482 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001483static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001484{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001485 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001486 BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001488#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001489 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1490#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001492#endif
1493}
1494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001498/*
1499 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1500 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1501 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001503{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001505 BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001507}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001509
Janos Follathb0697532016-08-18 12:38:46 +01001510#endif /* !MBEDTLS_ECP_ALT */
1511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001512#endif /* MBEDTLS_ECP_C */