ecp_curves.c 51.3 KB
Newer Older
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1 2 3
/*
 *  Elliptic curves over GF(p): curve-specific data and functions
 *
4
 *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
5
 *
6
 *  This file is part of mbed TLS (https://tls.mbed.org)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

23
#if !defined(MBEDTLS_CONFIG_FILE)
24
#include "mbedtls/config.h"
25
#else
26
#include MBEDTLS_CONFIG_FILE
27
#endif
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
28

29
#if defined(MBEDTLS_ECP_C)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
30

31
#include "mbedtls/ecp.h"
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
32

33 34
#include <string.h>

35
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline)
36
#define inline __inline
37
#endif
38

39 40
/*
 * Conversion macros for embedded constants:
41
 * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2
42
 */
43
#if defined(MBEDTLS_HAVE_INT32)
44

45
#define BYTES_TO_T_UINT_4( a, b, c, d )             \
46 47 48 49
    ( (mbedtls_mpi_uint) a <<  0 ) |                          \
    ( (mbedtls_mpi_uint) b <<  8 ) |                          \
    ( (mbedtls_mpi_uint) c << 16 ) |                          \
    ( (mbedtls_mpi_uint) d << 24 )
50

51 52 53
#define BYTES_TO_T_UINT_2( a, b )                   \
    BYTES_TO_T_UINT_4( a, b, 0, 0 )

54
#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
55
    BYTES_TO_T_UINT_4( a, b, c, d ),                \
56
    BYTES_TO_T_UINT_4( e, f, g, h )
57 58 59

#else /* 64-bits */

60
#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \
61 62 63 64 65 66 67 68
    ( (mbedtls_mpi_uint) a <<  0 ) |                          \
    ( (mbedtls_mpi_uint) b <<  8 ) |                          \
    ( (mbedtls_mpi_uint) c << 16 ) |                          \
    ( (mbedtls_mpi_uint) d << 24 ) |                          \
    ( (mbedtls_mpi_uint) e << 32 ) |                          \
    ( (mbedtls_mpi_uint) f << 40 ) |                          \
    ( (mbedtls_mpi_uint) g << 48 ) |                          \
    ( (mbedtls_mpi_uint) h << 56 )
69

70 71 72 73 74 75
#define BYTES_TO_T_UINT_4( a, b, c, d )             \
    BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 )

#define BYTES_TO_T_UINT_2( a, b )                   \
    BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 )

76
#endif /* bits in mbedtls_mpi_uint */
77

78 79 80 81 82
/*
 * Note: the constants are in little-endian order
 * to be directly usable in MPIs
 */

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
83 84 85
/*
 * Domain parameters for secp192r1
 */
86 87
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
static const mbedtls_mpi_uint secp192r1_p[] = {
88 89 90
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
91
};
92
static const mbedtls_mpi_uint secp192r1_b[] = {
93 94 95
    BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ),
    BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ),
    BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ),
96
};
97
static const mbedtls_mpi_uint secp192r1_gx[] = {
98 99 100
    BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ),
    BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ),
    BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ),
101
};
102
static const mbedtls_mpi_uint secp192r1_gy[] = {
103 104 105
    BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ),
    BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ),
    BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ),
106
};
107
static const mbedtls_mpi_uint secp192r1_n[] = {
108 109 110
    BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ),
    BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
111
};
112
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
113 114 115 116

/*
 * Domain parameters for secp224r1
 */
117 118
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
static const mbedtls_mpi_uint secp224r1_p[] = {
119 120 121 122
    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
123
};
124
static const mbedtls_mpi_uint secp224r1_b[] = {
125 126 127
    BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ),
    BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ),
    BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ),
128
    BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ),
129
};
130
static const mbedtls_mpi_uint secp224r1_gx[] = {
131 132 133
    BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ),
    BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ),
    BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ),
134
    BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ),
135
};
136
static const mbedtls_mpi_uint secp224r1_gy[] = {
137 138 139
    BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ),
    BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ),
    BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ),
140
    BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ),
141
};
142
static const mbedtls_mpi_uint secp224r1_n[] = {
143 144 145
    BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ),
    BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
146
    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
147
};
148
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
149 150 151 152

/*
 * Domain parameters for secp256r1
 */
153 154
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
static const mbedtls_mpi_uint secp256r1_p[] = {
155 156 157 158
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
    BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
159
};
160
static const mbedtls_mpi_uint secp256r1_b[] = {
161 162 163 164
    BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ),
    BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ),
    BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ),
    BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ),
165
};
166
static const mbedtls_mpi_uint secp256r1_gx[] = {
167 168 169 170
    BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ),
    BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ),
    BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ),
    BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ),
171
};
172
static const mbedtls_mpi_uint secp256r1_gy[] = {
173 174 175 176
    BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ),
    BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ),
    BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ),
    BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ),
177
};
178
static const mbedtls_mpi_uint secp256r1_n[] = {
179 180 181 182
    BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ),
    BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
183
};
184
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
185 186 187 188

/*
 * Domain parameters for secp384r1
 */
189 190
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
static const mbedtls_mpi_uint secp384r1_p[] = {
191 192 193 194 195 196
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ),
    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
197
};
198
static const mbedtls_mpi_uint secp384r1_b[] = {
199 200 201 202 203 204
    BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ),
    BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ),
    BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ),
    BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ),
    BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ),
    BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ),
205
};
206
static const mbedtls_mpi_uint secp384r1_gx[] = {
207 208 209 210 211 212
    BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ),
    BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ),
    BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ),
    BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ),
    BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ),
    BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ),
213
};
214
static const mbedtls_mpi_uint secp384r1_gy[] = {
215 216 217 218 219 220
    BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ),
    BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ),
    BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ),
    BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ),
    BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ),
    BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ),
221
};
222
static const mbedtls_mpi_uint secp384r1_n[] = {
223 224 225 226 227 228
    BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ),
    BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ),
    BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
229
};
230
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
231 232 233 234

/*
 * Domain parameters for secp521r1
 */
235 236
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
static const mbedtls_mpi_uint secp521r1_p[] = {
237 238 239 240 241 242 243 244
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
245
    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
246
};
247
static const mbedtls_mpi_uint secp521r1_b[] = {
248 249 250 251 252 253 254 255
    BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ),
    BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ),
    BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ),
    BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ),
    BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ),
    BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ),
    BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ),
    BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ),
256
    BYTES_TO_T_UINT_2( 0x51, 0x00 ),
257
};
258
static const mbedtls_mpi_uint secp521r1_gx[] = {
259 260 261 262 263 264 265 266
    BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ),
    BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ),
    BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ),
    BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ),
    BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ),
    BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ),
    BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ),
    BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ),
267
    BYTES_TO_T_UINT_2( 0xC6, 0x00 ),
268
};
269
static const mbedtls_mpi_uint secp521r1_gy[] = {
270 271 272 273 274 275 276 277
    BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ),
    BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ),
    BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ),
    BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ),
    BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ),
    BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ),
    BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ),
    BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ),
278
    BYTES_TO_T_UINT_2( 0x18, 0x01 ),
279
};
280
static const mbedtls_mpi_uint secp521r1_n[] = {
281 282 283 284 285 286 287 288
    BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ),
    BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ),
    BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ),
    BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ),
    BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
289
    BYTES_TO_T_UINT_2( 0xFF, 0x01 ),
290
};
291
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
292

293 294
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
static const mbedtls_mpi_uint secp192k1_p[] = {
295 296 297 298
    BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
};
299
static const mbedtls_mpi_uint secp192k1_a[] = {
300 301
    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
};
302
static const mbedtls_mpi_uint secp192k1_b[] = {
303 304
    BYTES_TO_T_UINT_2( 0x03, 0x00 ),
};
305
static const mbedtls_mpi_uint secp192k1_gx[] = {
306 307 308 309
    BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ),
    BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ),
    BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ),
};
310
static const mbedtls_mpi_uint secp192k1_gy[] = {
311 312 313 314
    BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ),
    BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ),
    BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ),
};
315
static const mbedtls_mpi_uint secp192k1_n[] = {
316 317 318 319
    BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ),
    BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
};
320
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
321

322 323
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
static const mbedtls_mpi_uint secp224k1_p[] = {
324 325 326 327 328
    BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ),
};
329
static const mbedtls_mpi_uint secp224k1_a[] = {
330 331
    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
};
332
static const mbedtls_mpi_uint secp224k1_b[] = {
333 334
    BYTES_TO_T_UINT_2( 0x05, 0x00 ),
};
335
static const mbedtls_mpi_uint secp224k1_gx[] = {
336 337 338 339 340
    BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ),
    BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ),
    BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ),
    BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ),
};
341
static const mbedtls_mpi_uint secp224k1_gy[] = {
342 343 344 345 346
    BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ),
    BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ),
    BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ),
    BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ),
};
347
static const mbedtls_mpi_uint secp224k1_n[] = {
348 349 350 351 352
    BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ),
    BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ),
    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ),
    BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ),
};
353
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
354

355 356
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
static const mbedtls_mpi_uint secp256k1_p[] = {
357 358 359 360 361
    BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
};
362
static const mbedtls_mpi_uint secp256k1_a[] = {
363 364
    BYTES_TO_T_UINT_2( 0x00, 0x00 ),
};
365
static const mbedtls_mpi_uint secp256k1_b[] = {
366 367
    BYTES_TO_T_UINT_2( 0x07, 0x00 ),
};
368
static const mbedtls_mpi_uint secp256k1_gx[] = {
369 370 371 372 373
    BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ),
    BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ),
    BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ),
    BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ),
};
374
static const mbedtls_mpi_uint secp256k1_gy[] = {
375 376 377 378 379
    BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ),
    BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ),
    BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ),
    BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ),
};
380
static const mbedtls_mpi_uint secp256k1_n[] = {
381 382 383 384 385
    BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ),
    BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ),
    BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
    BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ),
};
386
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
387

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
388 389 390
/*
 * Domain parameters for brainpoolP256r1 (RFC 5639 3.4)
 */
391 392
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
static const mbedtls_mpi_uint brainpoolP256r1_p[] = {
393 394 395 396
    BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ),
    BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ),
    BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
397
};
398
static const mbedtls_mpi_uint brainpoolP256r1_a[] = {
399 400 401 402
    BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ),
    BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ),
    BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ),
    BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ),
403
};
404
static const mbedtls_mpi_uint brainpoolP256r1_b[] = {
405 406 407 408
    BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ),
    BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ),
    BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ),
    BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ),
409
};
410
static const mbedtls_mpi_uint brainpoolP256r1_gx[] = {
411 412 413 414
    BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ),
    BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ),
    BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ),
    BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ),
415
};
416
static const mbedtls_mpi_uint brainpoolP256r1_gy[] = {
417 418 419 420
    BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ),
    BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ),
    BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ),
    BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ),
421
};
422
static const mbedtls_mpi_uint brainpoolP256r1_n[] = {
423 424 425 426
    BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ),
    BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ),
    BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ),
    BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ),
427
};
428
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
429 430 431 432

/*
 * Domain parameters for brainpoolP384r1 (RFC 5639 3.6)
 */
433 434
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
static const mbedtls_mpi_uint brainpoolP384r1_p[] = {
435 436 437 438 439 440
    BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ),
    BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ),
    BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ),
    BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
441
};
442
static const mbedtls_mpi_uint brainpoolP384r1_a[] = {
443 444 445 446 447 448
    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
    BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ),
    BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ),
    BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ),
    BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ),
    BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ),
449
};
450
static const mbedtls_mpi_uint brainpoolP384r1_b[] = {
451 452 453 454 455 456
    BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ),
    BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ),
    BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ),
    BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ),
    BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ),
    BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ),
457
};
458
static const mbedtls_mpi_uint brainpoolP384r1_gx[] = {
459 460 461 462 463 464
    BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ),
    BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ),
    BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ),
    BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ),
    BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ),
    BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ),
465
};
466
static const mbedtls_mpi_uint brainpoolP384r1_gy[] = {
467 468 469 470 471 472
    BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ),
    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ),
    BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ),
    BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ),
    BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ),
    BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ),
473
};
474
static const mbedtls_mpi_uint brainpoolP384r1_n[] = {
475 476 477 478 479 480
    BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ),
    BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ),
    BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ),
    BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ),
    BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ),
    BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ),
481
};
482
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
483 484 485 486

/*
 * Domain parameters for brainpoolP512r1 (RFC 5639 3.7)
 */
487 488
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
static const mbedtls_mpi_uint brainpoolP512r1_p[] = {
489 490 491 492 493 494 495 496
    BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ),
    BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ),
    BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ),
    BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ),
    BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
497
};
498
static const mbedtls_mpi_uint brainpoolP512r1_a[] = {
499 500 501 502 503 504 505 506
    BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ),
    BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ),
    BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ),
    BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ),
    BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ),
    BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ),
    BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ),
    BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ),
507
};
508
static const mbedtls_mpi_uint brainpoolP512r1_b[] = {
509 510 511 512 513 514 515 516
    BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ),
    BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ),
    BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ),
    BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ),
    BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ),
    BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ),
    BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ),
    BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ),
517
};
518
static const mbedtls_mpi_uint brainpoolP512r1_gx[] = {
519 520 521 522 523 524 525 526
    BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ),
    BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ),
    BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ),
    BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ),
    BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ),
    BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ),
    BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ),
    BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ),
527
};
528
static const mbedtls_mpi_uint brainpoolP512r1_gy[] = {
529 530 531 532 533 534 535 536
    BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ),
    BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ),
    BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ),
    BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ),
    BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ),
    BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ),
    BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ),
    BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ),
537
};
538
static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
539 540 541 542 543 544 545 546
    BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ),
    BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ),
    BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ),
    BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ),
    BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ),
    BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ),
    BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ),
    BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ),
547
};
548
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
549 550

/*
551
 * Create an MPI from embedded constants
552
 * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
553
 */
554
static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len )
555 556
{
    X->s = 1;
557 558
    X->n = len / sizeof( mbedtls_mpi_uint );
    X->p = (mbedtls_mpi_uint *) p;
559 560
}

561 562 563
/*
 * Set an MPI to static value 1
 */
564
static inline void ecp_mpi_set1( mbedtls_mpi *X )
565
{
566
    static mbedtls_mpi_uint one[] = { 1 };
567 568 569 570 571
    X->s = 1;
    X->n = 1;
    X->p = one;
}

572 573 574
/*
 * Make group available from embedded constants
 */
575 576 577 578 579 580 581
static int ecp_group_load( mbedtls_ecp_group *grp,
                           const mbedtls_mpi_uint *p,  size_t plen,
                           const mbedtls_mpi_uint *a,  size_t alen,
                           const mbedtls_mpi_uint *b,  size_t blen,
                           const mbedtls_mpi_uint *gx, size_t gxlen,
                           const mbedtls_mpi_uint *gy, size_t gylen,
                           const mbedtls_mpi_uint *n,  size_t nlen)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
582
{
583
    ecp_mpi_load( &grp->P, p, plen );
584
    if( a != NULL )
585 586 587
        ecp_mpi_load( &grp->A, a, alen );
    ecp_mpi_load( &grp->B, b, blen );
    ecp_mpi_load( &grp->N, n, nlen );
588

589 590
    ecp_mpi_load( &grp->G.X, gx, gxlen );
    ecp_mpi_load( &grp->G.Y, gy, gylen );
591
    ecp_mpi_set1( &grp->G.Z );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
592

593 594
    grp->pbits = mbedtls_mpi_bitlen( &grp->P );
    grp->nbits = mbedtls_mpi_bitlen( &grp->N );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
595

596 597
    grp->h = 1;

598
    return( 0 );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
599 600
}

601
#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
602
/* Forward declarations */
603 604
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
static int ecp_mod_p192( mbedtls_mpi * );
605
#endif
606 607
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
static int ecp_mod_p224( mbedtls_mpi * );
608
#endif
609 610
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
static int ecp_mod_p256( mbedtls_mpi * );
611
#endif
612 613
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
static int ecp_mod_p384( mbedtls_mpi * );
614
#endif
615 616
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
static int ecp_mod_p521( mbedtls_mpi * );
617
#endif
618 619 620 621

#define NIST_MODP( P )      grp->modp = ecp_mod_ ## P;
#else
#define NIST_MODP( P )
622
#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
623

624
/* Additional forward declarations */
625
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
626
static int ecp_mod_p255( mbedtls_mpi * );
627
#endif
628 629
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
static int ecp_mod_p192k1( mbedtls_mpi * );
630
#endif
631 632
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
static int ecp_mod_p224k1( mbedtls_mpi * );
633
#endif
634 635
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
static int ecp_mod_p256k1( mbedtls_mpi * );
636 637
#endif

638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
#define LOAD_GROUP_A( G )   ecp_group_load( grp,            \
                            G ## _p,  sizeof( G ## _p  ),   \
                            G ## _a,  sizeof( G ## _a  ),   \
                            G ## _b,  sizeof( G ## _b  ),   \
                            G ## _gx, sizeof( G ## _gx ),   \
                            G ## _gy, sizeof( G ## _gy ),   \
                            G ## _n,  sizeof( G ## _n  ) )

#define LOAD_GROUP( G )     ecp_group_load( grp,            \
                            G ## _p,  sizeof( G ## _p  ),   \
                            NULL,     0,                    \
                            G ## _b,  sizeof( G ## _b  ),   \
                            G ## _gx, sizeof( G ## _gx ),   \
                            G ## _gy, sizeof( G ## _gy ),   \
                            G ## _n,  sizeof( G ## _n  ) )

654
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
655 656 657
/*
 * Specialized function for creating the Curve25519 group
 */
658
static int ecp_use_curve25519( mbedtls_ecp_group *grp )
659 660 661 662
{
    int ret;

    /* Actually ( A + 2 ) / 4 */
663
    MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) );
664 665

    /* P = 2^255 - 19 */
666 667 668
    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) );
669
    grp->pbits = mbedtls_mpi_bitlen( &grp->P );
670

671 672
    /* Y intentionaly not set, since we use x/z coordinates.
     * This is used as a marker to identify Montgomery curves! */
673 674 675
    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) );
    mbedtls_mpi_free( &grp->G.Y );
676

677 678 679 680 681
    /* Actually, the required msb for private keys */
    grp->nbits = 254;

cleanup:
    if( ret != 0 )
682
        mbedtls_ecp_group_free( grp );
683 684 685

    return( ret );
}
686
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
687

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
688 689 690
/*
 * Set a group using well-known domain parameters
 */
691
int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
692
{
693
    mbedtls_ecp_group_free( grp );
694

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
695 696 697 698
    grp->id = id;

    switch( id )
    {
699 700
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
        case MBEDTLS_ECP_DP_SECP192R1:
701
            NIST_MODP( p192 );
702
            return( LOAD_GROUP( secp192r1 ) );
703
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
704

705 706
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
        case MBEDTLS_ECP_DP_SECP224R1:
707
            NIST_MODP( p224 );
708
            return( LOAD_GROUP( secp224r1 ) );
709
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
710

711 712
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
        case MBEDTLS_ECP_DP_SECP256R1:
713
            NIST_MODP( p256 );
714
            return( LOAD_GROUP( secp256r1 ) );
715
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
716

717 718
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
        case MBEDTLS_ECP_DP_SECP384R1:
719
            NIST_MODP( p384 );
720
            return( LOAD_GROUP( secp384r1 ) );
721
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
722

723 724
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
        case MBEDTLS_ECP_DP_SECP521R1:
725
            NIST_MODP( p521 );
726
            return( LOAD_GROUP( secp521r1 ) );
727
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
728

729 730
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
        case MBEDTLS_ECP_DP_SECP192K1:
731
            grp->modp = ecp_mod_p192k1;
732
            return( LOAD_GROUP_A( secp192k1 ) );
733
#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
734

735 736
#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
        case MBEDTLS_ECP_DP_SECP224K1:
737
            grp->modp = ecp_mod_p224k1;
738
            return( LOAD_GROUP_A( secp224k1 ) );
739
#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
740

741 742
#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
        case MBEDTLS_ECP_DP_SECP256K1:
743
            grp->modp = ecp_mod_p256k1;
744
            return( LOAD_GROUP_A( secp256k1 ) );
745
#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
746

747 748
#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)
        case MBEDTLS_ECP_DP_BP256R1:
749
            return( LOAD_GROUP_A( brainpoolP256r1 ) );
750
#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
751

752 753
#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
        case MBEDTLS_ECP_DP_BP384R1:
754
            return( LOAD_GROUP_A( brainpoolP384r1 ) );
755
#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
756

757 758
#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
        case MBEDTLS_ECP_DP_BP512R1:
759
            return( LOAD_GROUP_A( brainpoolP512r1 ) );
760
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
761

762 763
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
        case MBEDTLS_ECP_DP_CURVE25519:
764
            grp->modp = ecp_mod_p255;
765
            return( ecp_use_curve25519( grp ) );
766
#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
767

Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
768
        default:
769 770
            mbedtls_ecp_group_free( grp );
            return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
771 772 773
    }
}

774
#if defined(MBEDTLS_ECP_NIST_OPTIM)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
775 776 777 778 779 780 781 782 783 784
/*
 * Fast reduction modulo the primes used by the NIST curves.
 *
 * These functions are critical for speed, but not needed for correct
 * operations. So, we make the choice to heavily rely on the internals of our
 * bignum library, which creates a tight coupling between these functions and
 * our MPI implementation.  However, the coupling between the ECP module and
 * MPI remains loose, since these functions can be deactivated at will.
 */

785
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
786 787 788 789 790 791 792 793
/*
 * Compared to the way things are presented in FIPS 186-3 D.2,
 * we proceed in columns, from right (least significant chunk) to left,
 * adding chunks to N in place, and keeping a carry for the next chunk.
 * This avoids moving things around in memory, and uselessly adding zeros,
 * compared to the more straightforward, line-oriented approach.
 *
 * For this prime we need to handle data in chunks of 64 bits.
794 795
 * Since this is always a multiple of our basic mbedtls_mpi_uint, we can
 * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it.
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
796 797 798
 */

/* Add 64-bit chunks (dst += src) and update carry */
799
static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
800 801
{
    unsigned char i;
802 803
    mbedtls_mpi_uint c = 0;
    for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
804 805 806 807 808 809 810 811
    {
        *dst += c;      c  = ( *dst < c );
        *dst += *src;   c += ( *dst < *src );
    }
    *carry += c;
}

/* Add carry to a 64-bit chunk and update carry */
812
static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
813 814
{
    unsigned char i;
815
    for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
816 817 818 819 820 821
    {
        *dst += *carry;
        *carry  = ( *dst < *carry );
    }
}

822
#define WIDTH       8 / sizeof( mbedtls_mpi_uint )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
823 824 825 826 827 828 829 830
#define A( i )      N->p + i * WIDTH
#define ADD( i )    add64( p, A( i ), &c )
#define NEXT        p += WIDTH; carry64( p, &c )
#define LAST        p += WIDTH; *p = c; while( ++p < end ) *p = 0

/*
 * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
 */
831
static int ecp_mod_p192( mbedtls_mpi *N )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
832 833
{
    int ret;
834 835
    mbedtls_mpi_uint c = 0;
    mbedtls_mpi_uint *p, *end;
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
836 837

    /* Make sure we have enough blocks so that A(5) is legal */
838
    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855

    p = N->p;
    end = p + N->n;

    ADD( 3 ); ADD( 5 );             NEXT; // A0 += A3 + A5
    ADD( 3 ); ADD( 4 ); ADD( 5 );   NEXT; // A1 += A3 + A4 + A5
    ADD( 4 ); ADD( 5 );             LAST; // A2 += A4 + A5

cleanup:
    return( ret );
}

#undef WIDTH
#undef A
#undef ADD
#undef NEXT
#undef LAST
856
#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
857

858 859 860
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) ||   \
    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ||   \
    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
/*
 * The reader is advised to first understand ecp_mod_p192() since the same
 * general structure is used here, but with additional complications:
 * (1) chunks of 32 bits, and (2) subtractions.
 */

/*
 * For these primes, we need to handle data in chunks of 32 bits.
 * This makes it more complicated if we use 64 bits limbs in MPI,
 * which prevents us from using a uniform access method as for p192.
 *
 * So, we define a mini abstraction layer to access 32 bit chunks,
 * load them in 'cur' for work, and store them back from 'cur' when done.
 *
 * While at it, also define the size of N in terms of 32-bit chunks.
 */
#define LOAD32      cur = A( i );

879
#if defined(MBEDTLS_HAVE_INT32)  /* 32 bit */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
880 881 882 883 884 885 886 887 888 889 890 891

#define MAX32       N->n
#define A( j )      N->p[j]
#define STORE32     N->p[i] = cur;

#else                               /* 64-bit */

#define MAX32       N->n * 2
#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] )
#define STORE32                                   \
    if( i % 2 ) {                                 \
        N->p[i/2] &= 0x00000000FFFFFFFF;          \
892
        N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32;        \
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
893 894
    } else {                                      \
        N->p[i/2] &= 0xFFFFFFFF00000000;          \
895
        N->p[i/2] |= (mbedtls_mpi_uint) cur;                \
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
896 897
    }

898
#endif /* sizeof( mbedtls_mpi_uint ) */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926

/*
 * Helpers for addition and subtraction of chunks, with signed carry.
 */
static inline void add32( uint32_t *dst, uint32_t src, signed char *carry )
{
    *dst += src;
    *carry += ( *dst < src );
}

static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
{
    *carry -= ( *dst < src );
    *dst -= src;
}

#define ADD( j )    add32( &cur, A( j ), &c );
#define SUB( j )    sub32( &cur, A( j ), &c );

/*
 * Helpers for the main 'loop'
 * (see fix_negative for the motivation of C)
 */
#define INIT( b )                                           \
    int ret;                                                \
    signed char c = 0, cc;                                  \
    uint32_t cur;                                           \
    size_t i = 0, bits = b;                                 \
927 928
    mbedtls_mpi C;                                                  \
    mbedtls_mpi_uint Cp[ b / 8 / sizeof( mbedtls_mpi_uint) + 1 ];               \
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
929 930
                                                            \
    C.s = 1;                                                \
931
    C.n = b / 8 / sizeof( mbedtls_mpi_uint) + 1;                      \
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
932
    C.p = Cp;                                               \
933
    memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) );                \
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
934
                                                            \
935
    MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, b * 2 / 8 / sizeof( mbedtls_mpi_uint ) ) ); \
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955
    LOAD32;

#define NEXT                    \
    STORE32; i++; LOAD32;       \
    cc = c; c = 0;              \
    if( cc < 0 )                \
        sub32( &cur, -cc, &c ); \
    else                        \
        add32( &cur, cc, &c );  \

#define LAST                                    \
    STORE32; i++;                               \
    cur = c > 0 ? c : 0; STORE32;               \
    cur = 0; while( ++i < MAX32 ) { STORE32; }  \
    if( c < 0 ) fix_negative( N, c, &C, bits );

/*
 * If the result is negative, we get it in the form
 * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits'
 */
956
static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
957 958 959 960
{
    int ret;

    /* C = - c * 2^(bits + 32) */
961
#if !defined(MBEDTLS_HAVE_INT64)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
962 963 964
    ((void) bits);
#else
    if( bits == 224 )
965
        C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
966 967
    else
#endif
968
        C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
969 970

    /* N = - ( C - N ) */
971
    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
972 973 974 975 976 977 978
    N->s = -1;

cleanup:

    return( ret );
}

979
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
980 981 982
/*
 * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
 */
983
static int ecp_mod_p224( mbedtls_mpi *N )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
984 985 986 987 988 989 990 991 992 993 994 995 996 997
{
    INIT( 224 );

    SUB(  7 ); SUB( 11 );               NEXT; // A0 += -A7 - A11
    SUB(  8 ); SUB( 12 );               NEXT; // A1 += -A8 - A12
    SUB(  9 ); SUB( 13 );               NEXT; // A2 += -A9 - A13
    SUB( 10 ); ADD(  7 ); ADD( 11 );    NEXT; // A3 += -A10 + A7 + A11
    SUB( 11 ); ADD(  8 ); ADD( 12 );    NEXT; // A4 += -A11 + A8 + A12
    SUB( 12 ); ADD(  9 ); ADD( 13 );    NEXT; // A5 += -A12 + A9 + A13
    SUB( 13 ); ADD( 10 );               LAST; // A6 += -A13 + A10

cleanup:
    return( ret );
}
998
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
999

1000
#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1001 1002 1003
/*
 * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
 */
1004
static int ecp_mod_p256( mbedtls_mpi *N )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
{
    INIT( 256 );

    ADD(  8 ); ADD(  9 );
    SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 );             NEXT; // A0

    ADD(  9 ); ADD( 10 );
    SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 );             NEXT; // A1

    ADD( 10 ); ADD( 11 );
    SUB( 13 ); SUB( 14 ); SUB( 15 );                        NEXT; // A2

    ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 );
    SUB( 15 ); SUB(  8 ); SUB(  9 );                        NEXT; // A3

    ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 );
    SUB(  9 ); SUB( 10 );                                   NEXT; // A4

    ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 );
    SUB( 10 ); SUB( 11 );                                   NEXT; // A5

    ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 );
    SUB(  8 ); SUB(  9 );                                   NEXT; // A6

    ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 );
    SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 );             LAST; // A7

cleanup:
    return( ret );
}
1035
#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1036

1037
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1038 1039 1040
/*
 * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
 */
1041
static int ecp_mod_p384( mbedtls_mpi *N )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
{
    INIT( 384 );

    ADD( 12 ); ADD( 21 ); ADD( 20 );
    SUB( 23 );                                              NEXT; // A0

    ADD( 13 ); ADD( 22 ); ADD( 23 );
    SUB( 12 ); SUB( 20 );                                   NEXT; // A2

    ADD( 14 ); ADD( 23 );
    SUB( 13 ); SUB( 21 );                                   NEXT; // A2

    ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 );
    SUB( 14 ); SUB( 22 ); SUB( 23 );                        NEXT; // A3

    ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 );
    SUB( 15 ); SUB( 23 ); SUB( 23 );                        NEXT; // A4

    ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 );
    SUB( 16 );                                              NEXT; // A5

    ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 );
    SUB( 17 );                                              NEXT; // A6

    ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 );
    SUB( 18 );                                              NEXT; // A7

    ADD( 20 ); ADD( 17 ); ADD( 16 );
    SUB( 19 );                                              NEXT; // A8

    ADD( 21 ); ADD( 18 ); ADD( 17 );
    SUB( 20 );                                              NEXT; // A9

    ADD( 22 ); ADD( 19 ); ADD( 18 );
    SUB( 21 );                                              NEXT; // A10

    ADD( 23 ); ADD( 20 ); ADD( 19 );
    SUB( 22 );                                              LAST; // A11

cleanup:
    return( ret );
}
1084
#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1085 1086 1087 1088 1089 1090 1091 1092 1093

#undef A
#undef LOAD32
#undef STORE32
#undef MAX32
#undef INIT
#undef NEXT
#undef LAST

1094 1095 1096
#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED ||
          MBEDTLS_ECP_DP_SECP256R1_ENABLED ||
          MBEDTLS_ECP_DP_SECP384R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1097

1098
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1099 1100 1101 1102 1103
/*
 * Here we have an actual Mersenne prime, so things are more straightforward.
 * However, chunks are aligned on a 'weird' boundary (521 bits).
 */

1104 1105
/* Size of p521 in terms of mbedtls_mpi_uint */
#define P521_WIDTH      ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1106

1107
/* Bits to keep in the most significant mbedtls_mpi_uint */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1108 1109 1110 1111 1112 1113
#define P521_MASK       0x01FF

/*
 * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5)
 * Write N as A1 + 2^521 A0, return A0 + A1
 */
1114
static int ecp_mod_p521( mbedtls_mpi *N )
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1115 1116 1117
{
    int ret;
    size_t i;
1118 1119 1120
    mbedtls_mpi M;
    mbedtls_mpi_uint Mp[P521_WIDTH + 1];
    /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits:
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
     * we need to hold bits 513 to 1056, which is 34 limbs, that is
     * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */

    if( N->n < P521_WIDTH )
        return( 0 );

    /* M = A1 */
    M.s = 1;
    M.n = N->n - ( P521_WIDTH - 1 );
    if( M.n > P521_WIDTH + 1 )
        M.n = P521_WIDTH + 1;
    M.p = Mp;
1133 1134
    memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1135 1136 1137 1138 1139 1140 1141

    /* N = A0 */
    N->p[P521_WIDTH - 1] &= P521_MASK;
    for( i = P521_WIDTH; i < N->n; i++ )
        N->p[i] = 0;

    /* N = A0 + A1 */
1142
    MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) );
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1143 1144 1145 1146 1147 1148 1149

cleanup:
    return( ret );
}

#undef P521_WIDTH
#undef P521_MASK
1150
#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1151

1152
#endif /* MBEDTLS_ECP_NIST_OPTIM */
Manuel Pégourié-Gonnard's avatar
Manuel Pégourié-Gonnard committed
1153

1154
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
1155

1156 1157
/* Size of p255 in terms of mbedtls_mpi_uint */
#define P255_WIDTH      ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 )
1158 1159 1160

/*
 * Fast quasi-reduction modulo p255 = 2^255 - 19
1161
 * Write N as A0 + 2^255 A1, return A0 + 19 * A1
1162
 */
1163
static int ecp_mod_p255( mbedtls_mpi *N )
1164 1165 1166
{
    int ret;
    size_t i;
1167 1168
    mbedtls_mpi M;
    mbedtls_mpi_uint Mp[P255_WIDTH + 2];
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179

    if( N->n < P255_WIDTH )
        return( 0 );

    /* M = A1 */
    M.s = 1;
    M.n = N->n - ( P255_WIDTH - 1 );
    if( M.n > P255_WIDTH + 1 )
        M.n = P255_WIDTH + 1;
    M.p = Mp;
    memset( Mp, 0, sizeof Mp );
1180 1181
    memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) );
    MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) );
1182 1183 1184
    M.n++; /* Make room for multiplication by 19 */

    /* N = A0 */
1185
    MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) );
1186 1187 1188 1189
    for( i = P255_WIDTH; i < N->n; i++ )
        N->p[i] = 0;

    /* N = A0 + 19 * A1 */
Manuel Pégourié-Gonnard's avatar