blob: 61a1046f3a27cc4a784430c9d50e6fa1d1b452a5 [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
Dave Rodgman7ff79652023-11-03 12:04:52 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01006 */
7
Gilles Peskinedb09ef62020-06-03 01:43:33 +02008#include "common.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020010#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010011
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000012#include "mbedtls/ecp.h"
Hanno Becker4f8e8e52018-12-14 15:08:03 +000013#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000014#include "mbedtls/error.h"
Janos Follathbc96a792021-06-24 14:48:38 +010015#include "mbedtls/bn_mul.h"
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010016
Gilles Peskine618be2e2021-04-03 21:47:53 +020017#include "ecp_invasive.h"
18
Rich Evans00ab4702015-02-06 13:43:58 +000019#include <string.h>
20
Janos Follathb0697532016-08-18 12:38:46 +010021#if !defined(MBEDTLS_ECP_ALT)
22
Hanno Becker4f8e8e52018-12-14 15:08:03 +000023/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010024#define ECP_VALIDATE_RET(cond) \
25 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA)
26#define ECP_VALIDATE(cond) \
27 MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker4f8e8e52018-12-14 15:08:03 +000028
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010029#define ECP_MPI_INIT(s, n, p) { s, (n), (mbedtls_mpi_uint *) (p) }
Manuel Pégourié-Gonnard10b8e5a2021-06-23 12:25:48 +020030
31#define ECP_MPI_INIT_ARRAY(x) \
32 ECP_MPI_INIT(1, sizeof(x) / sizeof(mbedtls_mpi_uint), x)
33
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010034/*
Manuel Pégourié-Gonnard14a96c52013-12-11 12:15:28 +010035 * Note: the constants are in little-endian order
36 * to be directly usable in MPIs
37 */
38
39/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010040 * Domain parameters for secp192r1
41 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
43static const mbedtls_mpi_uint secp192r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010044 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
45 MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
46 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010047};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048static const mbedtls_mpi_uint secp192r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010049 MBEDTLS_BYTES_TO_T_UINT_8(0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE),
50 MBEDTLS_BYTES_TO_T_UINT_8(0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F),
51 MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010052};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053static const mbedtls_mpi_uint secp192r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054 MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4),
55 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C),
56 MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010057};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058static const mbedtls_mpi_uint secp192r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010059 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73),
60 MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63),
61 MBEDTLS_BYTES_TO_T_UINT_8(0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010062};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063static const mbedtls_mpi_uint secp192r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010064 MBEDTLS_BYTES_TO_T_UINT_8(0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14),
65 MBEDTLS_BYTES_TO_T_UINT_8(0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF),
66 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010067};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +010069
70/*
71 * Domain parameters for secp224r1
72 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
74static const mbedtls_mpi_uint secp224r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010075 MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
76 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
77 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
78 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010079};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080static const mbedtls_mpi_uint secp224r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010081 MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27),
82 MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50),
83 MBEDTLS_BYTES_TO_T_UINT_8(0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C),
84 MBEDTLS_BYTES_TO_T_UINT_4(0x85, 0x0A, 0x05, 0xB4),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010085};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020086static const mbedtls_mpi_uint secp224r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010087 MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34),
88 MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A),
89 MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B),
90 MBEDTLS_BYTES_TO_T_UINT_4(0xBD, 0x0C, 0x0E, 0xB7),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010091};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020092static const mbedtls_mpi_uint secp224r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010093 MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44),
94 MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD),
95 MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5),
96 MBEDTLS_BYTES_TO_T_UINT_4(0x88, 0x63, 0x37, 0xBD),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +010097};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098static const mbedtls_mpi_uint secp224r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010099 MBEDTLS_BYTES_TO_T_UINT_8(0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13),
100 MBEDTLS_BYTES_TO_T_UINT_8(0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF),
101 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
102 MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100103};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100105
106/*
107 * Domain parameters for secp256r1
108 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
110static const mbedtls_mpi_uint secp256r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100111 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
112 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
113 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
114 MBEDTLS_BYTES_TO_T_UINT_8(0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100115};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116static const mbedtls_mpi_uint secp256r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100117 MBEDTLS_BYTES_TO_T_UINT_8(0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B),
118 MBEDTLS_BYTES_TO_T_UINT_8(0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65),
119 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3),
120 MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100121};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122static const mbedtls_mpi_uint secp256r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100123 MBEDTLS_BYTES_TO_T_UINT_8(0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4),
124 MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77),
125 MBEDTLS_BYTES_TO_T_UINT_8(0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8),
126 MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100127};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128static const mbedtls_mpi_uint secp256r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100129 MBEDTLS_BYTES_TO_T_UINT_8(0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB),
130 MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B),
131 MBEDTLS_BYTES_TO_T_UINT_8(0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E),
132 MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100133};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134static const mbedtls_mpi_uint secp256r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100135 MBEDTLS_BYTES_TO_T_UINT_8(0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3),
136 MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC),
137 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
138 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100139};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100141
142/*
143 * Domain parameters for secp384r1
144 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
146static const mbedtls_mpi_uint secp384r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00),
148 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF),
149 MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
150 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
151 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
152 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100153};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154static const mbedtls_mpi_uint secp384r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100155 MBEDTLS_BYTES_TO_T_UINT_8(0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A),
156 MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6),
157 MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03),
158 MBEDTLS_BYTES_TO_T_UINT_8(0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18),
159 MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98),
160 MBEDTLS_BYTES_TO_T_UINT_8(0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100161};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162static const mbedtls_mpi_uint secp384r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100163 MBEDTLS_BYTES_TO_T_UINT_8(0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A),
164 MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55),
165 MBEDTLS_BYTES_TO_T_UINT_8(0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59),
166 MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E),
167 MBEDTLS_BYTES_TO_T_UINT_8(0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E),
168 MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100169};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170static const mbedtls_mpi_uint secp384r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100171 MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A),
172 MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A),
173 MBEDTLS_BYTES_TO_T_UINT_8(0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9),
174 MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8),
175 MBEDTLS_BYTES_TO_T_UINT_8(0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D),
176 MBEDTLS_BYTES_TO_T_UINT_8(0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100177};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178static const mbedtls_mpi_uint secp384r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100179 MBEDTLS_BYTES_TO_T_UINT_8(0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC),
180 MBEDTLS_BYTES_TO_T_UINT_8(0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58),
181 MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7),
182 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
183 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
184 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100185};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100187
188/*
189 * Domain parameters for secp521r1
190 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
192static const mbedtls_mpi_uint secp521r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100193 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
194 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
195 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
196 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
197 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
198 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
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_2(0xFF, 0x01),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100202};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203static const mbedtls_mpi_uint secp521r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100204 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF),
205 MBEDTLS_BYTES_TO_T_UINT_8(0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35),
206 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16),
207 MBEDTLS_BYTES_TO_T_UINT_8(0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56),
208 MBEDTLS_BYTES_TO_T_UINT_8(0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8),
209 MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2),
210 MBEDTLS_BYTES_TO_T_UINT_8(0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92),
211 MBEDTLS_BYTES_TO_T_UINT_8(0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95),
212 MBEDTLS_BYTES_TO_T_UINT_2(0x51, 0x00),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100213};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214static const mbedtls_mpi_uint secp521r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100215 MBEDTLS_BYTES_TO_T_UINT_8(0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9),
216 MBEDTLS_BYTES_TO_T_UINT_8(0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33),
217 MBEDTLS_BYTES_TO_T_UINT_8(0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE),
218 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1),
219 MBEDTLS_BYTES_TO_T_UINT_8(0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8),
220 MBEDTLS_BYTES_TO_T_UINT_8(0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C),
221 MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E),
222 MBEDTLS_BYTES_TO_T_UINT_8(0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85),
223 MBEDTLS_BYTES_TO_T_UINT_2(0xC6, 0x00),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100224};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225static const mbedtls_mpi_uint secp521r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100226 MBEDTLS_BYTES_TO_T_UINT_8(0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88),
227 MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35),
228 MBEDTLS_BYTES_TO_T_UINT_8(0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5),
229 MBEDTLS_BYTES_TO_T_UINT_8(0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97),
230 MBEDTLS_BYTES_TO_T_UINT_8(0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17),
231 MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98),
232 MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C),
233 MBEDTLS_BYTES_TO_T_UINT_8(0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39),
234 MBEDTLS_BYTES_TO_T_UINT_2(0x18, 0x01),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100235};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236static const mbedtls_mpi_uint secp521r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100237 MBEDTLS_BYTES_TO_T_UINT_8(0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB),
238 MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B),
239 MBEDTLS_BYTES_TO_T_UINT_8(0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F),
240 MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51),
241 MBEDTLS_BYTES_TO_T_UINT_8(0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
242 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
243 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
244 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
245 MBEDTLS_BYTES_TO_T_UINT_2(0xFF, 0x01),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100246};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200247#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100248
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
250static const mbedtls_mpi_uint secp192k1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100251 MBEDTLS_BYTES_TO_T_UINT_8(0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF),
252 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
253 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100254};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200255static const mbedtls_mpi_uint secp192k1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100256 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100257};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258static const mbedtls_mpi_uint secp192k1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100259 MBEDTLS_BYTES_TO_T_UINT_2(0x03, 0x00),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100260};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200261static const mbedtls_mpi_uint secp192k1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100262 MBEDTLS_BYTES_TO_T_UINT_8(0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D),
263 MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26),
264 MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100265};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266static const mbedtls_mpi_uint secp192k1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100267 MBEDTLS_BYTES_TO_T_UINT_8(0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40),
268 MBEDTLS_BYTES_TO_T_UINT_8(0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84),
269 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100270};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271static const mbedtls_mpi_uint secp192k1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100272 MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F),
273 MBEDTLS_BYTES_TO_T_UINT_8(0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF),
274 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100275};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100277
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200278#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
279static const mbedtls_mpi_uint secp224k1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100280 MBEDTLS_BYTES_TO_T_UINT_8(0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF),
281 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
282 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
283 MBEDTLS_BYTES_TO_T_UINT_4(0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100284};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200285static const mbedtls_mpi_uint secp224k1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100286 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100287};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288static const mbedtls_mpi_uint secp224k1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289 MBEDTLS_BYTES_TO_T_UINT_2(0x05, 0x00),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100290};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291static const mbedtls_mpi_uint secp224k1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100292 MBEDTLS_BYTES_TO_T_UINT_8(0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F),
293 MBEDTLS_BYTES_TO_T_UINT_8(0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69),
294 MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D),
295 MBEDTLS_BYTES_TO_T_UINT_4(0x33, 0x5B, 0x45, 0xA1),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100296};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297static const mbedtls_mpi_uint secp224k1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298 MBEDTLS_BYTES_TO_T_UINT_8(0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2),
299 MBEDTLS_BYTES_TO_T_UINT_8(0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7),
300 MBEDTLS_BYTES_TO_T_UINT_8(0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F),
301 MBEDTLS_BYTES_TO_T_UINT_4(0xED, 0x9F, 0x08, 0x7E),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100302};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303static const mbedtls_mpi_uint secp224k1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100304 MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA),
305 MBEDTLS_BYTES_TO_T_UINT_8(0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00),
306 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
307 MBEDTLS_BYTES_TO_T_UINT_8(0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00),
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100308};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100310
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
312static const mbedtls_mpi_uint secp256k1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100313 MBEDTLS_BYTES_TO_T_UINT_8(0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF),
314 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
315 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
316 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100317};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318static const mbedtls_mpi_uint secp256k1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100319 MBEDTLS_BYTES_TO_T_UINT_2(0x00, 0x00),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100320};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321static const mbedtls_mpi_uint secp256k1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 MBEDTLS_BYTES_TO_T_UINT_2(0x07, 0x00),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100323};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324static const mbedtls_mpi_uint secp256k1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100325 MBEDTLS_BYTES_TO_T_UINT_8(0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59),
326 MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02),
327 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55),
328 MBEDTLS_BYTES_TO_T_UINT_8(0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100329};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330static const mbedtls_mpi_uint secp256k1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 MBEDTLS_BYTES_TO_T_UINT_8(0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C),
332 MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD),
333 MBEDTLS_BYTES_TO_T_UINT_8(0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D),
334 MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100335};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336static const mbedtls_mpi_uint secp256k1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337 MBEDTLS_BYTES_TO_T_UINT_8(0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF),
338 MBEDTLS_BYTES_TO_T_UINT_8(0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA),
339 MBEDTLS_BYTES_TO_T_UINT_8(0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
340 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100341};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100343
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100344/*
345 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
346 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
348static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100349 MBEDTLS_BYTES_TO_T_UINT_8(0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20),
350 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E),
351 MBEDTLS_BYTES_TO_T_UINT_8(0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E),
352 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100353};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100355 MBEDTLS_BYTES_TO_T_UINT_8(0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9),
356 MBEDTLS_BYTES_TO_T_UINT_8(0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB),
357 MBEDTLS_BYTES_TO_T_UINT_8(0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE),
358 MBEDTLS_BYTES_TO_T_UINT_8(0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100359};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100361 MBEDTLS_BYTES_TO_T_UINT_8(0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B),
362 MBEDTLS_BYTES_TO_T_UINT_8(0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95),
363 MBEDTLS_BYTES_TO_T_UINT_8(0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3),
364 MBEDTLS_BYTES_TO_T_UINT_8(0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100365};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100367 MBEDTLS_BYTES_TO_T_UINT_8(0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A),
368 MBEDTLS_BYTES_TO_T_UINT_8(0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9),
369 MBEDTLS_BYTES_TO_T_UINT_8(0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C),
370 MBEDTLS_BYTES_TO_T_UINT_8(0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100371};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373 MBEDTLS_BYTES_TO_T_UINT_8(0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C),
374 MBEDTLS_BYTES_TO_T_UINT_8(0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2),
375 MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97),
376 MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100377};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100379 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90),
380 MBEDTLS_BYTES_TO_T_UINT_8(0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C),
381 MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E),
382 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100383};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100385
386/*
387 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
388 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
390static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391 MBEDTLS_BYTES_TO_T_UINT_8(0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87),
392 MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC),
393 MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12),
394 MBEDTLS_BYTES_TO_T_UINT_8(0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15),
395 MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F),
396 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100397};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100399 MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04),
400 MBEDTLS_BYTES_TO_T_UINT_8(0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A),
401 MBEDTLS_BYTES_TO_T_UINT_8(0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13),
402 MBEDTLS_BYTES_TO_T_UINT_8(0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2),
403 MBEDTLS_BYTES_TO_T_UINT_8(0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C),
404 MBEDTLS_BYTES_TO_T_UINT_8(0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100405};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100407 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A),
408 MBEDTLS_BYTES_TO_T_UINT_8(0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C),
409 MBEDTLS_BYTES_TO_T_UINT_8(0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E),
410 MBEDTLS_BYTES_TO_T_UINT_8(0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F),
411 MBEDTLS_BYTES_TO_T_UINT_8(0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B),
412 MBEDTLS_BYTES_TO_T_UINT_8(0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100413};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100415 MBEDTLS_BYTES_TO_T_UINT_8(0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF),
416 MBEDTLS_BYTES_TO_T_UINT_8(0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8),
417 MBEDTLS_BYTES_TO_T_UINT_8(0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB),
418 MBEDTLS_BYTES_TO_T_UINT_8(0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88),
419 MBEDTLS_BYTES_TO_T_UINT_8(0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2),
420 MBEDTLS_BYTES_TO_T_UINT_8(0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100421};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100423 MBEDTLS_BYTES_TO_T_UINT_8(0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42),
424 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E),
425 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1),
426 MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62),
427 MBEDTLS_BYTES_TO_T_UINT_8(0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C),
428 MBEDTLS_BYTES_TO_T_UINT_8(0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100429};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 MBEDTLS_BYTES_TO_T_UINT_8(0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B),
432 MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF),
433 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F),
434 MBEDTLS_BYTES_TO_T_UINT_8(0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15),
435 MBEDTLS_BYTES_TO_T_UINT_8(0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F),
436 MBEDTLS_BYTES_TO_T_UINT_8(0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100437};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100439
440/*
441 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
442 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
444static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100445 MBEDTLS_BYTES_TO_T_UINT_8(0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28),
446 MBEDTLS_BYTES_TO_T_UINT_8(0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28),
447 MBEDTLS_BYTES_TO_T_UINT_8(0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE),
448 MBEDTLS_BYTES_TO_T_UINT_8(0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D),
449 MBEDTLS_BYTES_TO_T_UINT_8(0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6),
450 MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB),
451 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F),
452 MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100453};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100455 MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7),
456 MBEDTLS_BYTES_TO_T_UINT_8(0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F),
457 MBEDTLS_BYTES_TO_T_UINT_8(0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A),
458 MBEDTLS_BYTES_TO_T_UINT_8(0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D),
459 MBEDTLS_BYTES_TO_T_UINT_8(0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8),
460 MBEDTLS_BYTES_TO_T_UINT_8(0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94),
461 MBEDTLS_BYTES_TO_T_UINT_8(0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2),
462 MBEDTLS_BYTES_TO_T_UINT_8(0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100463};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100465 MBEDTLS_BYTES_TO_T_UINT_8(0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28),
466 MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98),
467 MBEDTLS_BYTES_TO_T_UINT_8(0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77),
468 MBEDTLS_BYTES_TO_T_UINT_8(0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B),
469 MBEDTLS_BYTES_TO_T_UINT_8(0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B),
470 MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8),
471 MBEDTLS_BYTES_TO_T_UINT_8(0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA),
472 MBEDTLS_BYTES_TO_T_UINT_8(0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100473};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100475 MBEDTLS_BYTES_TO_T_UINT_8(0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B),
476 MBEDTLS_BYTES_TO_T_UINT_8(0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C),
477 MBEDTLS_BYTES_TO_T_UINT_8(0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50),
478 MBEDTLS_BYTES_TO_T_UINT_8(0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF),
479 MBEDTLS_BYTES_TO_T_UINT_8(0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4),
480 MBEDTLS_BYTES_TO_T_UINT_8(0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85),
481 MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A),
482 MBEDTLS_BYTES_TO_T_UINT_8(0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100483};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100485 MBEDTLS_BYTES_TO_T_UINT_8(0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78),
486 MBEDTLS_BYTES_TO_T_UINT_8(0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1),
487 MBEDTLS_BYTES_TO_T_UINT_8(0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B),
488 MBEDTLS_BYTES_TO_T_UINT_8(0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2),
489 MBEDTLS_BYTES_TO_T_UINT_8(0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0),
490 MBEDTLS_BYTES_TO_T_UINT_8(0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2),
491 MBEDTLS_BYTES_TO_T_UINT_8(0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0),
492 MBEDTLS_BYTES_TO_T_UINT_8(0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100493};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100495 MBEDTLS_BYTES_TO_T_UINT_8(0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5),
496 MBEDTLS_BYTES_TO_T_UINT_8(0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D),
497 MBEDTLS_BYTES_TO_T_UINT_8(0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41),
498 MBEDTLS_BYTES_TO_T_UINT_8(0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55),
499 MBEDTLS_BYTES_TO_T_UINT_8(0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6),
500 MBEDTLS_BYTES_TO_T_UINT_8(0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB),
501 MBEDTLS_BYTES_TO_T_UINT_8(0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F),
502 MBEDTLS_BYTES_TO_T_UINT_8(0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA),
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100503};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100505
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200506#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
507 defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
508 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
509 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
510 defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
511 defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
512 defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
513 defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
514 defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
515 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
516 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
517/* For these curves, we build the group parameters dynamically. */
518#define ECP_LOAD_GROUP
519#endif
520
521#if defined(ECP_LOAD_GROUP)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100522/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100523 * Create an MPI from embedded constants
Dave Rodgman18688702023-02-02 12:40:50 +0000524 * (assumes len is an exact multiple of sizeof(mbedtls_mpi_uint))
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100525 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526static 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 +0100527{
528 X->s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100529 X->n = len / sizeof(mbedtls_mpi_uint);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530 X->p = (mbedtls_mpi_uint *) p;
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100531}
532
533/*
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100534 * Set an MPI to static value 1
535 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536static inline void ecp_mpi_set1(mbedtls_mpi *X)
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100537{
Chien Wongb6d57932024-02-07 21:48:12 +0800538 static const mbedtls_mpi_uint one[] = { 1 };
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100539 X->s = 1;
540 X->n = 1;
Chien Wongb6d57932024-02-07 21:48:12 +0800541 X->p = (mbedtls_mpi_uint *) one; /* X->p will not be modified so the cast is safe */
Manuel Pégourié-Gonnard73cc01d2013-12-06 12:41:30 +0100542}
543
544/*
Manuel Pégourié-Gonnard731d08b2013-12-06 12:16:10 +0100545 * Make group available from embedded constants
546 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100547static int ecp_group_load(mbedtls_ecp_group *grp,
548 const mbedtls_mpi_uint *p, size_t plen,
549 const mbedtls_mpi_uint *a, size_t alen,
550 const mbedtls_mpi_uint *b, size_t blen,
551 const mbedtls_mpi_uint *gx, size_t gxlen,
552 const mbedtls_mpi_uint *gy, size_t gylen,
553 const mbedtls_mpi_uint *n, size_t nlen)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100554{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100555 ecp_mpi_load(&grp->P, p, plen);
556 if (a != NULL) {
557 ecp_mpi_load(&grp->A, a, alen);
558 }
559 ecp_mpi_load(&grp->B, b, blen);
560 ecp_mpi_load(&grp->N, n, nlen);
Manuel Pégourié-Gonnard9854fe92013-12-02 16:30:43 +0100561
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100562 ecp_mpi_load(&grp->G.X, gx, gxlen);
563 ecp_mpi_load(&grp->G.Y, gy, gylen);
564 ecp_mpi_set1(&grp->G.Z);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100565
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100566 grp->pbits = mbedtls_mpi_bitlen(&grp->P);
567 grp->nbits = mbedtls_mpi_bitlen(&grp->N);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100568
Manuel Pégourié-Gonnard1f82b042013-12-06 12:51:50 +0100569 grp->h = 1;
570
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571 return 0;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100572}
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200573#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100574
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100576/* Forward declarations */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100578static int ecp_mod_p192(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100579#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100581static int ecp_mod_p224(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100582#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100584static int ecp_mod_p256(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100585#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100587static int ecp_mod_p384(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100588#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100590static int ecp_mod_p521(mbedtls_mpi *);
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100591#endif
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100592
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100593#define NIST_MODP(P) grp->modp = ecp_mod_ ## P;
Manuel Pégourié-Gonnard3ee90002013-12-02 17:14:48 +0100594#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100595#define NIST_MODP(P)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100597
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100598/* Additional forward declarations */
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200599#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100600static int ecp_mod_p255(mbedtls_mpi *);
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100601#endif
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000602#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603static int ecp_mod_p448(mbedtls_mpi *);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000604#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100606static int ecp_mod_p192k1(mbedtls_mpi *);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100607#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100609static int ecp_mod_p224k1(mbedtls_mpi *);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100610#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100612static int ecp_mod_p256k1(mbedtls_mpi *);
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100613#endif
614
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200615#if defined(ECP_LOAD_GROUP)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100616#define LOAD_GROUP_A(G) ecp_group_load(grp, \
617 G ## _p, sizeof(G ## _p), \
618 G ## _a, sizeof(G ## _a), \
619 G ## _b, sizeof(G ## _b), \
620 G ## _gx, sizeof(G ## _gx), \
621 G ## _gy, sizeof(G ## _gy), \
622 G ## _n, sizeof(G ## _n))
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100623
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624#define LOAD_GROUP(G) ecp_group_load(grp, \
625 G ## _p, sizeof(G ## _p), \
626 NULL, 0, \
627 G ## _b, sizeof(G ## _b), \
628 G ## _gx, sizeof(G ## _gx), \
629 G ## _gy, sizeof(G ## _gy), \
630 G ## _n, sizeof(G ## _n))
Gilles Peskineaa9493a2018-09-12 14:44:03 +0200631#endif /* ECP_LOAD_GROUP */
Manuel Pégourié-Gonnard81e1b102013-12-06 13:28:05 +0100632
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200633#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200634/* Constants used by ecp_use_curve25519() */
Janos Follath1c6a4392021-06-24 15:00:33 +0100635static const mbedtls_mpi_sint curve25519_a24 = 0x01DB42;
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200636static const unsigned char curve25519_part_of_n[] = {
637 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7, 0x9C, 0xD6,
638 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
639};
640
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100641/*
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100642 * Specialized function for creating the Curve25519 group
643 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100644static int ecp_use_curve25519(mbedtls_ecp_group *grp)
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100645{
Janos Follath24eed8d2019-11-22 13:21:35 +0000646 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100647
648 /* Actually ( A + 2 ) / 4 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100649 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve25519_a24));
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100650
651 /* P = 2^255 - 19 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100652 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
653 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 255));
654 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 19));
655 grp->pbits = mbedtls_mpi_bitlen(&grp->P);
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100656
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100657 /* N = 2^252 + 27742317777372353535851937790883648493 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100658 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&grp->N,
659 curve25519_part_of_n, sizeof(curve25519_part_of_n)));
660 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 252, 1));
Nicholas Wilson54fc34e2016-05-16 15:15:45 +0100661
Manuel Pégourié-Gonnard18b78432018-03-28 11:14:06 +0200662 /* Y intentionally not set, since we use x/z coordinates.
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100663 * This is used as a marker to identify Montgomery curves! */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100664 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 9));
665 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1));
666 mbedtls_mpi_free(&grp->G.Y);
Manuel Pégourié-Gonnard312d2e82013-12-04 11:08:01 +0100667
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100668 /* Actually, the required msb for private keys */
669 grp->nbits = 254;
670
671cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100672 if (ret != 0) {
673 mbedtls_ecp_group_free(grp);
674 }
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100675
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100676 return ret;
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100677}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200678#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100679
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000680#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200681/* Constants used by ecp_use_curve448() */
Janos Follath1c6a4392021-06-24 15:00:33 +0100682static const mbedtls_mpi_sint curve448_a24 = 0x98AA;
Manuel Pégourié-Gonnardae481112021-06-23 12:43:34 +0200683static const unsigned char curve448_part_of_n[] = {
684 0x83, 0x35, 0xDC, 0x16, 0x3B, 0xB1, 0x24,
685 0xB6, 0x51, 0x29, 0xC9, 0x6F, 0xDE, 0x93,
686 0x3D, 0x8D, 0x72, 0x3A, 0x70, 0xAA, 0xDC,
687 0x87, 0x3D, 0x6D, 0x54, 0xA7, 0xBB, 0x0D,
688};
689
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000690/*
691 * Specialized function for creating the Curve448 group
692 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100693static int ecp_use_curve448(mbedtls_ecp_group *grp)
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000694{
695 mbedtls_mpi Ns;
Janos Follath24eed8d2019-11-22 13:21:35 +0000696 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000697
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100698 mbedtls_mpi_init(&Ns);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000699
700 /* Actually ( A + 2 ) / 4 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100701 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->A, curve448_a24));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000702
703 /* P = 2^448 - 2^224 - 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100704 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->P, 1));
705 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
706 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
707 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&grp->P, 224));
708 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&grp->P, &grp->P, 1));
709 grp->pbits = mbedtls_mpi_bitlen(&grp->P);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000710
711 /* Y intentionally not set, since we use x/z coordinates.
712 * This is used as a marker to identify Montgomery curves! */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100713 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.X, 5));
714 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&grp->G.Z, 1));
715 mbedtls_mpi_free(&grp->G.Y);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000716
717 /* N = 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100718 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(&grp->N, 446, 1));
719 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&Ns,
720 curve448_part_of_n, sizeof(curve448_part_of_n)));
721 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&grp->N, &grp->N, &Ns));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000722
723 /* Actually, the required msb for private keys */
724 grp->nbits = 447;
725
726cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100727 mbedtls_mpi_free(&Ns);
728 if (ret != 0) {
729 mbedtls_ecp_group_free(grp);
730 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000731
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100732 return ret;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000733}
734#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
735
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100736/*
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100737 * Set a group using well-known domain parameters
738 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100739int mbedtls_ecp_group_load(mbedtls_ecp_group *grp, mbedtls_ecp_group_id id)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100740{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100741 ECP_VALIDATE_RET(grp != NULL);
742 mbedtls_ecp_group_free(grp);
Pol Henarejosc46a2f62022-05-09 11:03:26 +0200743
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100744 mbedtls_ecp_group_init(grp);
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100745
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100746 grp->id = id;
747
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100748 switch (id) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
750 case MBEDTLS_ECP_DP_SECP192R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100751 NIST_MODP(p192);
752 return LOAD_GROUP(secp192r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200753#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100754
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
756 case MBEDTLS_ECP_DP_SECP224R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100757 NIST_MODP(p224);
758 return LOAD_GROUP(secp224r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100760
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
762 case MBEDTLS_ECP_DP_SECP256R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100763 NIST_MODP(p256);
764 return LOAD_GROUP(secp256r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200765#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100766
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
768 case MBEDTLS_ECP_DP_SECP384R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100769 NIST_MODP(p384);
770 return LOAD_GROUP(secp384r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100772
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
774 case MBEDTLS_ECP_DP_SECP521R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100775 NIST_MODP(p521);
776 return LOAD_GROUP(secp521r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100778
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200779#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
780 case MBEDTLS_ECP_DP_SECP192K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100781 grp->modp = ecp_mod_p192k1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100782 return LOAD_GROUP_A(secp192k1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnardea499a72014-01-11 15:58:47 +0100784
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
786 case MBEDTLS_ECP_DP_SECP224K1:
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +0100787 grp->modp = ecp_mod_p224k1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100788 return LOAD_GROUP_A(secp224k1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard18e3ec92014-01-11 15:22:07 +0100790
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
792 case MBEDTLS_ECP_DP_SECP256K1:
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +0100793 grp->modp = ecp_mod_p256k1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794 return LOAD_GROUP_A(secp256k1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnardf51c8fc2014-01-10 18:17:18 +0100796
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
798 case MBEDTLS_ECP_DP_BP256R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100799 return LOAD_GROUP_A(brainpoolP256r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100801
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200802#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
803 case MBEDTLS_ECP_DP_BP384R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804 return LOAD_GROUP_A(brainpoolP384r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
808 case MBEDTLS_ECP_DP_BP512R1:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100809 return LOAD_GROUP_A(brainpoolP512r1);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100811
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200812#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
813 case MBEDTLS_ECP_DP_CURVE25519:
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +0100814 grp->modp = ecp_mod_p255;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100815 return ecp_use_curve25519(grp);
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +0200816#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard66153662013-12-03 14:12:26 +0100817
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000818#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
819 case MBEDTLS_ECP_DP_CURVE448:
820 grp->modp = ecp_mod_p448;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100821 return ecp_use_curve448(grp);
Nicholas Wilson08f3ef12015-11-10 13:10:01 +0000822#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
823
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100824 default:
Alexander K56a74cd2019-09-10 17:58:20 +0300825 grp->id = MBEDTLS_ECP_DP_NONE;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100826 return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100827 }
828}
829
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100831/*
832 * Fast reduction modulo the primes used by the NIST curves.
833 *
834 * These functions are critical for speed, but not needed for correct
835 * operations. So, we make the choice to heavily rely on the internals of our
836 * bignum library, which creates a tight coupling between these functions and
837 * our MPI implementation. However, the coupling between the ECP module and
838 * MPI remains loose, since these functions can be deactivated at will.
839 */
840
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100842/*
843 * Compared to the way things are presented in FIPS 186-3 D.2,
844 * we proceed in columns, from right (least significant chunk) to left,
845 * adding chunks to N in place, and keeping a carry for the next chunk.
846 * This avoids moving things around in memory, and uselessly adding zeros,
847 * compared to the more straightforward, line-oriented approach.
848 *
849 * For this prime we need to handle data in chunks of 64 bits.
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
851 * 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 +0100852 */
853
854/* Add 64-bit chunks (dst += src) and update carry */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100855static inline void add64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100856{
857 unsigned char i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 mbedtls_mpi_uint c = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100859 for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++, src++) {
860 *dst += c; c = (*dst < c);
861 *dst += *src; c += (*dst < *src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100862 }
863 *carry += c;
864}
865
866/* Add carry to a 64-bit chunk and update carry */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100867static inline void carry64(mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100868{
869 unsigned char i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100870 for (i = 0; i < 8 / sizeof(mbedtls_mpi_uint); i++, dst++) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100871 *dst += *carry;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100872 *carry = (*dst < *carry);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100873 }
874}
875
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100876#define WIDTH 8 / sizeof(mbedtls_mpi_uint)
877#define A(i) N->p + (i) * WIDTH
878#define ADD(i) add64(p, A(i), &c)
879#define NEXT p += WIDTH; carry64(p, &c)
880#define LAST p += WIDTH; *p = c; while (++p < end) *p = 0
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100881
882/*
883 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
884 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100885static int ecp_mod_p192(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100886{
Janos Follath24eed8d2019-11-22 13:21:35 +0000887 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 mbedtls_mpi_uint c = 0;
889 mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100890
891 /* Make sure we have enough blocks so that A(5) is legal */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, 6 * WIDTH));
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100893
894 p = N->p;
895 end = p + N->n;
896
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100897 ADD(3); ADD(5); NEXT; // A0 += A3 + A5
898 ADD(3); ADD(4); ADD(5); NEXT; // A1 += A3 + A4 + A5
899 ADD(4); ADD(5); LAST; // A2 += A4 + A5
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100900
901cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100902 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100903}
904
905#undef WIDTH
906#undef A
907#undef ADD
908#undef NEXT
909#undef LAST
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100911
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
913 defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
914 defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100915/*
916 * The reader is advised to first understand ecp_mod_p192() since the same
917 * general structure is used here, but with additional complications:
918 * (1) chunks of 32 bits, and (2) subtractions.
919 */
920
921/*
922 * For these primes, we need to handle data in chunks of 32 bits.
923 * This makes it more complicated if we use 64 bits limbs in MPI,
924 * which prevents us from using a uniform access method as for p192.
925 *
926 * So, we define a mini abstraction layer to access 32 bit chunks,
927 * load them in 'cur' for work, and store them back from 'cur' when done.
928 *
929 * While at it, also define the size of N in terms of 32-bit chunks.
930 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100931#define LOAD32 cur = A(i);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100932
Manuel Pégourié-Gonnard7b538892015-04-09 17:00:17 +0200933#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100934
935#define MAX32 N->n
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100936#define A(j) N->p[j]
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100937#define STORE32 N->p[i] = cur;
938
939#else /* 64-bit */
940
941#define MAX32 N->n * 2
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100942#define A(j) (j) % 2 ? (uint32_t) (N->p[(j)/2] >> 32) : \
943 (uint32_t) (N->p[(j)/2])
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100944#define STORE32 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100945 if (i % 2) { \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100946 N->p[i/2] &= 0x00000000FFFFFFFF; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100948 } else { \
949 N->p[i/2] &= 0xFFFFFFFF00000000; \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 N->p[i/2] |= (mbedtls_mpi_uint) cur; \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100951 }
952
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100954
955/*
956 * Helpers for addition and subtraction of chunks, with signed carry.
957 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100958static inline void add32(uint32_t *dst, uint32_t src, signed char *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100959{
960 *dst += src;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100961 *carry += (*dst < src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100962}
963
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100964static inline void sub32(uint32_t *dst, uint32_t src, signed char *carry)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100965{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100966 *carry -= (*dst < src);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100967 *dst -= src;
968}
969
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100970#define ADD(j) add32(&cur, A(j), &c);
971#define SUB(j) sub32(&cur, A(j), &c);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100972
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200973#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
Gilles Peskineb76517b2021-03-10 23:44:28 +0100974#define biL (ciL << 3) /* bits in limb */
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200975
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100976/*
977 * Helpers for the main 'loop'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100978 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100979#define INIT(b) \
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200980 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
Hanno Becker1eeca412018-10-15 12:01:35 +0100981 signed char c = 0, cc; \
982 uint32_t cur; \
983 size_t i = 0, bits = (b); \
Gilles Peskined10e8fa2020-07-22 19:58:28 +0200984 /* N is the size of the product of two b-bit numbers, plus one */ \
985 /* limb for fix_negative */ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100986 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(N, (b) * 2 / biL + 1)); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100987 LOAD32;
988
989#define NEXT \
990 STORE32; i++; LOAD32; \
991 cc = c; c = 0; \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100992 if (cc < 0) \
993 sub32(&cur, -cc, &c); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100994 else \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100995 add32(&cur, cc, &c); \
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +0100996
997#define LAST \
998 STORE32; i++; \
999 cur = c > 0 ? c : 0; STORE32; \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001000 cur = 0; while (++i < MAX32) { STORE32; } \
1001 if (c < 0) mbedtls_ecp_fix_negative(N, c, bits);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001002
1003/*
1004 * If the result is negative, we get it in the form
Gilles Peskine349b3722021-04-03 21:40:11 +02001005 * c * 2^bits + N, with c negative and N positive shorter than 'bits'
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001006 */
Gilles Peskine618be2e2021-04-03 21:47:53 +02001007MBEDTLS_STATIC_TESTABLE
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001008void mbedtls_ecp_fix_negative(mbedtls_mpi *N, signed char c, size_t bits)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001009{
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001010 size_t i;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001011
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001012 /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
1013 * set the absolute value to 0xfff...fff - N. There is no carry
1014 * since we're subtracting from all-bits-one. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001015 for (i = 0; i <= bits / 8 / sizeof(mbedtls_mpi_uint); i++) {
1016 N->p[i] = ~(mbedtls_mpi_uint) 0 - N->p[i];
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001017 }
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001018 /* Add 1, taking care of the carry. */
1019 i = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001020 do {
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001021 ++N->p[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001022 } while (N->p[i++] == 0 && i <= bits / 8 / sizeof(mbedtls_mpi_uint));
Gilles Peskineff6a32d2021-04-03 20:21:43 +02001023 /* Invert the sign.
1024 * Now N = N0 - 2^bits where N0 is the initial value of N. */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001025 N->s = -1;
1026
Gilles Peskine349b3722021-04-03 21:40:11 +02001027 /* Add |c| * 2^bits to the absolute value. Since c and N are
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001028 * negative, this adds c * 2^bits. */
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001029 mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
1030#if defined(MBEDTLS_HAVE_INT64)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001031 if (bits == 224) {
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001032 msw <<= 32;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001033 }
Gilles Peskined10e8fa2020-07-22 19:58:28 +02001034#endif
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001035 N->p[bits / 8 / sizeof(mbedtls_mpi_uint)] += msw;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001036}
1037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001039/*
1040 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
1041 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001042static int ecp_mod_p224(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001043{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001044 INIT(224);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001045
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001046 SUB(7); SUB(11); NEXT; // A0 += -A7 - A11
1047 SUB(8); SUB(12); NEXT; // A1 += -A8 - A12
1048 SUB(9); SUB(13); NEXT; // A2 += -A9 - A13
1049 SUB(10); ADD(7); ADD(11); NEXT; // A3 += -A10 + A7 + A11
1050 SUB(11); ADD(8); ADD(12); NEXT; // A4 += -A11 + A8 + A12
1051 SUB(12); ADD(9); ADD(13); NEXT; // A5 += -A12 + A9 + A13
1052 SUB(13); ADD(10); LAST; // A6 += -A13 + A10
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001053
1054cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001055 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001056}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001060/*
1061 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
1062 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001063static int ecp_mod_p256(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001064{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001065 INIT(256);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001066
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001067 ADD(8); ADD(9);
1068 SUB(11); SUB(12); SUB(13); SUB(14); NEXT; // A0
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001069
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001070 ADD(9); ADD(10);
1071 SUB(12); SUB(13); SUB(14); SUB(15); NEXT; // A1
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001073 ADD(10); ADD(11);
1074 SUB(13); SUB(14); SUB(15); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001075
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001076 ADD(11); ADD(11); ADD(12); ADD(12); ADD(13);
1077 SUB(15); SUB(8); SUB(9); NEXT; // A3
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001078
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001079 ADD(12); ADD(12); ADD(13); ADD(13); ADD(14);
1080 SUB(9); SUB(10); NEXT; // A4
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001081
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001082 ADD(13); ADD(13); ADD(14); ADD(14); ADD(15);
1083 SUB(10); SUB(11); NEXT; // A5
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001085 ADD(14); ADD(14); ADD(15); ADD(15); ADD(14); ADD(13);
1086 SUB(8); SUB(9); NEXT; // A6
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001087
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001088 ADD(15); ADD(15); ADD(15); ADD(8);
1089 SUB(10); SUB(11); SUB(12); SUB(13); LAST; // A7
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001090
1091cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001092 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001093}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001094#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001095
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001096#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001097/*
1098 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
1099 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001100static int ecp_mod_p384(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001101{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001102 INIT(384);
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001103
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001104 ADD(12); ADD(21); ADD(20);
1105 SUB(23); NEXT; // A0
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001106
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001107 ADD(13); ADD(22); ADD(23);
1108 SUB(12); SUB(20); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001109
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001110 ADD(14); ADD(23);
1111 SUB(13); SUB(21); NEXT; // A2
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001112
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001113 ADD(15); ADD(12); ADD(20); ADD(21);
1114 SUB(14); SUB(22); SUB(23); NEXT; // A3
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001115
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001116 ADD(21); ADD(21); ADD(16); ADD(13); ADD(12); ADD(20); ADD(22);
1117 SUB(15); SUB(23); SUB(23); NEXT; // A4
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001118
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001119 ADD(22); ADD(22); ADD(17); ADD(14); ADD(13); ADD(21); ADD(23);
1120 SUB(16); NEXT; // A5
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001121
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001122 ADD(23); ADD(23); ADD(18); ADD(15); ADD(14); ADD(22);
1123 SUB(17); NEXT; // A6
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001124
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001125 ADD(19); ADD(16); ADD(15); ADD(23);
1126 SUB(18); NEXT; // A7
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001128 ADD(20); ADD(17); ADD(16);
1129 SUB(19); NEXT; // A8
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001131 ADD(21); ADD(18); ADD(17);
1132 SUB(20); NEXT; // A9
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001133
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001134 ADD(22); ADD(19); ADD(18);
1135 SUB(21); NEXT; // A10
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001136
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001137 ADD(23); ADD(20); ADD(19);
1138 SUB(22); LAST; // A11
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001139
1140cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001141 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001142}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001143#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001144
1145#undef A
1146#undef LOAD32
1147#undef STORE32
1148#undef MAX32
1149#undef INIT
1150#undef NEXT
1151#undef LAST
1152
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
1154 MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
1155 MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001158/*
1159 * Here we have an actual Mersenne prime, so things are more straightforward.
1160 * However, chunks are aligned on a 'weird' boundary (521 bits).
1161 */
1162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163/* Size of p521 in terms of mbedtls_mpi_uint */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001164#define P521_WIDTH (521 / 8 / sizeof(mbedtls_mpi_uint) + 1)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001165
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001167#define P521_MASK 0x01FF
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001168
1169/*
1170 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
1171 * Write N as A1 + 2^521 A0, return A0 + A1
1172 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001173static int ecp_mod_p521(mbedtls_mpi *N)
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001174{
Janos Follath24eed8d2019-11-22 13:21:35 +00001175 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001176 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001177 mbedtls_mpi M;
1178 mbedtls_mpi_uint Mp[P521_WIDTH + 1];
1179 /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001180 * we need to hold bits 513 to 1056, which is 34 limbs, that is
1181 * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */
1182
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001183 if (N->n < P521_WIDTH) {
1184 return 0;
1185 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001186
1187 /* M = A1 */
1188 M.s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001189 M.n = N->n - (P521_WIDTH - 1);
1190 if (M.n > P521_WIDTH + 1) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001191 M.n = P521_WIDTH + 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001192 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001193 M.p = Mp;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001194 memcpy(Mp, N->p + P521_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint));
1195 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 521 % (8 * sizeof(mbedtls_mpi_uint))));
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001196
1197 /* N = A0 */
1198 N->p[P521_WIDTH - 1] &= P521_MASK;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001199 for (i = P521_WIDTH; i < N->n; i++) {
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001200 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001201 }
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001202
1203 /* N = A0 + A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001204 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001205
1206cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001207 return ret;
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001208}
1209
1210#undef P521_WIDTH
1211#undef P521_MASK
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001212#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001214#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard32b04c12013-12-02 15:49:09 +01001215
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001216#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001217
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218/* Size of p255 in terms of mbedtls_mpi_uint */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001219#define P255_WIDTH (255 / 8 / sizeof(mbedtls_mpi_uint) + 1)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001220
1221/*
1222 * Fast quasi-reduction modulo p255 = 2^255 - 19
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001223 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001224 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001225static int ecp_mod_p255(mbedtls_mpi *N)
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001226{
Janos Follath24eed8d2019-11-22 13:21:35 +00001227 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001228 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001229 mbedtls_mpi M;
1230 mbedtls_mpi_uint Mp[P255_WIDTH + 2];
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001231
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001232 if (N->n < P255_WIDTH) {
1233 return 0;
1234 }
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001235
1236 /* M = A1 */
1237 M.s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001238 M.n = N->n - (P255_WIDTH - 1);
1239 if (M.n > P255_WIDTH + 1) {
1240 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1241 }
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001242 M.p = Mp;
Dave Rodgmanecb44202023-02-02 15:34:23 +00001243 memset(Mp, 0, sizeof(Mp));
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001244 memcpy(Mp, N->p + P255_WIDTH - 1, M.n * sizeof(mbedtls_mpi_uint));
1245 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, 255 % (8 * sizeof(mbedtls_mpi_uint))));
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001246 M.n++; /* Make room for multiplication by 19 */
1247
1248 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001249 MBEDTLS_MPI_CHK(mbedtls_mpi_set_bit(N, 255, 0));
1250 for (i = P255_WIDTH; i < N->n; i++) {
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001251 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001252 }
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001253
1254 /* N = A0 + 19 * A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001255 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&M, &M, 19));
1256 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001257
1258cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001259 return ret;
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001260}
Manuel Pégourié-Gonnard07894332015-06-23 00:18:41 +02001261#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
Manuel Pégourié-Gonnard3d7053a2013-12-04 20:51:13 +01001262
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001263#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1264
1265/* Size of p448 in terms of mbedtls_mpi_uint */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001266#define P448_WIDTH (448 / 8 / sizeof(mbedtls_mpi_uint))
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001267
1268/* Number of limbs fully occupied by 2^224 (max), and limbs used by it (min) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001269#define DIV_ROUND_UP(X, Y) (((X) + (Y) -1) / (Y))
1270#define P224_WIDTH_MIN (28 / sizeof(mbedtls_mpi_uint))
1271#define P224_WIDTH_MAX DIV_ROUND_UP(28, sizeof(mbedtls_mpi_uint))
1272#define P224_UNUSED_BITS ((P224_WIDTH_MAX * sizeof(mbedtls_mpi_uint) * 8) - 224)
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001273
1274/*
1275 * Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
1276 * Write N as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return
1277 * A0 + A1 + B1 + (B0 + B1) * 2^224. This is different to the reference
1278 * implementation of Curve448, which uses its own special 56-bit limbs rather
1279 * than a generic bignum library. We could squeeze some extra speed out on
1280 * 32-bit machines by splitting N up into 32-bit limbs and doing the
1281 * arithmetic using the limbs directly as we do for the NIST primes above,
1282 * but for 64-bit targets it should use half the number of operations if we do
1283 * the reduction with 224-bit limbs, since mpi_add_mpi will then use 64-bit adds.
1284 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001285static int ecp_mod_p448(mbedtls_mpi *N)
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001286{
Janos Follath24eed8d2019-11-22 13:21:35 +00001287 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001288 size_t i;
1289 mbedtls_mpi M, Q;
1290 mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
1291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001292 if (N->n <= P448_WIDTH) {
1293 return 0;
1294 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001295
1296 /* M = A1 */
1297 M.s = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001298 M.n = N->n - (P448_WIDTH);
1299 if (M.n > P448_WIDTH) {
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001300 /* Shouldn't be called with N larger than 2^896! */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001301 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
1302 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001303 M.p = Mp;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001304 memset(Mp, 0, sizeof(Mp));
1305 memcpy(Mp, N->p + P448_WIDTH, M.n * sizeof(mbedtls_mpi_uint));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001306
1307 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001308 for (i = P448_WIDTH; i < N->n; i++) {
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001309 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001310 }
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001311
1312 /* N += A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001313 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001314
1315 /* Q = B1, N += B1 */
1316 Q = M;
1317 Q.p = Qp;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001318 memcpy(Qp, Mp, sizeof(Qp));
1319 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Q, 224));
1320 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &Q));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001321
1322 /* M = (B0 + B1) * 2^224, N += M */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001323 if (sizeof(mbedtls_mpi_uint) > 4) {
1324 Mp[P224_WIDTH_MIN] &= ((mbedtls_mpi_uint)-1) >> (P224_UNUSED_BITS);
1325 }
1326 for (i = P224_WIDTH_MAX; i < M.n; ++i) {
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001327 Mp[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001328 }
1329 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&M, &M, &Q));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001330 M.n = P448_WIDTH + 1; /* Make room for shifted carry bit from the addition */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001331 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&M, 224));
1332 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(N, N, &M));
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001333
1334cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001335 return ret;
Nicholas Wilson08f3ef12015-11-10 13:10:01 +00001336}
1337#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
1338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001339#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
1340 defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
1341 defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001342/*
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001343 * Fast quasi-reduction modulo P = 2^s - R,
1344 * with R about 33 bits, used by the Koblitz curves.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001345 *
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001346 * Write N as A0 + 2^224 A1, return A0 + R * A1.
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001347 * Actually do two passes, since R is big.
1348 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001349#define P_KOBLITZ_MAX (256 / 8 / sizeof(mbedtls_mpi_uint)) // Max limbs in P
1350#define P_KOBLITZ_R (8 / sizeof(mbedtls_mpi_uint)) // Limbs in R
Chien Wongb6d57932024-02-07 21:48:12 +08001351static inline int ecp_mod_koblitz(mbedtls_mpi *N, const mbedtls_mpi_uint *Rp, size_t p_limbs,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001352 size_t adjust, size_t shift, mbedtls_mpi_uint mask)
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001353{
Janos Follath24eed8d2019-11-22 13:21:35 +00001354 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001355 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001356 mbedtls_mpi M, R;
Janos Follath7dadc2f2017-01-27 16:05:20 +00001357 mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001358
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001359 if (N->n < p_limbs) {
1360 return 0;
1361 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001362
1363 /* Init R */
1364 R.s = 1;
Chien Wongb6d57932024-02-07 21:48:12 +08001365 R.p = (mbedtls_mpi_uint *) Rp; /* R.p will not be modified so the cast is safe */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001366 R.n = P_KOBLITZ_R;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001367
1368 /* Common setup for M */
1369 M.s = 1;
1370 M.p = Mp;
1371
1372 /* M = A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001373 M.n = N->n - (p_limbs - adjust);
1374 if (M.n > p_limbs + adjust) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001375 M.n = p_limbs + adjust;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001376 }
Dave Rodgman18688702023-02-02 12:40:50 +00001377 memset(Mp, 0, sizeof(Mp));
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001378 memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
1379 if (shift != 0) {
1380 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
1381 }
Janos Follath7dadc2f2017-01-27 16:05:20 +00001382 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001383
1384 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001385 if (mask != 0) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001386 N->p[p_limbs - 1] &= mask;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001387 }
1388 for (i = p_limbs; i < N->n; i++) {
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001389 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001390 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001391
1392 /* N = A0 + R * A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001393 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
1394 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001395
1396 /* Second pass */
1397
1398 /* M = A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001399 M.n = N->n - (p_limbs - adjust);
1400 if (M.n > p_limbs + adjust) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001401 M.n = p_limbs + adjust;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001402 }
Dave Rodgman18688702023-02-02 12:40:50 +00001403 memset(Mp, 0, sizeof(Mp));
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001404 memcpy(Mp, N->p + p_limbs - adjust, M.n * sizeof(mbedtls_mpi_uint));
1405 if (shift != 0) {
1406 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&M, shift));
1407 }
Janos Follath7dadc2f2017-01-27 16:05:20 +00001408 M.n += R.n; /* Make room for multiplication by R */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001409
1410 /* N = A0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001411 if (mask != 0) {
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001412 N->p[p_limbs - 1] &= mask;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001413 }
1414 for (i = p_limbs; i < N->n; i++) {
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001415 N->p[i] = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001416 }
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001417
1418 /* N = A0 + R * A1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001419 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&M, &M, &R));
1420 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(N, N, &M));
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001421
1422cleanup:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001423 return ret;
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001424}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001425#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||
1426 MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||
1427 MBEDTLS_ECP_DP_SECP256K1_ENABLED) */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001430/*
1431 * Fast quasi-reduction modulo p192k1 = 2^192 - R,
1432 * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119
1433 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001434static int ecp_mod_p192k1(mbedtls_mpi *N)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001435{
Chien Wongb6d57932024-02-07 21:48:12 +08001436 static const mbedtls_mpi_uint Rp[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001437 MBEDTLS_BYTES_TO_T_UINT_8(0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00,
1438 0x00)
1439 };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001441 return ecp_mod_koblitz(N, Rp, 192 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1442 0);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001443}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001446#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001447/*
1448 * Fast quasi-reduction modulo p224k1 = 2^224 - R,
1449 * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
1450 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001451static int ecp_mod_p224k1(mbedtls_mpi *N)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001452{
Chien Wongb6d57932024-02-07 21:48:12 +08001453 static const mbedtls_mpi_uint Rp[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001454 MBEDTLS_BYTES_TO_T_UINT_8(0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00,
1455 0x00)
1456 };
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001458#if defined(MBEDTLS_HAVE_INT64)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001459 return ecp_mod_koblitz(N, Rp, 4, 1, 32, 0xFFFFFFFF);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001460#else
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001461 return ecp_mod_koblitz(N, Rp, 224 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1462 0);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001463#endif
1464}
1465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001468#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001469/*
1470 * Fast quasi-reduction modulo p256k1 = 2^256 - R,
1471 * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
1472 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001473static int ecp_mod_p256k1(mbedtls_mpi *N)
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001474{
Chien Wongb6d57932024-02-07 21:48:12 +08001475 static const mbedtls_mpi_uint Rp[] = {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001476 MBEDTLS_BYTES_TO_T_UINT_8(0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00,
1477 0x00)
1478 };
1479 return ecp_mod_koblitz(N, Rp, 256 / 8 / sizeof(mbedtls_mpi_uint), 0, 0,
1480 0);
Manuel Pégourié-Gonnard9af7d3a2014-01-18 17:28:59 +01001481}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
Manuel Pégourié-Gonnard8887d8d2014-01-17 23:17:10 +01001483
Janos Follathb0697532016-08-18 12:38:46 +01001484#endif /* !MBEDTLS_ECP_ALT */
1485
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486#endif /* MBEDTLS_ECP_C */