25 const size_t p_full_words = 521 / BOTAN_MP_WORD_BITS;
26 const size_t p_top_bits = 521 % BOTAN_MP_WORD_BITS;
27 const size_t p_words = p_full_words + 1;
29#if (BOTAN_MP_WORD_BITS == 64)
30 static const word p521_words[p_words] = {
31 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
32 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
35 static const word p521_words[p_words] = {
36 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
37 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
38 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
39 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
43 if(ws.size() < p_words + 1)
56 const word top_word = x.
word_at(p_full_words);
67 for(
size_t i = 0; i != p_full_words; ++i)
71 const auto is_p521 = all_512_low_bits_set & has_p521_top_word;
73 const auto needs_reduction = is_p521 | bit_522_set;
115 static const size_t p192_limbs = 192 / BOTAN_MP_WORD_BITS;
120 const uint64_t X00 = get_uint32(xw, 0);
121 const uint64_t X01 = get_uint32(xw, 1);
122 const uint64_t X02 = get_uint32(xw, 2);
123 const uint64_t X03 = get_uint32(xw, 3);
124 const uint64_t X04 = get_uint32(xw, 4);
125 const uint64_t X05 = get_uint32(xw, 5);
126 const uint64_t X06 = get_uint32(xw, 6);
127 const uint64_t X07 = get_uint32(xw, 7);
128 const uint64_t X08 = get_uint32(xw, 8);
129 const uint64_t X09 = get_uint32(xw, 9);
130 const uint64_t X10 = get_uint32(xw, 10);
131 const uint64_t X11 = get_uint32(xw, 11);
133 const uint64_t S0 = X00 + X06 + X10;
134 const uint64_t S1 = X01 + X07 + X11;
135 const uint64_t S2 = X02 + X06 + X08 + X10;
136 const uint64_t S3 = X03 + X07 + X09 + X11;
137 const uint64_t S4 = X04 + X08 + X10;
138 const uint64_t S5 = X05 + X09 + X11;
141 uint32_t R0 = 0, R1 = 0;
144 R0 =
static_cast<uint32_t
>(S);
148 R1 =
static_cast<uint32_t
>(S);
151 set_words(xw, 0, R0, R1);
154 R0 =
static_cast<uint32_t
>(S);
158 R1 =
static_cast<uint32_t
>(S);
161 set_words(xw, 2, R0, R1);
164 R0 =
static_cast<uint32_t
>(S);
168 R1 =
static_cast<uint32_t
>(S);
171 set_words(xw, 4, R0, R1);
178 static const word p192_mults[3][p192_limbs] = {
179#if (BOTAN_MP_WORD_BITS == 64)
180 {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF},
181 {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF},
182 {0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF},
184 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
185 {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
186 {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
208 static const size_t p224_limbs = (BOTAN_MP_WORD_BITS == 32) ? 7 : 4;
215 const int64_t X00 = get_uint32(xw, 0);
216 const int64_t X01 = get_uint32(xw, 1);
217 const int64_t X02 = get_uint32(xw, 2);
218 const int64_t X03 = get_uint32(xw, 3);
219 const int64_t X04 = get_uint32(xw, 4);
220 const int64_t X05 = get_uint32(xw, 5);
221 const int64_t X06 = get_uint32(xw, 6);
222 const int64_t X07 = get_uint32(xw, 7);
223 const int64_t X08 = get_uint32(xw, 8);
224 const int64_t X09 = get_uint32(xw, 9);
225 const int64_t X10 = get_uint32(xw, 10);
226 const int64_t X11 = get_uint32(xw, 11);
227 const int64_t X12 = get_uint32(xw, 12);
228 const int64_t X13 = get_uint32(xw, 13);
232 const int64_t S0 = 0x00000001 + X00 - X07 - X11;
233 const int64_t S1 = 0x00000000 + X01 - X08 - X12;
234 const int64_t S2 = 0x00000000 + X02 - X09 - X13;
235 const int64_t S3 = 0xFFFFFFFF + X03 + X07 + X11 - X10;
236 const int64_t S4 = 0xFFFFFFFF + X04 + X08 + X12 - X11;
237 const int64_t S5 = 0xFFFFFFFF + X05 + X09 + X13 - X12;
238 const int64_t S6 = 0xFFFFFFFF + X06 + X10 - X13;
241 uint32_t R0 = 0, R1 = 0;
244 R0 =
static_cast<uint32_t
>(S);
248 R1 =
static_cast<uint32_t
>(S);
251 set_words(xw, 0, R0, R1);
254 R0 =
static_cast<uint32_t
>(S);
258 R1 =
static_cast<uint32_t
>(S);
261 set_words(xw, 2, R0, R1);
264 R0 =
static_cast<uint32_t
>(S);
268 R1 =
static_cast<uint32_t
>(S);
271 set_words(xw, 4, R0, R1);
274 R0 =
static_cast<uint32_t
>(S);
277 set_words(xw, 6, R0, 0);
279 static const word p224_mults[3][p224_limbs] = {
280#if (BOTAN_MP_WORD_BITS == 64)
281 {0x0000000000000001, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF},
282 {0x0000000000000002, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF},
283 {0x0000000000000003, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF},
285 {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
286 {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
287 {0x00000003, 0x00000000, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
310 static const size_t p256_limbs = (BOTAN_MP_WORD_BITS == 32) ? 8 : 4;
317 const int64_t X00 = get_uint32(xw, 0);
318 const int64_t X01 = get_uint32(xw, 1);
319 const int64_t X02 = get_uint32(xw, 2);
320 const int64_t X03 = get_uint32(xw, 3);
321 const int64_t X04 = get_uint32(xw, 4);
322 const int64_t X05 = get_uint32(xw, 5);
323 const int64_t X06 = get_uint32(xw, 6);
324 const int64_t X07 = get_uint32(xw, 7);
325 const int64_t X08 = get_uint32(xw, 8);
326 const int64_t X09 = get_uint32(xw, 9);
327 const int64_t X10 = get_uint32(xw, 10);
328 const int64_t X11 = get_uint32(xw, 11);
329 const int64_t X12 = get_uint32(xw, 12);
330 const int64_t X13 = get_uint32(xw, 13);
331 const int64_t X14 = get_uint32(xw, 14);
332 const int64_t X15 = get_uint32(xw, 15);
335 const int64_t S0 = 0xFFFFFFFA + X00 + X08 + X09 - (X11 + X12 + X13) - X14;
336 const int64_t S1 = 0xFFFFFFFF + X01 + X09 + X10 - X12 - (X13 + X14 + X15);
337 const int64_t S2 = 0xFFFFFFFF + X02 + X10 + X11 - (X13 + X14 + X15);
338 const int64_t S3 = 0x00000005 + X03 + (X11 + X12)*2 + X13 - X15 - X08 - X09;
339 const int64_t S4 = 0x00000000 + X04 + (X12 + X13)*2 + X14 - X09 - X10;
340 const int64_t S5 = 0x00000000 + X05 + (X13 + X14)*2 + X15 - X10 - X11;
341 const int64_t S6 = 0x00000006 + X06 + X13 + X14*3 + X15*2 - X08 - X09;
342 const int64_t S7 = 0xFFFFFFFA + X07 + X15*3 + X08 - X10 - (X11 + X12 + X13);
346 uint32_t R0 = 0, R1 = 0;
349 R0 =
static_cast<uint32_t
>(S);
353 R1 =
static_cast<uint32_t
>(S);
356 set_words(xw, 0, R0, R1);
359 R0 =
static_cast<uint32_t
>(S);
363 R1 =
static_cast<uint32_t
>(S);
366 set_words(xw, 2, R0, R1);
369 R0 =
static_cast<uint32_t
>(S);
373 R1 =
static_cast<uint32_t
>(S);
376 set_words(xw, 4, R0, R1);
379 R0 =
static_cast<uint32_t
>(S);
383 R1 =
static_cast<uint32_t
>(S);
385 set_words(xw, 6, R0, R1);
392 static const word p256_mults[11][p256_limbs] = {
393#if (BOTAN_MP_WORD_BITS == 64)
394 {0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001},
395 {0xFFFFFFFFFFFFFFFE, 0x00000001FFFFFFFF, 0x0000000000000000, 0xFFFFFFFE00000002},
396 {0xFFFFFFFFFFFFFFFD, 0x00000002FFFFFFFF, 0x0000000000000000, 0xFFFFFFFD00000003},
397 {0xFFFFFFFFFFFFFFFC, 0x00000003FFFFFFFF, 0x0000000000000000, 0xFFFFFFFC00000004},
398 {0xFFFFFFFFFFFFFFFB, 0x00000004FFFFFFFF, 0x0000000000000000, 0xFFFFFFFB00000005},
399 {0xFFFFFFFFFFFFFFFA, 0x00000005FFFFFFFF, 0x0000000000000000, 0xFFFFFFFA00000006},
400 {0xFFFFFFFFFFFFFFF9, 0x00000006FFFFFFFF, 0x0000000000000000, 0xFFFFFFF900000007},
401 {0xFFFFFFFFFFFFFFF8, 0x00000007FFFFFFFF, 0x0000000000000000, 0xFFFFFFF800000008},
402 {0xFFFFFFFFFFFFFFF7, 0x00000008FFFFFFFF, 0x0000000000000000, 0xFFFFFFF700000009},
403 {0xFFFFFFFFFFFFFFF6, 0x00000009FFFFFFFF, 0x0000000000000000, 0xFFFFFFF60000000A},
404 {0xFFFFFFFFFFFFFFF5, 0x0000000AFFFFFFFF, 0x0000000000000000, 0xFFFFFFF50000000B},
406 {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
407 {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
408 {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
409 {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
410 {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
411 {0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000005, 0x00000000, 0x00000000, 0x00000006, 0xFFFFFFFA},
412 {0xFFFFFFF9, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0xFFFFFFF9},
413 {0xFFFFFFF8, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000, 0x00000000, 0x00000008, 0xFFFFFFF8},
414 {0xFFFFFFF7, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000008, 0x00000000, 0x00000000, 0x00000009, 0xFFFFFFF7},
415 {0xFFFFFFF6, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000009, 0x00000000, 0x00000000, 0x0000000A, 0xFFFFFFF6},
416 {0xFFFFFFF5, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000A, 0x00000000, 0x00000000, 0x0000000B, 0xFFFFFFF5},
440 static const size_t p384_limbs = (BOTAN_MP_WORD_BITS == 32) ? 12 : 6;
445 const int64_t X00 = get_uint32(xw, 0);
446 const int64_t X01 = get_uint32(xw, 1);
447 const int64_t X02 = get_uint32(xw, 2);
448 const int64_t X03 = get_uint32(xw, 3);
449 const int64_t X04 = get_uint32(xw, 4);
450 const int64_t X05 = get_uint32(xw, 5);
451 const int64_t X06 = get_uint32(xw, 6);
452 const int64_t X07 = get_uint32(xw, 7);
453 const int64_t X08 = get_uint32(xw, 8);
454 const int64_t X09 = get_uint32(xw, 9);
455 const int64_t X10 = get_uint32(xw, 10);
456 const int64_t X11 = get_uint32(xw, 11);
457 const int64_t X12 = get_uint32(xw, 12);
458 const int64_t X13 = get_uint32(xw, 13);
459 const int64_t X14 = get_uint32(xw, 14);
460 const int64_t X15 = get_uint32(xw, 15);
461 const int64_t X16 = get_uint32(xw, 16);
462 const int64_t X17 = get_uint32(xw, 17);
463 const int64_t X18 = get_uint32(xw, 18);
464 const int64_t X19 = get_uint32(xw, 19);
465 const int64_t X20 = get_uint32(xw, 20);
466 const int64_t X21 = get_uint32(xw, 21);
467 const int64_t X22 = get_uint32(xw, 22);
468 const int64_t X23 = get_uint32(xw, 23);
471 const int64_t S0 = 0xFFFFFFFF + X00 + X12 + X20 + X21 - X23;
472 const int64_t S1 = 0x00000000 + X01 + X13 + X22 + X23 - X12 - X20;
473 const int64_t S2 = 0x00000000 + X02 + X14 + X23 - X13 - X21;
474 const int64_t S3 = 0xFFFFFFFF + X03 + X12 + X15 + X20 + X21 - X14 - X22 - X23;
475 const int64_t S4 = 0xFFFFFFFE + X04 + X12 + X13 + X16 + X20 + X21*2 + X22 - X15 - X23*2;
476 const int64_t S5 = 0xFFFFFFFF + X05 + X13 + X14 + X17 + X21 + X22*2 + X23 - X16;
477 const int64_t S6 = 0xFFFFFFFF + X06 + X14 + X15 + X18 + X22 + X23*2 - X17;
478 const int64_t S7 = 0xFFFFFFFF + X07 + X15 + X16 + X19 + X23 - X18;
479 const int64_t S8 = 0xFFFFFFFF + X08 + X16 + X17 + X20 - X19;
480 const int64_t S9 = 0xFFFFFFFF + X09 + X17 + X18 + X21 - X20;
481 const int64_t SA = 0xFFFFFFFF + X10 + X18 + X19 + X22 - X21;
482 const int64_t SB = 0xFFFFFFFF + X11 + X19 + X20 + X23 - X22;
486 uint32_t R0 = 0, R1 = 0;
489 R0 =
static_cast<uint32_t
>(S);
493 R1 =
static_cast<uint32_t
>(S);
496 set_words(xw, 0, R0, R1);
499 R0 =
static_cast<uint32_t
>(S);
503 R1 =
static_cast<uint32_t
>(S);
506 set_words(xw, 2, R0, R1);
509 R0 =
static_cast<uint32_t
>(S);
513 R1 =
static_cast<uint32_t
>(S);
516 set_words(xw, 4, R0, R1);
519 R0 =
static_cast<uint32_t
>(S);
523 R1 =
static_cast<uint32_t
>(S);
526 set_words(xw, 6, R0, R1);
529 R0 =
static_cast<uint32_t
>(S);
533 R1 =
static_cast<uint32_t
>(S);
536 set_words(xw, 8, R0, R1);
539 R0 =
static_cast<uint32_t
>(S);
543 R1 =
static_cast<uint32_t
>(S);
546 set_words(xw, 10, R0, R1);
551 static const word p384_mults[5][p384_limbs] = {
552#if (BOTAN_MP_WORD_BITS == 64)
553 {0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
554 {0x00000001FFFFFFFE, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
555 {0x00000002FFFFFFFD, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
556 {0x00000003FFFFFFFC, 0xFFFFFFFC00000000, 0xFFFFFFFFFFFFFFFB, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
557 {0x00000004FFFFFFFB, 0xFFFFFFFB00000000, 0xFFFFFFFFFFFFFFFA, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
560 {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
561 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
562 {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
563 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
564 {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF,
565 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
566 {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF,
567 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
568 {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF,
569 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},