1 /* 2 * Copyright (C) 2017 - This file is part of libecc project 3 * 4 * Authors: 5 * Ryad BENADJILA <ryadbenadjila@gmail.com> 6 * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7 * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> 8 * 9 * Contributors: 10 * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> 11 * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> 12 * 13 * This software is licensed under a dual BSD and GPL v2 license. 14 * See LICENSE file at the root folder of the project. 15 */ 16 #include <libecc/lib_ecc_config.h> 17 #ifdef WITH_CURVE_SECP521R1 18 19 #ifndef __EC_PARAMS_SECP521R1_H__ 20 #define __EC_PARAMS_SECP521R1_H__ 21 #include "ec_params_external.h" 22 23 static const u8 secp521r1_p[] = { 24 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 25 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 26 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 27 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 28 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 29 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 30 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 31 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 32 0xFF, 0xFF 33 }; 34 35 TO_EC_STR_PARAM(secp521r1_p); 36 37 #define CURVE_SECP521R1_P_BITLEN 521 38 static const u8 secp521r1_p_bitlen[] = { 0x02, 0x09 }; 39 40 TO_EC_STR_PARAM(secp521r1_p_bitlen); 41 42 /* 43 * Note: our multiprecision Montgomery mutiplication algorithm 44 * fp_mul_redc1() expects R and R^2 used for prior redcification 45 * to be power of B, the base in which we currently work, i.e. 46 * the defined number of bits for our words. For primes which 47 * have a common bitsize such as 256 and 512, which are a multiple 48 * of 64, 32 and 16, the value of r and r^2 are alway same, no 49 * matter the value of WORD_BYTES (i.e. no matter the base we 50 * currently use). But for secp521r1, p being 521 bit long, r is 51 * 2^576 mod p for 64 bits words, 2^544 mod p for 32 bits words 52 * and 528 for 16 bit words. Hence the following specific 53 * definitions for r and r^2 depending on words bitsize. 54 */ 55 #if (WORD_BYTES == 8) /* 64-bit words */ 56 static const u8 secp521r1_r[] = { 57 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 58 }; 59 60 static const u8 secp521r1_r_square[] = { 61 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 63 }; 64 #elif (WORD_BYTES == 4) /* 32-bit words */ 65 static const u8 secp521r1_r[] = { 0x80, 0x00, 0x00 }; 66 67 static const u8 secp521r1_r_square[] = { 68 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00 69 }; 70 #elif (WORD_BYTES == 2) /* 16-bit words */ 71 static const u8 secp521r1_r[] = { 0x80 }; 72 static const u8 secp521r1_r_square[] = { 0x40, 0x00 }; 73 #else /* unknown word size */ 74 #error "Unsupported word size" 75 #endif 76 TO_EC_STR_PARAM(secp521r1_r); 77 TO_EC_STR_PARAM(secp521r1_r_square); 78 79 static const u8 secp521r1_mpinv[] = { 0x01 }; 80 81 TO_EC_STR_PARAM(secp521r1_mpinv); 82 83 #if (WORD_BYTES == 8) 84 static const u8 secp521r1_p_shift[] = { 85 0x37 86 }; 87 88 static const u8 secp521r1_p_normalized[] = { 89 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 90 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 91 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 92 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 93 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 94 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 95 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 96 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 97 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 98 }; 99 #elif (WORD_BYTES == 4) 100 static const u8 secp521r1_p_shift[] = { 101 0x17 102 }; 103 104 static const u8 secp521r1_p_normalized[] = { 105 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 106 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 107 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 109 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 110 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 111 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 112 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 113 0xFF, 0x80, 0x00, 0x00 114 }; 115 #elif (WORD_BYTES == 2) 116 static const u8 secp521r1_p_shift[] = { 117 0x7 118 }; 119 120 static const u8 secp521r1_p_normalized[] = { 121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 122 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 123 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 124 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 125 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 126 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 127 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 128 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 129 0xFF, 0x80 130 }; 131 #else 132 #error "Unsupported word size" 133 #endif 134 TO_EC_STR_PARAM(secp521r1_p_shift); 135 TO_EC_STR_PARAM(secp521r1_p_normalized); 136 137 static const u8 secp521r1_p_reciprocal[] = { 138 0x00 139 }; 140 141 TO_EC_STR_PARAM(secp521r1_p_reciprocal); 142 143 static const u8 secp521r1_a[] = { 144 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 145 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 146 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 147 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 148 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 149 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 150 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 151 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 152 0xFF, 0xFC 153 }; 154 155 TO_EC_STR_PARAM(secp521r1_a); 156 157 static const u8 secp521r1_b[] = { 158 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 159 0x9A, 0x1F, 0x92, 0x9A, 0x21, 0xA0, 0xB6, 0x85, 160 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 161 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 162 0x09, 0xE1, 0x56, 0x19, 0x39, 0x51, 0xEC, 0x7E, 163 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 164 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 165 0x34, 0xF1, 0xEF, 0x45, 0x1F, 0xD4, 0x6B, 0x50, 166 0x3F, 0x00 167 }; 168 169 TO_EC_STR_PARAM(secp521r1_b); 170 171 #define CURVE_SECP521R1_CURVE_ORDER_BITLEN 521 172 static const u8 secp521r1_curve_order[] = { 173 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 174 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 175 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 176 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 177 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 178 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 179 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 180 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 181 0x64, 0x09 182 }; 183 184 TO_EC_STR_PARAM(secp521r1_curve_order); 185 186 static const u8 secp521r1_gx[] = { 187 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 188 0xE9, 0xCD, 0x9E, 0x3E, 0xCB, 0x66, 0x23, 0x95, 189 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 190 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 191 0x3D, 0xBA, 0xA1, 0x4B, 0x5E, 0x77, 0xEF, 0xE7, 192 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 193 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 194 0x42, 0x9B, 0xF9, 0x7E, 0x7E, 0x31, 0xC2, 0xE5, 195 0xBD, 0x66, 196 }; 197 198 TO_EC_STR_PARAM(secp521r1_gx); 199 200 static const u8 secp521r1_gy[] = { 201 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 202 0xC0, 0x04, 0x5C, 0x8A, 0x5F, 0xB4, 0x2C, 0x7D, 203 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, 204 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 205 0x66, 0x2C, 0x97, 0xEE, 0x72, 0x99, 0x5E, 0xF4, 206 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, 207 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 208 0xC2, 0x40, 0x88, 0xBE, 0x94, 0x76, 0x9F, 0xD1, 209 0x66, 0x50 210 }; 211 212 TO_EC_STR_PARAM(secp521r1_gy); 213 214 static const u8 secp521r1_gz[] = { 215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 223 0x00, 0x01 224 }; 225 226 TO_EC_STR_PARAM(secp521r1_gz); 227 228 static const u8 secp521r1_gen_order[] = { 229 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 230 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 231 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 232 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 233 0xFF, 0xFA, 0x51, 0x86, 0x87, 0x83, 0xBF, 0x2F, 234 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 235 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 236 0x47, 0xAE, 0xBB, 0x6F, 0xB7, 0x1E, 0x91, 0x38, 237 0x64, 0x09 238 }; 239 240 TO_EC_STR_PARAM(secp521r1_gen_order); 241 242 #define CURVE_SECP521R1_Q_BITLEN 521 243 static const u8 secp521r1_gen_order_bitlen[] = { 0x02, 0x09 }; 244 245 TO_EC_STR_PARAM(secp521r1_gen_order_bitlen); 246 247 static const u8 secp521r1_cofactor[] = { 0x01 }; 248 249 TO_EC_STR_PARAM(secp521r1_cofactor); 250 251 static const u8 secp521r1_alpha_montgomery[] = { 252 0x00, 253 }; 254 255 TO_EC_STR_PARAM_FIXED_SIZE(secp521r1_alpha_montgomery, 0); 256 257 static const u8 secp521r1_gamma_montgomery[] = { 258 0x00, 259 }; 260 261 TO_EC_STR_PARAM_FIXED_SIZE(secp521r1_gamma_montgomery, 0); 262 263 static const u8 secp521r1_alpha_edwards[] = { 264 0x00, 265 }; 266 267 TO_EC_STR_PARAM_FIXED_SIZE(secp521r1_alpha_edwards, 0); 268 269 static const u8 secp521r1_oid[] = "1.3.132.0.35"; 270 TO_EC_STR_PARAM(secp521r1_oid); 271 272 static const u8 secp521r1_name[] = "SECP521R1"; 273 TO_EC_STR_PARAM(secp521r1_name); 274 275 static const ec_str_params secp521r1_str_params = { 276 .p = &secp521r1_p_str_param, 277 .p_bitlen = &secp521r1_p_bitlen_str_param, 278 .r = &secp521r1_r_str_param, 279 .r_square = &secp521r1_r_square_str_param, 280 .mpinv = &secp521r1_mpinv_str_param, 281 .p_shift = &secp521r1_p_shift_str_param, 282 .p_normalized = &secp521r1_p_normalized_str_param, 283 .p_reciprocal = &secp521r1_p_reciprocal_str_param, 284 .a = &secp521r1_a_str_param, 285 .b = &secp521r1_b_str_param, 286 .curve_order = &secp521r1_curve_order_str_param, 287 .gx = &secp521r1_gx_str_param, 288 .gy = &secp521r1_gy_str_param, 289 .gz = &secp521r1_gz_str_param, 290 .gen_order = &secp521r1_gen_order_str_param, 291 .gen_order_bitlen = &secp521r1_gen_order_bitlen_str_param, 292 .cofactor = &secp521r1_cofactor_str_param, 293 .alpha_montgomery = &secp521r1_alpha_montgomery_str_param, 294 .gamma_montgomery = &secp521r1_gamma_montgomery_str_param, 295 .alpha_edwards = &secp521r1_alpha_edwards_str_param, 296 .oid = &secp521r1_oid_str_param, 297 .name = &secp521r1_name_str_param, 298 }; 299 300 /* 301 * Compute max bit length of all curves for p and q 302 */ 303 #ifndef CURVES_MAX_P_BIT_LEN 304 #define CURVES_MAX_P_BIT_LEN 0 305 #endif 306 #if (CURVES_MAX_P_BIT_LEN < CURVE_SECP521R1_P_BITLEN) 307 #undef CURVES_MAX_P_BIT_LEN 308 #define CURVES_MAX_P_BIT_LEN CURVE_SECP521R1_P_BITLEN 309 #endif 310 #ifndef CURVES_MAX_Q_BIT_LEN 311 #define CURVES_MAX_Q_BIT_LEN 0 312 #endif 313 #if (CURVES_MAX_Q_BIT_LEN < CURVE_SECP521R1_Q_BITLEN) 314 #undef CURVES_MAX_Q_BIT_LEN 315 #define CURVES_MAX_Q_BIT_LEN CURVE_SECP521R1_Q_BITLEN 316 #endif 317 #ifndef CURVES_MAX_CURVE_ORDER_BIT_LEN 318 #define CURVES_MAX_CURVE_ORDER_BIT_LEN 0 319 #endif 320 #if (CURVES_MAX_CURVE_ORDER_BIT_LEN < CURVE_SECP521R1_CURVE_ORDER_BITLEN) 321 #undef CURVES_MAX_CURVE_ORDER_BIT_LEN 322 #define CURVES_MAX_CURVE_ORDER_BIT_LEN CURVE_SECP521R1_CURVE_ORDER_BITLEN 323 #endif 324 325 #endif /* __EC_PARAMS_SECP521R1_H__ */ 326 327 #endif /* WITH_CURVE_SECP521R1 */ 328