blob: 2199be6461819aee0739f67babe1a53afe9c32de [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[] = {
Janos Follathbc589022021-06-25 12:43:26 +010061 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
62 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
63 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +010066 MBEDTLS_BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
67 MBEDTLS_BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
68 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +010071 MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
72 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
73 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +010076 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
77 MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
78 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +010081 MBEDTLS_BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
82 MBEDTLS_BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
83 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +010092 MBEDTLS_BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
93 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
94 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
95 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +010098 MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
99 MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
100 MBEDTLS_BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
101 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100104 MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
105 MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
106 MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
107 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100110 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
111 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
112 MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
113 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100116 MBEDTLS_BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
117 MBEDTLS_BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
118 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
119 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100128 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
129 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
130 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
131 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100134 MBEDTLS_BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
135 MBEDTLS_BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
136 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
137 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100140 MBEDTLS_BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
141 MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
142 MBEDTLS_BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
143 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100146 MBEDTLS_BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
147 MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
148 MBEDTLS_BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
149 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100152 MBEDTLS_BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
153 MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
154 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
155 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100164 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
165 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
166 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
167 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
168 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
169 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100172 MBEDTLS_BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
173 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
174 MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
175 MBEDTLS_BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
176 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
177 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100180 MBEDTLS_BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
181 MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
182 MBEDTLS_BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
183 MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
184 MBEDTLS_BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
185 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100188 MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
189 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
190 MBEDTLS_BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
191 MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
192 MBEDTLS_BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
193 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100196 MBEDTLS_BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
197 MBEDTLS_BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
198 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
199 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
200 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
201 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100210 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
211 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
212 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
213 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
214 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
215 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
216 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
217 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
218 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100221 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
222 MBEDTLS_BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
223 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
224 MBEDTLS_BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
225 MBEDTLS_BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
226 MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
227 MBEDTLS_BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
228 MBEDTLS_BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
229 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100232 MBEDTLS_BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
233 MBEDTLS_BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
234 MBEDTLS_BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
235 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
236 MBEDTLS_BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
237 MBEDTLS_BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
238 MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
239 MBEDTLS_BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
240 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100243 MBEDTLS_BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
244 MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
245 MBEDTLS_BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
246 MBEDTLS_BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
247 MBEDTLS_BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
248 MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
249 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
250 MBEDTLS_BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
251 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100254 MBEDTLS_BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
255 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
256 MBEDTLS_BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
257 MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
258 MBEDTLS_BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
259 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
260 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
261 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
262 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100268 MBEDTLS_BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
269 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
270 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100271};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272static const mbedtls_mpi_uint secp192k1_a[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100273 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100274};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275static const mbedtls_mpi_uint secp192k1_b[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100276 MBEDTLS_BYTES_TO_T_UINT_2( 0x03, 0x00 ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100277};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200278static const mbedtls_mpi_uint secp192k1_gx[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100279 MBEDTLS_BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
280 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
281 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100282};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283static const mbedtls_mpi_uint secp192k1_gy[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100284 MBEDTLS_BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
285 MBEDTLS_BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
286 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100287};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288static const mbedtls_mpi_uint secp192k1_n[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100289 MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
290 MBEDTLS_BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
291 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100292};
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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100297 MBEDTLS_BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
298 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
299 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
300 MBEDTLS_BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100301};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302static const mbedtls_mpi_uint secp224k1_a[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100303 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100304};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305static const mbedtls_mpi_uint secp224k1_b[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100306 MBEDTLS_BYTES_TO_T_UINT_2( 0x05, 0x00 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100307};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308static const mbedtls_mpi_uint secp224k1_gx[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100309 MBEDTLS_BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
310 MBEDTLS_BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
311 MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
312 MBEDTLS_BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100313};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314static const mbedtls_mpi_uint secp224k1_gy[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100315 MBEDTLS_BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
316 MBEDTLS_BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
317 MBEDTLS_BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
318 MBEDTLS_BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100319};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320static const mbedtls_mpi_uint secp224k1_n[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100321 MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
322 MBEDTLS_BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
323 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
324 MBEDTLS_BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100325};
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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100330 MBEDTLS_BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
331 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
332 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
333 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100334};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335static const mbedtls_mpi_uint secp256k1_a[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100336 MBEDTLS_BYTES_TO_T_UINT_2( 0x00, 0x00 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100337};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338static const mbedtls_mpi_uint secp256k1_b[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100339 MBEDTLS_BYTES_TO_T_UINT_2( 0x07, 0x00 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100340};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341static const mbedtls_mpi_uint secp256k1_gx[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100342 MBEDTLS_BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
343 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
344 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
345 MBEDTLS_BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100346};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347static const mbedtls_mpi_uint secp256k1_gy[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100348 MBEDTLS_BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
349 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
350 MBEDTLS_BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
351 MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100352};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353static const mbedtls_mpi_uint secp256k1_n[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100354 MBEDTLS_BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
355 MBEDTLS_BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
356 MBEDTLS_BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
357 MBEDTLS_BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100358};
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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100366 MBEDTLS_BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
367 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
368 MBEDTLS_BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
369 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100372 MBEDTLS_BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
373 MBEDTLS_BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
374 MBEDTLS_BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
375 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100378 MBEDTLS_BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
379 MBEDTLS_BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
380 MBEDTLS_BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
381 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100384 MBEDTLS_BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
385 MBEDTLS_BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
386 MBEDTLS_BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
387 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100390 MBEDTLS_BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
391 MBEDTLS_BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
392 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
393 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100396 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
397 MBEDTLS_BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
398 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
399 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100408 MBEDTLS_BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
409 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
410 MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
411 MBEDTLS_BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
412 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
413 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100416 MBEDTLS_BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
417 MBEDTLS_BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
418 MBEDTLS_BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
419 MBEDTLS_BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
420 MBEDTLS_BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
421 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100424 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
425 MBEDTLS_BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
426 MBEDTLS_BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
427 MBEDTLS_BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
428 MBEDTLS_BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
429 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100432 MBEDTLS_BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
433 MBEDTLS_BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
434 MBEDTLS_BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
435 MBEDTLS_BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
436 MBEDTLS_BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
437 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100440 MBEDTLS_BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
441 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
442 MBEDTLS_BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
443 MBEDTLS_BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
444 MBEDTLS_BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
445 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100448 MBEDTLS_BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
449 MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
450 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
451 MBEDTLS_BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
452 MBEDTLS_BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
453 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100462 MBEDTLS_BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
463 MBEDTLS_BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
464 MBEDTLS_BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
465 MBEDTLS_BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
466 MBEDTLS_BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
467 MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
468 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
469 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100472 MBEDTLS_BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
473 MBEDTLS_BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
474 MBEDTLS_BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
475 MBEDTLS_BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
476 MBEDTLS_BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
477 MBEDTLS_BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
478 MBEDTLS_BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
479 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100482 MBEDTLS_BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
483 MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
484 MBEDTLS_BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
485 MBEDTLS_BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
486 MBEDTLS_BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
487 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
488 MBEDTLS_BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
489 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100492 MBEDTLS_BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
493 MBEDTLS_BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
494 MBEDTLS_BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
495 MBEDTLS_BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
496 MBEDTLS_BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
497 MBEDTLS_BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
498 MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
499 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100502 MBEDTLS_BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
503 MBEDTLS_BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
504 MBEDTLS_BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
505 MBEDTLS_BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
506 MBEDTLS_BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
507 MBEDTLS_BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
508 MBEDTLS_BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
509 MBEDTLS_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[] = {
Janos Follathbc589022021-06-25 12:43:26 +0100512 MBEDTLS_BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
513 MBEDTLS_BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
514 MBEDTLS_BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
515 MBEDTLS_BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
516 MBEDTLS_BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
517 MBEDTLS_BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
518 MBEDTLS_BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
519 MBEDTLS_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 );
Pol Henarejosc46a2f62022-05-09 11:03:26 +0200757
Pol Henarejosa93442e2022-05-09 10:08:46 +0200758 mbedtls_ecp_group_init( grp );
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100759
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100760 grp->id = id;
761
762 switch( id )
763 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
765 case MBEDTLS_ECP_DP_SECP192R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100766 NIST_MODP( p192 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100767 return( LOAD_GROUP( secp192r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100769
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
771 case MBEDTLS_ECP_DP_SECP224R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100772 NIST_MODP( p224 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100773 return( LOAD_GROUP( secp224r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100775
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
777 case MBEDTLS_ECP_DP_SECP256R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100778 NIST_MODP( p256 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100779 return( LOAD_GROUP( secp256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100781
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
783 case MBEDTLS_ECP_DP_SECP384R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100784 NIST_MODP( p384 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100785 return( LOAD_GROUP( secp384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100787
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
789 case MBEDTLS_ECP_DP_SECP521R1:
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100790 NIST_MODP( p521 );
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100791 return( LOAD_GROUP( secp521r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100793
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
795 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100796 grp->modp = ecp_mod_p192k1;
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100797 return( LOAD_GROUP_A( secp192k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100799
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
801 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100802 grp->modp = ecp_mod_p224k1;
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100803 return( LOAD_GROUP_A( secp224k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200804#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100805
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
807 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100808 grp->modp = ecp_mod_p256k1;
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100809 return( LOAD_GROUP_A( secp256k1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100811
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
813 case MBEDTLS_ECP_DP_BP256R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100814 return( LOAD_GROUP_A( brainpoolP256r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100816
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200817#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
818 case MBEDTLS_ECP_DP_BP384R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100819 return( LOAD_GROUP_A( brainpoolP384r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100821
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
823 case MBEDTLS_ECP_DP_BP512R1:
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100824 return( LOAD_GROUP_A( brainpoolP512r1 ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100826
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200827#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
828 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100829 grp->modp = ecp_mod_p255;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100830 return( ecp_use_curve25519( grp ) );
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200831#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100832
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000833#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
834 case MBEDTLS_ECP_DP_CURVE448:
835 grp->modp = ecp_mod_p448;
836 return( ecp_use_curve448( grp ) );
837#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
838
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100839 default:
Alexander K56a74cd2019-09-10 17:58:20 +0300840 grp->id = MBEDTLS_ECP_DP_NONE;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100842 }
843}
844
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100846/*
847 * Fast reduction modulo the primes used by the NIST curves.
848 *
849 * These functions are critical for speed, but not needed for correct
850 * operations. So, we make the choice to heavily rely on the internals of our
851 * bignum library, which creates a tight coupling between these functions and
852 * our MPI implementation. However, the coupling between the ECP module and
853 * MPI remains loose, since these functions can be deactivated at will.
854 */
855
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200856#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100857/*
858 * Compared to the way things are presented in FIPS 186-3 D.2,
859 * we proceed in columns, from right (least significant chunk) to left,
860 * adding chunks to N in place, and keeping a carry for the next chunk.
861 * This avoids moving things around in memory, and uselessly adding zeros,
862 * compared to the more straightforward, line-oriented approach.
863 *
864 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
866 * 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 +0100867 */
868
869/* Add 64-bit chunks (dst += src) and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100871{
872 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 mbedtls_mpi_uint c = 0;
874 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100875 {
876 *dst += c; c = ( *dst < c );
877 *dst += *src; c += ( *dst < *src );
878 }
879 *carry += c;
880}
881
882/* Add carry to a 64-bit chunk and update carry */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100884{
885 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200886 for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100887 {
888 *dst += *carry;
889 *carry = ( *dst < *carry );
890 }
891}
892
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893#define WIDTH 8 / sizeof( mbedtls_mpi_uint )
Hanno Becker1eeca412018-10-15 12:01:35 +0100894#define A( i ) N->p + (i) * WIDTH
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100895#define ADD( i ) add64( p, A( i ), &c )
896#define NEXT p += WIDTH; carry64( p, &c )
897#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0
898
899/*
900 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
901 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100903{
Janos Follath24eed8d2019-11-22 13:21:35 +0000904 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200905 mbedtls_mpi_uint c = 0;
906 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100907
908 /* Make sure we have enough blocks so that A(5) is legal */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100910
911 p = N->p;
912 end = p + N->n;
913
914 ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5
915 ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5
916 ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5
917
918cleanup:
919 return( ret );
920}
921
922#undef WIDTH
923#undef A
924#undef ADD
925#undef NEXT
926#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100928
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
930 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
931 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100932/*
933 * The reader is advised to first understand ecp_mod_p192() since the same
934 * general structure is used here, but with additional complications:
935 * (1) chunks of 32 bits, and (2) subtractions.
936 */
937
938/*
939 * For these primes, we need to handle data in chunks of 32 bits.
940 * This makes it more complicated if we use 64 bits limbs in MPI,
941 * which prevents us from using a uniform access method as for p192.
942 *
943 * So, we define a mini abstraction layer to access 32 bit chunks,
944 * load them in 'cur' for work, and store them back from 'cur' when done.
945 *
946 * While at it, also define the size of N in terms of 32-bit chunks.
947 */
948#define LOAD32 cur = A( i );
949
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200950#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100951
952#define MAX32 N->n
953#define A( j ) N->p[j]
954#define STORE32 N->p[i] = cur;
955
956#else /* 64-bit */
957
958#define MAX32 N->n * 2
Hanno Becker1eeca412018-10-15 12:01:35 +0100959#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \
960 (uint32_t)( N->p[(j)/2] )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100961#define STORE32 \
962 if( i % 2 ) { \
963 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100965 } else { \
966 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200967 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100968 }
969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100971
972/*
973 * Helpers for addition and subtraction of chunks, with signed carry.
974 */
975static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
976{
977 *dst += src;
978 *carry += ( *dst < src );
979}
980
981static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
982{
983 *carry -= ( *dst < src );
984 *dst -= src;
985}
986
987#define ADD( j ) add32( &cur, A( j ), &c );
988#define SUB( j ) sub32( &cur, A( j ), &c );
989
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200990#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
Gilles Peskineb76517b2021-03-10 23:44:28 +0100991#define biL (ciL << 3) /* bits in limb */
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200992
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100993/*
994 * Helpers for the main 'loop'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100995 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100996#define INIT( b ) \
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200997 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100998 signed char c = 0, cc; \
999 uint32_t cur; \
1000 size_t i = 0, bits = (b); \
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001001 /* N is the size of the product of two b-bit numbers, plus one */ \
1002 /* limb for fix_negative */ \
1003 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, ( b ) * 2 / biL + 1 ) ); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001004 LOAD32;
1005
1006#define NEXT \
1007 STORE32; i++; LOAD32; \
1008 cc = c; c = 0; \
1009 if( cc < 0 ) \
1010 sub32( &cur, -cc, &c ); \
1011 else \
1012 add32( &cur, cc, &c ); \
1013
1014#define LAST \
1015 STORE32; i++; \
1016 cur = c > 0 ? c : 0; STORE32; \
1017 cur = 0; while( ++i < MAX32 ) { STORE32; } \
Gilles Peskine618be2e2021-04-03 21:47:53 +02001018 if( c < 0 ) mbedtls_ecp_fix_negative( N, c, bits );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001019
1020/*
1021 * If the result is negative, we get it in the form
Gilles Peskine349b3722021-04-03 21:40:11 +02001022 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001023 */
Gilles Peskine618be2e2021-04-03 21:47:53 +02001024MBEDTLS_STATIC_TESTABLE
1025void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001026{
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001027 size_t i;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001028
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001029 /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
1030 * set the absolute value to 0xfff...fff - N. There is no carry
1031 * since we're subtracting from all-bits-one. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001032 for( i = 0; i <= bits / 8 / sizeof( mbedtls_mpi_uint ); i++ )
1033 {
1034 N->p[i] = ~(mbedtls_mpi_uint)0 - N->p[i];
1035 }
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001036 /* Add 1, taking care of the carry. */
1037 i = 0;
1038 do
1039 ++N->p[i];
1040 while( N->p[i++] == 0 && i <= bits / 8 / sizeof( mbedtls_mpi_uint ) );
1041 /* Invert the sign.
1042 * Now N = N0 - 2^bits where N0 is the initial value of N. */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001043 N->s = -1;
1044
Gilles Peskine349b3722021-04-03 21:40:11 +02001045 /* Add |c| * 2^bits to the absolute value. Since c and N are
1046 * negative, this adds c * 2^bits. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001047 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1048#if defined(MBEDTLS_HAVE_INT64)
1049 if( bits == 224 )
1050 msw <<= 32;
1051#endif
1052 N->p[bits / 8 / sizeof( mbedtls_mpi_uint)] += msw;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001053}
1054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001056/*
1057 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1058 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001060{
1061 INIT( 224 );
1062
1063 SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11
1064 SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12
1065 SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13
1066 SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11
1067 SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12
1068 SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13
1069 SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10
1070
1071cleanup:
1072 return( ret );
1073}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001077/*
1078 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1079 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001081{
1082 INIT( 256 );
1083
1084 ADD( 8 ); ADD( 9 );
1085 SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0
1086
1087 ADD( 9 ); ADD( 10 );
1088 SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1
1089
1090 ADD( 10 ); ADD( 11 );
1091 SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2
1092
1093 ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
1094 SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3
1095
1096 ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
1097 SUB( 9 ); SUB( 10 ); NEXT; // A4
1098
1099 ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
1100 SUB( 10 ); SUB( 11 ); NEXT; // A5
1101
1102 ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
1103 SUB( 8 ); SUB( 9 ); NEXT; // A6
1104
1105 ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
1106 SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7
1107
1108cleanup:
1109 return( ret );
1110}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001114/*
1115 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1116 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001118{
1119 INIT( 384 );
1120
1121 ADD( 12 ); ADD( 21 ); ADD( 20 );
1122 SUB( 23 ); NEXT; // A0
1123
1124 ADD( 13 ); ADD( 22 ); ADD( 23 );
1125 SUB( 12 ); SUB( 20 ); NEXT; // A2
1126
1127 ADD( 14 ); ADD( 23 );
1128 SUB( 13 ); SUB( 21 ); NEXT; // A2
1129
1130 ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
1131 SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3
1132
1133 ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
1134 SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4
1135
1136 ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
1137 SUB( 16 ); NEXT; // A5
1138
1139 ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
1140 SUB( 17 ); NEXT; // A6
1141
1142 ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
1143 SUB( 18 ); NEXT; // A7
1144
1145 ADD( 20 ); ADD( 17 ); ADD( 16 );
1146 SUB( 19 ); NEXT; // A8
1147
1148 ADD( 21 ); ADD( 18 ); ADD( 17 );
1149 SUB( 20 ); NEXT; // A9
1150
1151 ADD( 22 ); ADD( 19 ); ADD( 18 );
1152 SUB( 21 ); NEXT; // A10
1153
1154 ADD( 23 ); ADD( 20 ); ADD( 19 );
1155 SUB( 22 ); LAST; // A11
1156
1157cleanup:
1158 return( ret );
1159}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001161
1162#undef A
1163#undef LOAD32
1164#undef STORE32
1165#undef MAX32
1166#undef INIT
1167#undef NEXT
1168#undef LAST
1169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1171 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1172 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001173
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001174#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001175/*
1176 * Here we have an actual Mersenne prime, so things are more straightforward.
1177 * However, chunks are aligned on a 'weird' boundary (521 bits).
1178 */
1179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180/* Size of p521 in terms of mbedtls_mpi_uint */
1181#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001183/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001184#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001185
1186/*
1187 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1188 * Write N as A1 + 2^521 A0, return A0 + A1
1189 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001190static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001191{
Janos Follath24eed8d2019-11-22 13:21:35 +00001192 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001193 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001194 mbedtls_mpi M;
1195 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1196 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001197 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1198 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1199
1200 if( N->n < P521_WIDTH )
1201 return( 0 );
1202
1203 /* M = A1 */
1204 M.s = 1;
1205 M.n = N->n - ( P521_WIDTH - 1 );
1206 if( M.n > P521_WIDTH + 1 )
1207 M.n = P521_WIDTH + 1;
1208 M.p = Mp;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001209 memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1210 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001211
1212 /* N = A0 */
1213 N->p[P521_WIDTH - 1] &= P521_MASK;
1214 for( i = P521_WIDTH; i < N->n; i++ )
1215 N->p[i] = 0;
1216
1217 /* N = A0 + A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001219
1220cleanup:
1221 return( ret );
1222}
1223
1224#undef P521_WIDTH
1225#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001226#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001227
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001228#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001229
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001230#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232/* Size of p255 in terms of mbedtls_mpi_uint */
1233#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001234
1235/*
1236 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001237 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001238 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001239static int ecp_mod_p255( mbedtls_mpi *N )
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001240{
Janos Follath24eed8d2019-11-22 13:21:35 +00001241 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001242 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243 mbedtls_mpi M;
1244 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001245
1246 if( N->n < P255_WIDTH )
1247 return( 0 );
1248
1249 /* M = A1 */
1250 M.s = 1;
1251 M.n = N->n - ( P255_WIDTH - 1 );
1252 if( M.n > P255_WIDTH + 1 )
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001253 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001254 M.p = Mp;
1255 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001256 memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
1257 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001258 M.n++; /* Make room for multiplication by 19 */
1259
1260 /* N = A0 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001261 MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001262 for( i = P255_WIDTH; i < N->n; i++ )
1263 N->p[i] = 0;
1264
1265 /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001266 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) );
1267 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001268
1269cleanup:
1270 return( ret );
1271}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001272#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001273
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001274#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1275
1276/* Size of p448 in terms of mbedtls_mpi_uint */
1277#define P448_WIDTH ( 448 / 8 / sizeof( mbedtls_mpi_uint ) )
1278
1279/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
1280#define DIV_ROUND_UP( X, Y ) ( ( ( X ) + ( Y ) - 1 ) / ( Y ) )
1281#define P224_WIDTH_MIN ( 28 / sizeof( mbedtls_mpi_uint ) )
1282#define P224_WIDTH_MAX DIV_ROUND_UP( 28, sizeof( mbedtls_mpi_uint ) )
1283#define P224_UNUSED_BITS ( ( P224_WIDTH_MAX * sizeof( mbedtls_mpi_uint ) * 8 ) - 224 )
1284
1285/*
1286 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1287 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1288 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1289 * implementation of Curve448, which uses its own special 56-bit limbs rather
1290 * than a generic bignum library. We could squeeze some extra speed out on
1291 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1292 * arithmetic using the limbs directly as we do for the NIST primes above,
1293 * but for 64-bit targets it should use half the number of operations if we do
1294 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1295 */
1296static int ecp_mod_p448( mbedtls_mpi *N )
1297{
Janos Follath24eed8d2019-11-22 13:21:35 +00001298 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001299 size_t i;
1300 mbedtls_mpi M, Q;
1301 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1302
1303 if( N->n <= P448_WIDTH )
1304 return( 0 );
1305
1306 /* M = A1 */
1307 M.s = 1;
1308 M.n = N->n - ( P448_WIDTH );
1309 if( M.n > P448_WIDTH )
1310 /* Shouldn't be called with N larger than 2^896! */
1311 return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
1312 M.p = Mp;
1313 memset( Mp, 0, sizeof( Mp ) );
1314 memcpy( Mp, N->p + P448_WIDTH, M.n * sizeof( mbedtls_mpi_uint ) );
1315
1316 /* N = A0 */
1317 for( i = P448_WIDTH; i < N->n; i++ )
1318 N->p[i] = 0;
1319
1320 /* N += A1 */
1321 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1322
1323 /* Q = B1, N += B1 */
1324 Q = M;
1325 Q.p = Qp;
1326 memcpy( Qp, Mp, sizeof( Qp ) );
1327 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Q, 224 ) );
1328 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &Q ) );
1329
1330 /* M = (B0 + B1) * 2^224, N += M */
1331 if( sizeof( mbedtls_mpi_uint ) > 4 )
1332 Mp[P224_WIDTH_MIN] &= ( (mbedtls_mpi_uint)-1 ) >> ( P224_UNUSED_BITS );
1333 for( i = P224_WIDTH_MAX; i < M.n; ++i )
1334 Mp[i] = 0;
1335 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &Q ) );
1336 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
1337 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &M, 224 ) );
1338 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &M ) );
1339
1340cleanup:
1341 return( ret );
1342}
1343#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1344
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001345#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1346 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1347 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001348/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001349 * Fast quasi-reduction modulo P = 2^s - R,
1350 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001351 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001352 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001353 * Actually do two passes, since R is big.
1354 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001355#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P
1356#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R
1357static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
1358 size_t adjust, size_t shift, mbedtls_mpi_uint mask )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001359{
Janos Follath24eed8d2019-11-22 13:21:35 +00001360 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001361 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001362 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001363 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001364
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001365 if( N->n < p_limbs )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001366 return( 0 );
1367
1368 /* Init R */
1369 R.s = 1;
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001370 R.p = Rp;
1371 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001372
1373 /* Common setup for M */
1374 M.s = 1;
1375 M.p = Mp;
1376
1377 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001378 M.n = N->n - ( p_limbs - adjust );
1379 if( M.n > p_limbs + adjust )
1380 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001381 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001382 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001383 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001384 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001385 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001386
1387 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001388 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001389 N->p[p_limbs - 1] &= mask;
1390 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001391 N->p[i] = 0;
1392
1393 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001394 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1395 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001396
1397 /* Second pass */
1398
1399 /* M = A1 */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001400 M.n = N->n - ( p_limbs - adjust );
1401 if( M.n > p_limbs + adjust )
1402 M.n = p_limbs + adjust;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001403 memset( Mp, 0, sizeof Mp );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001404 memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001405 if( shift != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001406 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) );
Janos Follath7dadc2f2017-01-27 16:05:20 +00001407 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001408
1409 /* N = A0 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001410 if( mask != 0 )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001411 N->p[p_limbs - 1] &= mask;
1412 for( i = p_limbs; i < N->n; i++ )
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001413 N->p[i] = 0;
1414
1415 /* N = A0 + R * A1 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001416 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) );
1417 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001418
1419cleanup:
1420 return( ret );
1421}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1423 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1424 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001426#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001427/*
1428 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1429 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1430 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001431static int ecp_mod_p192k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001432{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433 static mbedtls_mpi_uint Rp[] = {
Janos Follathbc589022021-06-25 12:43:26 +01001434 MBEDTLS_BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
1435 0x00 ) };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001436
Janos Follathbc589022021-06-25 12:43:26 +01001437 return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1438 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001439}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001440#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001443/*
1444 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1445 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001447static int ecp_mod_p224k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001448{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001449 static mbedtls_mpi_uint Rp[] = {
Janos Follathbc589022021-06-25 12:43:26 +01001450 MBEDTLS_BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
1451 0x00 ) };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453#if defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001454 return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) );
1455#else
Janos Follathbc589022021-06-25 12:43:26 +01001456 return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1457 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001458#endif
1459}
1460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001461#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001463#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001464/*
1465 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1466 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1467 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468static int ecp_mod_p256k1( mbedtls_mpi *N )
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001469{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470 static mbedtls_mpi_uint Rp[] = {
Janos Follathbc589022021-06-25 12:43:26 +01001471 MBEDTLS_BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
1472 0x00 ) };
1473 return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0,
1474 0 ) );
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001475}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001477
Janos Follathb0697532016-08-18 12:38:46 +01001478#endif /* !MBEDTLS_ECP_ALT */
1479
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480#endif /* MBEDTLS_ECP_C */