blob: 7e87acb60a5014c0b76094785f5ecca031dba6a2 [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"
Janos Follathbc96a792021-06-24 14:48:38 +010027#include "mbedtls/bn_mul.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010028
Gilles Peskine618be2e2021-04-03 21:47:53 +020029#include "ecp_invasive.h"
30
Rich Evans00ab4702015-02-06 13:43:58 +000031#include <string.h>
32
Janos Follathb0697532016-08-18 12:38:46 +010033#if !defined(MBEDTLS_ECP_ALT)
34
Hanno Becker4f8e8e52018-12-14 15:08:03 +000035/* Parameter validation macros based on platform_util.h */
36#define ECP_VALIDATE_RET( cond ) \
37 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA )
38#define ECP_VALIDATE( cond ) \
39 MBEDTLS_INTERNAL_VALIDATE( cond )
40
Manuel Pégourié-Gonnard0223ab92015-10-05 11:40:01 +010041#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
42 !defined(inline) && !defined(__cplusplus)
Paul Bakker498fd352013-12-02 22:17:24 +010043#define inline __inline
Manuel Pégourié-Gonnard20af64d2015-07-07 18:33:39 +020044#endif
Paul Bakker498fd352013-12-02 22:17:24 +010045
Manuel Pégourié-Gonnard10b8e5a2021-06-23 12:25:48 +020046#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
47
48#define ECP_MPI_INIT_ARRAY(x) \
49 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
50
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010051/*
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010052 * Note: the constants are in little-endian order
53 * to be directly usable in MPIs
54 */
55
56/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010057 * Domain parameters for secp192r1
58 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
60static const mbedtls_mpi_uint secp192r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010061 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
62 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
63 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010064};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065static const mbedtls_mpi_uint secp192r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010066 BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
67 BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
68 BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010069};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070static const mbedtls_mpi_uint secp192r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010071 BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
72 BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
73 BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010074};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075static const mbedtls_mpi_uint secp192r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010076 BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
77 BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
78 BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010079};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080static const mbedtls_mpi_uint secp192r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010081 BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
82 BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
83 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010084};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010086
87/*
88 * Domain parameters for secp224r1
89 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020090#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
91static const mbedtls_mpi_uint secp224r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010092 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
93 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
94 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
95 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010096};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020097static const mbedtls_mpi_uint secp224r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +010098 BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
99 BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
100 BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100101 BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100102};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103static const mbedtls_mpi_uint secp224r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100104 BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
105 BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
106 BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100107 BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100108};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109static const mbedtls_mpi_uint secp224r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100110 BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
111 BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
112 BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100113 BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100114};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115static const mbedtls_mpi_uint secp224r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100116 BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
117 BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
118 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100119 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100120};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100122
123/*
124 * Domain parameters for secp256r1
125 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
127static const mbedtls_mpi_uint secp256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100128 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
129 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
130 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
131 BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100132};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133static const mbedtls_mpi_uint secp256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100134 BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
135 BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
136 BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
137 BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100138};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139static const mbedtls_mpi_uint secp256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100140 BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
141 BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
142 BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
143 BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100144};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145static const mbedtls_mpi_uint secp256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100146 BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
147 BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
148 BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
149 BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100150};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200151static const mbedtls_mpi_uint secp256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100152 BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
153 BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
154 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
155 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100156};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100158
159/*
160 * Domain parameters for secp384r1
161 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
163static const mbedtls_mpi_uint secp384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100164 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
165 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
166 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
167 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
168 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
169 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 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 secp384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100172 BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
173 BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
174 BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
175 BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
176 BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
177 BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100178};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200179static const mbedtls_mpi_uint secp384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100180 BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
181 BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
182 BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
183 BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
184 BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
185 BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100186};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187static const mbedtls_mpi_uint secp384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100188 BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
189 BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
190 BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
191 BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
192 BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
193 BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100194};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195static const mbedtls_mpi_uint secp384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100196 BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
197 BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
198 BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
199 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
200 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
201 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100202};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100204
205/*
206 * Domain parameters for secp521r1
207 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
209static const mbedtls_mpi_uint secp521r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100210 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
211 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
212 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
213 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
214 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
215 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
216 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
217 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100218 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100219};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220static const mbedtls_mpi_uint secp521r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100221 BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
222 BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
223 BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
224 BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
225 BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
226 BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
227 BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
228 BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100229 BYTES_TO_T_UINT_2( 0x51, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100230};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231static const mbedtls_mpi_uint secp521r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100232 BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
233 BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
234 BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
235 BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
236 BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
237 BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
238 BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
239 BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100240 BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100241};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242static const mbedtls_mpi_uint secp521r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100243 BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
244 BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
245 BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
246 BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
247 BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
248 BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
249 BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
250 BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100251 BYTES_TO_T_UINT_2( 0x18, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100252};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200253static const mbedtls_mpi_uint secp521r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100254 BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
255 BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
256 BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
257 BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
258 BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
259 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
260 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
261 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +0100262 BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100263};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200264#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
267static const mbedtls_mpi_uint secp192k1_p[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100268 BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
269 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
270 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
271};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272static const mbedtls_mpi_uint secp192k1_a[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100273 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
274};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275static const mbedtls_mpi_uint secp192k1_b[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100276 BYTES_TO_T_UINT_2( 0x03, 0x00 ),
277};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200278static const mbedtls_mpi_uint secp192k1_gx[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100279 BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
280 BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
281 BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
282};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283static const mbedtls_mpi_uint secp192k1_gy[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100284 BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
285 BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
286 BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
287};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288static const mbedtls_mpi_uint secp192k1_n[] = {
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100289 BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
290 BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
291 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
292};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200293#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
296static const mbedtls_mpi_uint secp224k1_p[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100297 BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 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 ),
300 BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
301};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302static const mbedtls_mpi_uint secp224k1_a[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100303 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
304};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305static const mbedtls_mpi_uint secp224k1_b[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100306 BYTES_TO_T_UINT_2( 0x05, 0x00 ),
307};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308static const mbedtls_mpi_uint secp224k1_gx[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100309 BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
310 BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
311 BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
312 BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
313};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314static const mbedtls_mpi_uint secp224k1_gy[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100315 BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
316 BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
317 BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
318 BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
319};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320static const mbedtls_mpi_uint secp224k1_n[] = {
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100321 BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
322 BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
323 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
324 BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
325};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
329static const mbedtls_mpi_uint secp256k1_p[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100330 BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
331 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
332 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
333 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
334};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335static const mbedtls_mpi_uint secp256k1_a[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100336 BYTES_TO_T_UINT_2( 0x00, 0x00 ),
337};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338static const mbedtls_mpi_uint secp256k1_b[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100339 BYTES_TO_T_UINT_2( 0x07, 0x00 ),
340};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341static const mbedtls_mpi_uint secp256k1_gx[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100342 BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
343 BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
344 BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
345 BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
346};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347static const mbedtls_mpi_uint secp256k1_gy[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100348 BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
349 BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
350 BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
351 BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
352};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353static const mbedtls_mpi_uint secp256k1_n[] = {
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100354 BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
355 BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
356 BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
357 BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
358};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100360
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100361/*
362 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
363 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
365static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100366 BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
367 BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
368 BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
369 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100370};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100372 BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
373 BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
374 BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
375 BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100376};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100378 BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
379 BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
380 BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
381 BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100382};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100384 BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
385 BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
386 BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
387 BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100388};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100390 BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
391 BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
392 BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
393 BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100394};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100396 BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
397 BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
398 BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
399 BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100400};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100402
403/*
404 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
405 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
407static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100408 BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
409 BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
410 BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
411 BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
412 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
413 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100414};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100416 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
417 BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
418 BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
419 BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
420 BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
421 BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100422};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100424 BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
425 BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
426 BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
427 BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
428 BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
429 BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100430};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100432 BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
433 BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
434 BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
435 BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
436 BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
437 BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100438};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100440 BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
441 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
442 BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
443 BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
444 BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
445 BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100446};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100448 BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
449 BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
450 BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
451 BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
452 BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
453 BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100454};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100456
457/*
458 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
459 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
461static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100462 BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
463 BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
464 BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
465 BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
466 BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
467 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
468 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
469 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100470};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100472 BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
473 BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
474 BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
475 BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
476 BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
477 BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
478 BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
479 BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100480};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100482 BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
483 BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
484 BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
485 BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
486 BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
487 BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
488 BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
489 BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100490};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100492 BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
493 BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
494 BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
495 BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
496 BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
497 BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
498 BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
499 BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100500};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100502 BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
503 BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
504 BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
505 BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
506 BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
507 BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
508 BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
509 BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100510};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Manuel Pégourié-Gonnard95b45b72013-12-11 12:03:23 +0100512 BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
513 BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
514 BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
515 BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
516 BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
517 BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
518 BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
519 BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100520};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100522
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200523#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
524 defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
525 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
526 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
527 defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
528 defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
529 defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
530 defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
531 defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
532 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
533 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
534/* For these curves, we build the group parameters dynamically. */
535#define ECP_LOAD_GROUP
536#endif
537
538#if defined(ECP_LOAD_GROUP)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100539/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100540 * Create an MPI from embedded constants
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100542 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543static 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 +0100544{
545 X->s = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546 X->n = len / sizeof( mbedtls_mpi_uint );
547 X->p = (mbedtls_mpi_uint *) p;
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100548}
549
550/*
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100551 * Set an MPI to static value 1
552 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553static inline void ecp_mpi_set1( mbedtls_mpi *X )
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100554{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555 static mbedtls_mpi_uint one[] = { 1 };
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100556 X->s = 1;
557 X->n = 1;
558 X->p = one;
559}
560
561/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100562 * Make group available from embedded constants
563 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564static int ecp_group_load( mbedtls_ecp_group *grp,
565 const mbedtls_mpi_uint *p, size_t plen,
566 const mbedtls_mpi_uint *a, size_t alen,
567 const mbedtls_mpi_uint *b, size_t blen,
568 const mbedtls_mpi_uint *gx, size_t gxlen,
569 const mbedtls_mpi_uint *gy, size_t gylen,
570 const mbedtls_mpi_uint *n, size_t nlen)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100571{
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100572 ecp_mpi_load( &grp->P, p, plen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100573 if( a != NULL )
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100574 ecp_mpi_load( &grp->A, a, alen );
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100575 ecp_mpi_load( &grp->B, b, blen );
576 ecp_mpi_load( &grp->N, n, nlen );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100577
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100578 ecp_mpi_load( &grp->G.X, gx, gxlen );
579 ecp_mpi_load( &grp->G.Y, gy, gylen );
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100580 ecp_mpi_set1( &grp->G.Z );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100581
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200582 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
583 grp->nbits = mbedtls_mpi_bitlen( &grp->N );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100584
Manuel Pégourié-Gonnard1f82b042013-12-06 12:51:50 +0100585 grp->h = 1;
586
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100587 return( 0 );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100588}
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200589#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100590
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100592/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
594static int ecp_mod_p192( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100595#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
597static int ecp_mod_p224( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100598#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200599#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
600static int ecp_mod_p256( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100601#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
603static int ecp_mod_p384( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100604#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
606static int ecp_mod_p521( mbedtls_mpi * );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100607#endif
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100608
609#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P;
610#else
611#define NIST_MODP( P )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100613
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100614/* Additional forward declarations */
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200615#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616static int ecp_mod_p255( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100617#endif
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000618#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
619static int ecp_mod_p448( mbedtls_mpi * );
620#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
622static int ecp_mod_p192k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100623#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
625static int ecp_mod_p224k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100626#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
628static int ecp_mod_p256k1( mbedtls_mpi * );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100629#endif
630
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200631#if defined(ECP_LOAD_GROUP)
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100632#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
633 G ## _p, sizeof( G ## _p ), \
634 G ## _a, sizeof( G ## _a ), \
635 G ## _b, sizeof( G ## _b ), \
636 G ## _gx, sizeof( G ## _gx ), \
637 G ## _gy, sizeof( G ## _gy ), \
638 G ## _n, sizeof( G ## _n ) )
639
640#define LOAD_GROUP( G ) ecp_group_load( grp, \
641 G ## _p, sizeof( G ## _p ), \
642 NULL, 0, \
643 G ## _b, sizeof( G ## _b ), \
644 G ## _gx, sizeof( G ## _gx ), \
645 G ## _gy, sizeof( G ## _gy ), \
646 G ## _n, sizeof( G ## _n ) )
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200647#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100648
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200649#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200650/* Constants used by ecp_use_curve25519() */
Janos Follath1c6a4392021-06-24 15:00:33 +0100651static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200652static const unsigned char curve25519_part_of_n[] = {
653 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
654 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
655};
656
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100657/*
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100658 * Specialized function for creating the Curve25519 group
659 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660static int ecp_use_curve25519( mbedtls_ecp_group *grp )
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100661{
Janos Follath24eed8d2019-11-22 13:21:35 +0000662 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100663
664 /* Actually ( A + 2 ) / 4 */
Janos Follath1c6a4392021-06-24 15:00:33 +0100665 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100666
667 /* P = 2^255 - 19 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
669 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
670 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200671 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100672
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100673 /* N = 2^252 + 27742317777372353535851937790883648493 */
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200674 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &grp->N,
675 curve25519_part_of_n, sizeof( curve25519_part_of_n ) ) );
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100676 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 252, 1 ) );
677
Manuel Pégourié-Gonnard18b78432018-03-28 11:14:06 +0200678 /* Y intentionally not set, since we use x/z coordinates.
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100679 * This is used as a marker to identify Montgomery curves! */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
681 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
682 mbedtls_mpi_free( &grp->G.Y );
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100683
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100684 /* Actually, the required msb for private keys */
685 grp->nbits = 254;
686
687cleanup:
688 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100690
691 return( ret );
692}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200693#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100694
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000695#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200696/* Constants used by ecp_use_curve448() */
Janos Follath1c6a4392021-06-24 15:00:33 +0100697static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200698static const unsigned char curve448_part_of_n[] = {
699 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
700 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
701 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
702 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
703};
704
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000705/*
706 * Specialized function for creating the Curve448 group
707 */
708static int ecp_use_curve448( mbedtls_ecp_group *grp )
709{
710 mbedtls_mpi Ns;
Janos Follath24eed8d2019-11-22 13:21:35 +0000711 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000712
713 mbedtls_mpi_init( &Ns );
714
715 /* Actually ( A + 2 ) / 4 */
Janos Follath1c6a4392021-06-24 15:00:33 +0100716 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve448_a24 ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000717
718 /* P = 2^448 - 2^224 - 1 */
719 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
720 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
721 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
722 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 224 ) );
723 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 1 ) );
724 grp->pbits = mbedtls_mpi_bitlen( &grp->P );
725
726 /* Y intentionally not set, since we use x/z coordinates.
727 * This is used as a marker to identify Montgomery curves! */
728 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 5 ) );
729 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
730 mbedtls_mpi_free( &grp->G.Y );
731
732 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
733 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &grp->N, 446, 1 ) );
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200734 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &Ns,
735 curve448_part_of_n, sizeof( curve448_part_of_n ) ) );
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000736 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &grp->N, &grp->N, &Ns ) );
737
738 /* Actually, the required msb for private keys */
739 grp->nbits = 447;
740
741cleanup:
742 mbedtls_mpi_free( &Ns );
743 if( ret != 0 )
744 mbedtls_ecp_group_free( grp );
745
746 return( ret );
747}
748#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
749
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100750/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100751 * Set a group using well-known domain parameters
752 */
Manuel Pégourié-Gonnarde3a062b2015-05-11 18:46:47 +0200753int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100754{
Hanno Becker4f8e8e52018-12-14 15:08:03 +0000755 ECP_VALIDATE_RET( grp != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 mbedtls_ecp_group_free( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100757
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100758 grp->id = id;
759
760 switch( id )
761 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200762#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
763 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100764 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100765 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200766#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100767
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
769 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100770 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100771 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100773
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
775 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100776 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100777 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200778#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100779
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
781 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100782 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100783 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100785
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
787 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100788 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100789 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100791
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
793 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100794 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100795 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100797
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
799 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100800 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100801 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200802#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100803
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200804#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
805 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100806 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100807 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100809
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
811 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100812 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100814
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
816 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100817 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818#endif /* MBEDTLS_ECP_DP_BP384R1_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_BP512R1_ENABLED)
821 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100822 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100824
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200825#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
826 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100827 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100828 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200829#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100830
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000831#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
832 case MBEDTLS_ECP_DP_CURVE448:
833 grp->modp = ecp_mod_p448;
834 return( ecp_use_curve448( grp ) );
835#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
836
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100837 default:
Alexander K56a74cd2019-09-10 17:58:20 +0300838 grp->id = MBEDTLS_ECP_DP_NONE;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100840 }
841}
842
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100844/*
845 * Fast reduction modulo the primes used by the NIST curves.
846 *
847 * These functions are critical for speed, but not needed for correct
848 * operations. So, we make the choice to heavily rely on the internals of our
849 * bignum library, which creates a tight coupling between these functions and
850 * our MPI implementation. However, the coupling between the ECP module and
851 * MPI remains loose, since these functions can be deactivated at will.
852 */
853
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200854#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100855/*
856 * Compared to the way things are presented in FIPS 186-3 D.2,
857 * we proceed in columns, from right (least significant chunk) to left,
858 * adding chunks to N in place, and keeping a carry for the next chunk.
859 * This avoids moving things around in memory, and uselessly adding zeros,
860 * compared to the more straightforward, line-oriented approach.
861 *
862 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
864 * 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 +0100865 */
866
867/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100869{
870 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 mbedtls_mpi_uint c = 0;
872 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100873 {
874 *dst += c; c = ( *dst < c );
875 *dst += *src; c += ( *dst < *src );
876 }
877 *carry += c;
878}
879
880/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100882{
883 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100885 {
886 *dst += *carry;
887 *carry = ( *dst < *carry );
888 }
889}
890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Becker1eeca412018-10-15 12:01:35 +0100892#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100893#define ADD( i ) add64( p, A( i ), &c )
894#define NEXT p += WIDTH; carry64( p, &c )
895#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
896
897/*
898 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
899 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100901{
Janos Follath24eed8d2019-11-22 13:21:35 +0000902 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_mpi_uint c = 0;
904 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100905
906 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100908
909 p = N->p;
910 end = p + N->n;
911
912 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
913 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
914 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
915
916cleanup:
917 return( ret );
918}
919
920#undef WIDTH
921#undef A
922#undef ADD
923#undef NEXT
924#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100926
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
928 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
929 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100930/*
931 * The reader is advised to first understand ecp_mod_p192() since the same
932 * general structure is used here, but with additional complications:
933 * (1) chunks of 32 bits, and (2) subtractions.
934 */
935
936/*
937 * For these primes, we need to handle data in chunks of 32 bits.
938 * This makes it more complicated if we use 64 bits limbs in MPI,
939 * which prevents us from using a uniform access method as for p192.
940 *
941 * So, we define a mini abstraction layer to access 32 bit chunks,
942 * load them in 'cur' for work, and store them back from 'cur' when done.
943 *
944 * While at it, also define the size of N in terms of 32-bit chunks.
945 */
946#define LOAD32 cur = A( i );
947
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200948#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100949
950#define MAX32 N->n
951#define A( j ) N->p[j]
952#define STORE32 N->p[i] = cur;
953
954#else /* 64-bit */
955
956#define MAX32 N->n * 2
Hanno Becker1eeca412018-10-15 12:01:35 +0100957#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
958 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100959#define STORE32 \
960 if( i % 2 ) { \
961 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200962 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100963 } else { \
964 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100966 }
967
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100969
970/*
971 * Helpers for addition and subtraction of chunks, with signed carry.
972 */
973static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
974{
975 *dst += src;
976 *carry += ( *dst < src );
977}
978
979static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
980{
981 *carry -= ( *dst < src );
982 *dst -= src;
983}
984
985#define ADD( j ) add32( &cur, A( j ), &c );
986#define SUB( j ) sub32( &cur, A( j ), &c );
987
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200988#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
Gilles Peskineb76517b2021-03-10 23:44:28 +0100989#define biL (ciL << 3) /* bits in limb */
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200990
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100991/*
992 * Helpers for the main 'loop'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100993 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100994#define INIT( b ) \
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200995 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100996 signed char c = 0, cc; \
997 uint32_t cur; \
998 size_t i = 0, bits = (b); \
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200999 /* N is the size of the product of two b-bit numbers, plus one */ \
1000 /* limb for fix_negative */ \
1001 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, ( b ) * 2 / biL + 1 ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001002 LOAD32;
1003
1004#define NEXT \
1005 STORE32; i++; LOAD32; \
1006 cc = c; c = 0; \
1007 if( cc < 0 ) \
1008 sub32( &cur, -cc, &c ); \
1009 else \
1010 add32( &cur, cc, &c ); \
1011
1012#define LAST \
1013 STORE32; i++; \
1014 cur = c > 0 ? c : 0; STORE32; \
1015 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine618be2e2021-04-03 21:47:53 +02001016 if( c < 0 ) mbedtls_ecp_fix_negative( N, c, bits );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001017
1018/*
1019 * If the result is negative, we get it in the form
Gilles Peskine349b3722021-04-03 21:40:11 +02001020 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001021 */
Gilles Peskine618be2e2021-04-03 21:47:53 +02001022MBEDTLS_STATIC_TESTABLE
1023void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001024{
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001025 size_t i;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001026
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001027 /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
1028 * set the absolute value to 0xfff...fff - N. There is no carry
1029 * since we're subtracting from all-bits-one. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001030 for( i = 0; i <= bits / 8 / sizeof( mbedtls_mpi_uint ); i++ )
1031 {
1032 N->p[i] = ~(mbedtls_mpi_uint)0 - N->p[i];
1033 }
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001034 /* Add 1, taking care of the carry. */
1035 i = 0;
1036 do
1037 ++N->p[i];
1038 while( N->p[i++] == 0 && i <= bits / 8 / sizeof( mbedtls_mpi_uint ) );
1039 /* Invert the sign.
1040 * Now N = N0 - 2^bits where N0 is the initial value of N. */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001041 N->s = -1;
1042
Gilles Peskine349b3722021-04-03 21:40:11 +02001043 /* Add |c| * 2^bits to the absolute value. Since c and N are
1044 * negative, this adds c * 2^bits. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001045 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1046#if defined(MBEDTLS_HAVE_INT64)
1047 if( bits == 224 )
1048 msw <<= 32;
1049#endif
1050 N->p[bits / 8 / sizeof( mbedtls_mpi_uint)] += msw;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001051}
1052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001054/*
1055 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1056 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001058{
1059 INIT( 224 );
1060
1061 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1062 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1063 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1064 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1065 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1066 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1067 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1068
1069cleanup:
1070 return( ret );
1071}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001075/*
1076 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1077 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001079{
1080 INIT( 256 );
1081
1082 ADD( 8 ); ADD( 9 );
1083 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1084
1085 ADD( 9 ); ADD( 10 );
1086 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1087
1088 ADD( 10 ); ADD( 11 );
1089 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1090
1091 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1092 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1093
1094 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1095 SUB( 9 ); SUB( 10 ); NEXT; // A4
1096
1097 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1098 SUB( 10 ); SUB( 11 ); NEXT; // A5
1099
1100 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1101 SUB( 8 ); SUB( 9 ); NEXT; // A6
1102
1103 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1104 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1105
1106cleanup:
1107 return( ret );
1108}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001112/*
1113 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1114 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001116{
1117 INIT( 384 );
1118
1119 ADD( 12 ); ADD( 21 ); ADD( 20 );
1120 SUB( 23 ); NEXT; // A0
1121
1122 ADD( 13 ); ADD( 22 ); ADD( 23 );
1123 SUB( 12 ); SUB( 20 ); NEXT; // A2
1124
1125 ADD( 14 ); ADD( 23 );
1126 SUB( 13 ); SUB( 21 ); NEXT; // A2
1127
1128 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1129 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1130
1131 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1132 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1133
1134 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1135 SUB( 16 ); NEXT; // A5
1136
1137 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1138 SUB( 17 ); NEXT; // A6
1139
1140 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1141 SUB( 18 ); NEXT; // A7
1142
1143 ADD( 20 ); ADD( 17 ); ADD( 16 );
1144 SUB( 19 ); NEXT; // A8
1145
1146 ADD( 21 ); ADD( 18 ); ADD( 17 );
1147 SUB( 20 ); NEXT; // A9
1148
1149 ADD( 22 ); ADD( 19 ); ADD( 18 );
1150 SUB( 21 ); NEXT; // A10
1151
1152 ADD( 23 ); ADD( 20 ); ADD( 19 );
1153 SUB( 22 ); LAST; // A11
1154
1155cleanup:
1156 return( ret );
1157}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001159
1160#undef A
1161#undef LOAD32
1162#undef STORE32
1163#undef MAX32
1164#undef INIT
1165#undef NEXT
1166#undef LAST
1167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001168#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1169 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1170 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001173/*
1174 * Here we have an actual Mersenne prime, so things are more straightforward.
1175 * However, chunks are aligned on a 'weird' boundary (521 bits).
1176 */
1177
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178/* Size of p521 in terms of mbedtls_mpi_uint */
1179#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001181/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001182#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001183
1184/*
1185 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1186 * Write N as A1 + 2^521 A0, return A0 + A1
1187 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001188static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001189{
Janos Follath24eed8d2019-11-22 13:21:35 +00001190 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001191 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001192 mbedtls_mpi M;
1193 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1194 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001195 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1196 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1197
1198 if( N->n < P521_WIDTH )
1199 return( 0 );
1200
1201 /* M = A1 */
1202 M.s = 1;
1203 M.n = N->n - ( P521_WIDTH - 1 );
1204 if( M.n > P521_WIDTH + 1 )
1205 M.n = P521_WIDTH + 1;
1206 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001207 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1208 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001209
1210 /* N = A0 */
1211 N->p[P521_WIDTH - 1] &= P521_MASK;
1212 for( i = P521_WIDTH; i < N->n; i++ )
1213 N->p[i] = 0;
1214
1215 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001217
1218cleanup:
1219 return( ret );
1220}
1221
1222#undef P521_WIDTH
1223#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001225
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001226#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001227
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001228#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230/* Size of p255 in terms of mbedtls_mpi_uint */
1231#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001232
1233/*
1234 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001235 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001236 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001238{
Janos Follath24eed8d2019-11-22 13:21:35 +00001239 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001240 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 mbedtls_mpi M;
1242 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001243
1244 if( N->n < P255_WIDTH )
1245 return( 0 );
1246
1247 /* M = A1 */
1248 M.s = 1;
1249 M.n = N->n - ( P255_WIDTH - 1 );
1250 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001251 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001252 M.p = Mp;
1253 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001254 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1255 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001256 M.n++; /* Make room for multiplication by 19 */
1257
1258 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001259 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001260 for( i = P255_WIDTH; i < N->n; i++ )
1261 N->p[i] = 0;
1262
1263 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001264 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1265 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001266
1267cleanup:
1268 return( ret );
1269}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001270#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001271
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001272#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1273
1274/* Size of p448 in terms of mbedtls_mpi_uint */
1275#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1276
1277/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1278#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1279#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1280#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1281#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1282
1283/*
1284 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1285 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1286 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1287 * implementation of Curve448, which uses its own special 56-bit limbs rather
1288 * than a generic bignum library. We could squeeze some extra speed out on
1289 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1290 * arithmetic using the limbs directly as we do for the NIST primes above,
1291 * but for 64-bit targets it should use half the number of operations if we do
1292 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1293 */
1294static int ecp_mod_p448( mbedtls_mpi *N )
1295{
Janos Follath24eed8d2019-11-22 13:21:35 +00001296 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001297 size_t i;
1298 mbedtls_mpi M, Q;
1299 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1300
1301 if( N->n <= P448_WIDTH )
1302 return( 0 );
1303
1304 /* M = A1 */
1305 M.s = 1;
1306 M.n = N->n - ( P448_WIDTH );
1307 if( M.n > P448_WIDTH )
1308 /* Shouldn't be called with N larger than 2^896! */
1309 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1310 M.p = Mp;
1311 memset( Mp, 0, sizeof( Mp ) );
1312 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1313
1314 /* N = A0 */
1315 for( i = P448_WIDTH; i < N->n; i++ )
1316 N->p[i] = 0;
1317
1318 /* N += A1 */
1319 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1320
1321 /* Q = B1, N += B1 */
1322 Q = M;
1323 Q.p = Qp;
1324 memcpy( Qp, Mp, sizeof( Qp ) );
1325 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1326 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1327
1328 /* M = (B0 + B1) * 2^224, N += M */
1329 if( sizeof( mbedtls_mpi_uint ) > 4 )
1330 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1331 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1332 Mp[i] = 0;
1333 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1334 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1335 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1336 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1337
1338cleanup:
1339 return( ret );
1340}
1341#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001343#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1344 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1345 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001346/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001347 * Fast quasi-reduction modulo P = 2^s - R,
1348 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001349 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001350 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001351 * Actually do two passes, since R is big.
1352 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001353#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1354#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1355static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1356 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001357{
Janos Follath24eed8d2019-11-22 13:21:35 +00001358 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001359 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001360 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001361 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001362
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001363 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001364 return( 0 );
1365
1366 /* Init R */
1367 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001368 R.p = Rp;
1369 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001370
1371 /* Common setup for M */
1372 M.s = 1;
1373 M.p = Mp;
1374
1375 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001376 M.n = N->n - ( p_limbs - adjust );
1377 if( M.n > p_limbs + adjust )
1378 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001379 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001380 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001381 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001382 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001383 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001384
1385 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001386 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001387 N->p[p_limbs - 1] &= mask;
1388 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001389 N->p[i] = 0;
1390
1391 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001392 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1393 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001394
1395 /* Second pass */
1396
1397 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001398 M.n = N->n - ( p_limbs - adjust );
1399 if( M.n > p_limbs + adjust )
1400 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001401 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001402 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001403 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001404 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001405 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001406
1407 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001408 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001409 N->p[p_limbs - 1] &= mask;
1410 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001411 N->p[i] = 0;
1412
1413 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001414 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1415 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001416
1417cleanup:
1418 return( ret );
1419}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1421 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1422 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001423
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001424#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001425/*
1426 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1427 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1428 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001430{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001431 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001432 BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001434 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001435}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001436#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001438#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001439/*
1440 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1441 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1442 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001444{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001445 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001446 BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
1447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001449 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1450#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001451 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001452#endif
1453}
1454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001455#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001456
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001457#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001458/*
1459 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1460 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1461 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001462static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001463{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001464 static mbedtls_mpi_uint Rp[] = {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001465 BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001467}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001469
Janos Follathb0697532016-08-18 12:38:46 +01001470#endif /* !MBEDTLS_ECP_ALT */
1471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472#endif /* MBEDTLS_ECP_C */