Coverage Report

Created: 2020-03-26 13:53

/src/botan/src/lib/math/numbertheory/nistp_redc.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* NIST prime reductions
3
* (C) 2014,2015,2018 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/curve_nistp.h>
9
#include <botan/internal/mp_core.h>
10
#include <botan/internal/mp_asmi.h>
11
#include <botan/internal/ct_utils.h>
12
13
namespace Botan {
14
15
const BigInt& prime_p521()
16
10.2M
   {
17
10.2M
   static const BigInt p521("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
18
10.2M
                               "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
19
10.2M
20
10.2M
   return p521;
21
10.2M
   }
22
23
void redc_p521(BigInt& x, secure_vector<word>& ws)
24
134M
   {
25
134M
   const size_t p_full_words = 521 / BOTAN_MP_WORD_BITS;
26
134M
   const size_t p_top_bits = 521 % BOTAN_MP_WORD_BITS;
27
134M
   const size_t p_words = p_full_words + 1;
28
134M
29
134M
#if (BOTAN_MP_WORD_BITS == 64)
30
134M
   static const word p521_words[p_words] = {
31
134M
      0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
32
134M
      0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
33
134M
      0x1FF };
34
#else
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,
40
      0x1FF };
41
#endif
42
43
134M
   if(ws.size() < p_words + 1)
44
181
      ws.resize(p_words + 1);
45
134M
46
134M
   clear_mem(ws.data(), ws.size());
47
134M
   bigint_shr2(ws.data(), x.data(), std::min(x.size(), 2*p_words), p_full_words, p_top_bits);
48
134M
49
134M
   x.mask_bits(521);
50
134M
   x.grow_to(p_words);
51
134M
52
134M
   // Word-level carry will be zero
53
134M
   word carry = bigint_add3_nc(x.mutable_data(), x.data(), p_words, ws.data(), p_words);
54
134M
   BOTAN_ASSERT_EQUAL(carry, 0, "Final carry in P-521 reduction");
55
134M
56
134M
   const word top_word = x.word_at(p_full_words);
57
134M
58
134M
   /*
59
134M
   * Check if we need to reduce modulo P
60
134M
   * There are two possible cases:
61
134M
   * - The result overflowed past 521 bits, in which case bit 522 will be set
62
134M
   * - The result is exactly 2**521 - 1
63
134M
   */
64
134M
   const auto bit_522_set = CT::Mask<word>::expand(top_word >> p_top_bits);
65
134M
66
134M
   word and_512 = MP_WORD_MAX;
67
1.20G
   for(size_t i = 0; i != p_full_words; ++i)
68
1.07G
      and_512 &= x.word_at(i);
69
134M
   const auto all_512_low_bits_set = CT::Mask<word>::is_equal(and_512, MP_WORD_MAX);
70
134M
   const auto has_p521_top_word = CT::Mask<word>::is_equal(top_word, 0x1FF);
71
134M
   const auto is_p521 = all_512_low_bits_set & has_p521_top_word;
72
134M
73
134M
   const auto needs_reduction = is_p521 | bit_522_set;
74
134M
75
134M
   bigint_cnd_sub(needs_reduction.value(), x.mutable_data(), p521_words, p_words);
76
134M
   }
77
78
namespace {
79
80
/**
81
* Treating this MPI as a sequence of 32-bit words in big-endian
82
* order, return word i. The array is assumed to be large enough.
83
*/
84
inline uint32_t get_uint32(const word xw[], size_t i)
85
2.07G
   {
86
#if (BOTAN_MP_WORD_BITS == 32)
87
   return xw[i];
88
#else
89
   return static_cast<uint32_t>(xw[i/2] >> ((i % 2)*32));
90
2.07G
#endif
91
2.07G
   }
92
93
inline void set_words(word x[], size_t i, uint32_t R0, uint32_t R1)
94
520M
   {
95
#if (BOTAN_MP_WORD_BITS == 32)
96
   x[i] = R0;
97
   x[i+1] = R1;
98
#else
99
   x[i/2] = (static_cast<uint64_t>(R1) << 32) | R0;
100
520M
#endif
101
520M
   }
102
103
}
104
105
const BigInt& prime_p192()
106
27.5k
   {
107
27.5k
   static const BigInt p192("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF");
108
27.5k
   return p192;
109
27.5k
   }
110
111
void redc_p192(BigInt& x, secure_vector<word>& ws)
112
445k
   {
113
445k
   BOTAN_UNUSED(ws);
114
445k
115
445k
   static const size_t p192_limbs = 192 / BOTAN_MP_WORD_BITS;
116
445k
117
445k
   x.grow_to(2*p192_limbs);
118
445k
   word* xw = x.mutable_data();
119
445k
120
445k
   const uint64_t X00 = get_uint32(xw,  0);
121
445k
   const uint64_t X01 = get_uint32(xw,  1);
122
445k
   const uint64_t X02 = get_uint32(xw,  2);
123
445k
   const uint64_t X03 = get_uint32(xw,  3);
124
445k
   const uint64_t X04 = get_uint32(xw,  4);
125
445k
   const uint64_t X05 = get_uint32(xw,  5);
126
445k
   const uint64_t X06 = get_uint32(xw,  6);
127
445k
   const uint64_t X07 = get_uint32(xw,  7);
128
445k
   const uint64_t X08 = get_uint32(xw,  8);
129
445k
   const uint64_t X09 = get_uint32(xw,  9);
130
445k
   const uint64_t X10 = get_uint32(xw, 10);
131
445k
   const uint64_t X11 = get_uint32(xw, 11);
132
445k
133
445k
   const uint64_t S0 = X00 + X06 + X10;
134
445k
   const uint64_t S1 = X01 + X07 + X11;
135
445k
   const uint64_t S2 = X02 + X06 + X08 + X10;
136
445k
   const uint64_t S3 = X03 + X07 + X09 + X11;
137
445k
   const uint64_t S4 = X04 + X08 + X10;
138
445k
   const uint64_t S5 = X05 + X09 + X11;
139
445k
140
445k
   uint64_t S = 0;
141
445k
   uint32_t R0 = 0, R1 = 0;
142
445k
143
445k
   S += S0;
144
445k
   R0 = static_cast<uint32_t>(S);
145
445k
   S >>= 32;
146
445k
147
445k
   S += S1;
148
445k
   R1 = static_cast<uint32_t>(S);
149
445k
   S >>= 32;
150
445k
151
445k
   set_words(xw, 0, R0, R1);
152
445k
153
445k
   S += S2;
154
445k
   R0 = static_cast<uint32_t>(S);
155
445k
   S >>= 32;
156
445k
157
445k
   S += S3;
158
445k
   R1 = static_cast<uint32_t>(S);
159
445k
   S >>= 32;
160
445k
161
445k
   set_words(xw, 2, R0, R1);
162
445k
163
445k
   S += S4;
164
445k
   R0 = static_cast<uint32_t>(S);
165
445k
   S >>= 32;
166
445k
167
445k
   S += S5;
168
445k
   R1 = static_cast<uint32_t>(S);
169
445k
   S >>= 32;
170
445k
171
445k
   set_words(xw, 4, R0, R1);
172
445k
173
445k
   // No underflow possible
174
445k
175
445k
   /*
176
445k
   This is a table of (i*P-192) % 2**192 for i in 1...3
177
445k
   */
178
445k
   static const word p192_mults[3][p192_limbs] = {
179
445k
#if (BOTAN_MP_WORD_BITS == 64)
180
445k
      {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF},
181
445k
      {0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF},
182
445k
      {0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF},
183
#else
184
      {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
185
      {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
186
      {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
187
#endif
188
   };
189
445k
190
445k
   CT::unpoison(S);
191
445k
   BOTAN_ASSERT(S <= 2, "Expected overflow");
192
445k
193
445k
   BOTAN_ASSERT_NOMSG(x.size() >= p192_limbs + 1);
194
445k
   x.mask_bits(192);
195
445k
   word borrow = bigint_sub2(x.mutable_data(), p192_limbs + 1, p192_mults[S], p192_limbs);
196
445k
   BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1);
197
445k
   bigint_cnd_add(borrow, x.mutable_data(), p192_limbs + 1, p192_mults[0], p192_limbs);
198
445k
   }
199
200
const BigInt& prime_p224()
201
292k
   {
202
292k
   static const BigInt p224("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001");
203
292k
   return p224;
204
292k
   }
205
206
void redc_p224(BigInt& x, secure_vector<word>& ws)
207
4.94M
   {
208
4.94M
   static const size_t p224_limbs = (BOTAN_MP_WORD_BITS == 32) ? 7 : 4;
209
4.94M
210
4.94M
   BOTAN_UNUSED(ws);
211
4.94M
212
4.94M
   x.grow_to(2*p224_limbs);
213
4.94M
   word* xw = x.mutable_data();
214
4.94M
215
4.94M
   const int64_t X00 = get_uint32(xw,  0);
216
4.94M
   const int64_t X01 = get_uint32(xw,  1);
217
4.94M
   const int64_t X02 = get_uint32(xw,  2);
218
4.94M
   const int64_t X03 = get_uint32(xw,  3);
219
4.94M
   const int64_t X04 = get_uint32(xw,  4);
220
4.94M
   const int64_t X05 = get_uint32(xw,  5);
221
4.94M
   const int64_t X06 = get_uint32(xw,  6);
222
4.94M
   const int64_t X07 = get_uint32(xw,  7);
223
4.94M
   const int64_t X08 = get_uint32(xw,  8);
224
4.94M
   const int64_t X09 = get_uint32(xw,  9);
225
4.94M
   const int64_t X10 = get_uint32(xw, 10);
226
4.94M
   const int64_t X11 = get_uint32(xw, 11);
227
4.94M
   const int64_t X12 = get_uint32(xw, 12);
228
4.94M
   const int64_t X13 = get_uint32(xw, 13);
229
4.94M
230
4.94M
   // One full copy of P224 is added, so the result is always positive
231
4.94M
232
4.94M
   const int64_t S0 = 0x00000001 + X00 - X07 - X11;
233
4.94M
   const int64_t S1 = 0x00000000 + X01 - X08 - X12;
234
4.94M
   const int64_t S2 = 0x00000000 + X02 - X09 - X13;
235
4.94M
   const int64_t S3 = 0xFFFFFFFF + X03 + X07 + X11 - X10;
236
4.94M
   const int64_t S4 = 0xFFFFFFFF + X04 + X08 + X12 - X11;
237
4.94M
   const int64_t S5 = 0xFFFFFFFF + X05 + X09 + X13 - X12;
238
4.94M
   const int64_t S6 = 0xFFFFFFFF + X06 + X10 - X13;
239
4.94M
240
4.94M
   int64_t S = 0;
241
4.94M
   uint32_t R0 = 0, R1 = 0;
242
4.94M
243
4.94M
   S += S0;
244
4.94M
   R0 = static_cast<uint32_t>(S);
245
4.94M
   S >>= 32;
246
4.94M
247
4.94M
   S += S1;
248
4.94M
   R1 = static_cast<uint32_t>(S);
249
4.94M
   S >>= 32;
250
4.94M
251
4.94M
   set_words(xw, 0, R0, R1);
252
4.94M
253
4.94M
   S += S2;
254
4.94M
   R0 = static_cast<uint32_t>(S);
255
4.94M
   S >>= 32;
256
4.94M
257
4.94M
   S += S3;
258
4.94M
   R1 = static_cast<uint32_t>(S);
259
4.94M
   S >>= 32;
260
4.94M
261
4.94M
   set_words(xw, 2, R0, R1);
262
4.94M
263
4.94M
   S += S4;
264
4.94M
   R0 = static_cast<uint32_t>(S);
265
4.94M
   S >>= 32;
266
4.94M
267
4.94M
   S += S5;
268
4.94M
   R1 = static_cast<uint32_t>(S);
269
4.94M
   S >>= 32;
270
4.94M
271
4.94M
   set_words(xw, 4, R0, R1);
272
4.94M
273
4.94M
   S += S6;
274
4.94M
   R0 = static_cast<uint32_t>(S);
275
4.94M
   S >>= 32;
276
4.94M
277
4.94M
   set_words(xw, 6, R0, 0);
278
4.94M
279
4.94M
   static const word p224_mults[3][p224_limbs] = {
280
4.94M
#if (BOTAN_MP_WORD_BITS == 64)
281
4.94M
    {0x0000000000000001, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF},
282
4.94M
    {0x0000000000000002, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF},
283
4.94M
    {0x0000000000000003, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF},
284
#else
285
    {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
286
    {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
287
    {0x00000003, 0x00000000, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
288
#endif
289
290
4.94M
   };
291
4.94M
292
4.94M
   CT::unpoison(S);
293
4.94M
   BOTAN_ASSERT(S >= 0 && S <= 2, "Expected overflow");
294
4.94M
295
4.94M
   BOTAN_ASSERT_NOMSG(x.size() >= p224_limbs + 1);
296
4.94M
   x.mask_bits(224);
297
4.94M
   word borrow = bigint_sub2(x.mutable_data(), p224_limbs + 1, p224_mults[S], p224_limbs);
298
4.94M
   BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1);
299
4.94M
   bigint_cnd_add(borrow, x.mutable_data(), p224_limbs + 1, p224_mults[0], p224_limbs);
300
4.94M
   }
301
302
const BigInt& prime_p256()
303
3.00M
   {
304
3.00M
   static const BigInt p256("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
305
3.00M
   return p256;
306
3.00M
   }
307
308
void redc_p256(BigInt& x, secure_vector<word>& ws)
309
38.6M
   {
310
38.6M
   static const size_t p256_limbs = (BOTAN_MP_WORD_BITS == 32) ? 8 : 4;
311
38.6M
312
38.6M
   BOTAN_UNUSED(ws);
313
38.6M
314
38.6M
   x.grow_to(2*p256_limbs);
315
38.6M
   word* xw = x.mutable_data();
316
38.6M
317
38.6M
   const int64_t X00 = get_uint32(xw,  0);
318
38.6M
   const int64_t X01 = get_uint32(xw,  1);
319
38.6M
   const int64_t X02 = get_uint32(xw,  2);
320
38.6M
   const int64_t X03 = get_uint32(xw,  3);
321
38.6M
   const int64_t X04 = get_uint32(xw,  4);
322
38.6M
   const int64_t X05 = get_uint32(xw,  5);
323
38.6M
   const int64_t X06 = get_uint32(xw,  6);
324
38.6M
   const int64_t X07 = get_uint32(xw,  7);
325
38.6M
   const int64_t X08 = get_uint32(xw,  8);
326
38.6M
   const int64_t X09 = get_uint32(xw,  9);
327
38.6M
   const int64_t X10 = get_uint32(xw, 10);
328
38.6M
   const int64_t X11 = get_uint32(xw, 11);
329
38.6M
   const int64_t X12 = get_uint32(xw, 12);
330
38.6M
   const int64_t X13 = get_uint32(xw, 13);
331
38.6M
   const int64_t X14 = get_uint32(xw, 14);
332
38.6M
   const int64_t X15 = get_uint32(xw, 15);
333
38.6M
334
38.6M
   // Adds 6 * P-256 to prevent underflow
335
38.6M
   const int64_t S0 = 0xFFFFFFFA + X00 + X08 + X09 - (X11 + X12 + X13) - X14;
336
38.6M
   const int64_t S1 = 0xFFFFFFFF + X01 + X09 + X10 - X12 - (X13 + X14 + X15);
337
38.6M
   const int64_t S2 = 0xFFFFFFFF + X02 + X10 + X11 - (X13 + X14 + X15);
338
38.6M
   const int64_t S3 = 0x00000005 + X03 + (X11 + X12)*2 + X13 - X15 - X08 - X09;
339
38.6M
   const int64_t S4 = 0x00000000 + X04 + (X12 + X13)*2 + X14 - X09 - X10;
340
38.6M
   const int64_t S5 = 0x00000000 + X05 + (X13 + X14)*2 + X15 - X10 - X11;
341
38.6M
   const int64_t S6 = 0x00000006 + X06 + X13 + X14*3 + X15*2 - X08 - X09;
342
38.6M
   const int64_t S7 = 0xFFFFFFFA + X07 + X15*3 + X08 - X10 - (X11 + X12 + X13);
343
38.6M
344
38.6M
   int64_t S = 0;
345
38.6M
346
38.6M
   uint32_t R0 = 0, R1 = 0;
347
38.6M
348
38.6M
   S += S0;
349
38.6M
   R0 = static_cast<uint32_t>(S);
350
38.6M
   S >>= 32;
351
38.6M
352
38.6M
   S += S1;
353
38.6M
   R1 = static_cast<uint32_t>(S);
354
38.6M
   S >>= 32;
355
38.6M
356
38.6M
   set_words(xw, 0, R0, R1);
357
38.6M
358
38.6M
   S += S2;
359
38.6M
   R0 = static_cast<uint32_t>(S);
360
38.6M
   S >>= 32;
361
38.6M
362
38.6M
   S += S3;
363
38.6M
   R1 = static_cast<uint32_t>(S);
364
38.6M
   S >>= 32;
365
38.6M
366
38.6M
   set_words(xw, 2, R0, R1);
367
38.6M
368
38.6M
   S += S4;
369
38.6M
   R0 = static_cast<uint32_t>(S);
370
38.6M
   S >>= 32;
371
38.6M
372
38.6M
   S += S5;
373
38.6M
   R1 = static_cast<uint32_t>(S);
374
38.6M
   S >>= 32;
375
38.6M
376
38.6M
   set_words(xw, 4, R0, R1);
377
38.6M
378
38.6M
   S += S6;
379
38.6M
   R0 = static_cast<uint32_t>(S);
380
38.6M
   S >>= 32;
381
38.6M
382
38.6M
   S += S7;
383
38.6M
   R1 = static_cast<uint32_t>(S);
384
38.6M
   S >>= 32;
385
38.6M
   set_words(xw, 6, R0, R1);
386
38.6M
387
38.6M
   S += 5; // the top digits of 6*P-256
388
38.6M
389
38.6M
   /*
390
38.6M
   This is a table of (i*P-256) % 2**256 for i in 1...10
391
38.6M
   */
392
38.6M
   static const word p256_mults[11][p256_limbs] = {
393
38.6M
#if (BOTAN_MP_WORD_BITS == 64)
394
38.6M
      {0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001},
395
38.6M
      {0xFFFFFFFFFFFFFFFE, 0x00000001FFFFFFFF, 0x0000000000000000, 0xFFFFFFFE00000002},
396
38.6M
      {0xFFFFFFFFFFFFFFFD, 0x00000002FFFFFFFF, 0x0000000000000000, 0xFFFFFFFD00000003},
397
38.6M
      {0xFFFFFFFFFFFFFFFC, 0x00000003FFFFFFFF, 0x0000000000000000, 0xFFFFFFFC00000004},
398
38.6M
      {0xFFFFFFFFFFFFFFFB, 0x00000004FFFFFFFF, 0x0000000000000000, 0xFFFFFFFB00000005},
399
38.6M
      {0xFFFFFFFFFFFFFFFA, 0x00000005FFFFFFFF, 0x0000000000000000, 0xFFFFFFFA00000006},
400
38.6M
      {0xFFFFFFFFFFFFFFF9, 0x00000006FFFFFFFF, 0x0000000000000000, 0xFFFFFFF900000007},
401
38.6M
      {0xFFFFFFFFFFFFFFF8, 0x00000007FFFFFFFF, 0x0000000000000000, 0xFFFFFFF800000008},
402
38.6M
      {0xFFFFFFFFFFFFFFF7, 0x00000008FFFFFFFF, 0x0000000000000000, 0xFFFFFFF700000009},
403
38.6M
      {0xFFFFFFFFFFFFFFF6, 0x00000009FFFFFFFF, 0x0000000000000000, 0xFFFFFFF60000000A},
404
38.6M
      {0xFFFFFFFFFFFFFFF5, 0x0000000AFFFFFFFF, 0x0000000000000000, 0xFFFFFFF50000000B},
405
#else
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},
417
#endif
418
   };
419
38.6M
420
38.6M
   CT::unpoison(S);
421
38.6M
   BOTAN_ASSERT(S >= 0 && S <= 10, "Expected overflow");
422
38.6M
423
38.6M
   BOTAN_ASSERT_NOMSG(x.size() >= p256_limbs + 1);
424
38.6M
   x.mask_bits(256);
425
38.6M
   word borrow = bigint_sub2(x.mutable_data(), p256_limbs + 1, p256_mults[S], p256_limbs);
426
38.6M
   BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1);
427
38.6M
   bigint_cnd_add(borrow, x.mutable_data(), p256_limbs + 1, p256_mults[0], p256_limbs);
428
38.6M
   }
429
430
const BigInt& prime_p384()
431
4.42M
   {
432
4.42M
   static const BigInt p384("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF");
433
4.42M
   return p384;
434
4.42M
   }
435
436
void redc_p384(BigInt& x, secure_vector<word>& ws)
437
57.4M
   {
438
57.4M
   BOTAN_UNUSED(ws);
439
57.4M
440
57.4M
   static const size_t p384_limbs = (BOTAN_MP_WORD_BITS == 32) ? 12 : 6;
441
57.4M
442
57.4M
   x.grow_to(2*p384_limbs);
443
57.4M
   word* xw = x.mutable_data();
444
57.4M
445
57.4M
   const int64_t X00 = get_uint32(xw,  0);
446
57.4M
   const int64_t X01 = get_uint32(xw,  1);
447
57.4M
   const int64_t X02 = get_uint32(xw,  2);
448
57.4M
   const int64_t X03 = get_uint32(xw,  3);
449
57.4M
   const int64_t X04 = get_uint32(xw,  4);
450
57.4M
   const int64_t X05 = get_uint32(xw,  5);
451
57.4M
   const int64_t X06 = get_uint32(xw,  6);
452
57.4M
   const int64_t X07 = get_uint32(xw,  7);
453
57.4M
   const int64_t X08 = get_uint32(xw,  8);
454
57.4M
   const int64_t X09 = get_uint32(xw,  9);
455
57.4M
   const int64_t X10 = get_uint32(xw, 10);
456
57.4M
   const int64_t X11 = get_uint32(xw, 11);
457
57.4M
   const int64_t X12 = get_uint32(xw, 12);
458
57.4M
   const int64_t X13 = get_uint32(xw, 13);
459
57.4M
   const int64_t X14 = get_uint32(xw, 14);
460
57.4M
   const int64_t X15 = get_uint32(xw, 15);
461
57.4M
   const int64_t X16 = get_uint32(xw, 16);
462
57.4M
   const int64_t X17 = get_uint32(xw, 17);
463
57.4M
   const int64_t X18 = get_uint32(xw, 18);
464
57.4M
   const int64_t X19 = get_uint32(xw, 19);
465
57.4M
   const int64_t X20 = get_uint32(xw, 20);
466
57.4M
   const int64_t X21 = get_uint32(xw, 21);
467
57.4M
   const int64_t X22 = get_uint32(xw, 22);
468
57.4M
   const int64_t X23 = get_uint32(xw, 23);
469
57.4M
470
57.4M
   // One copy of P-384 is added to prevent underflow
471
57.4M
   const int64_t S0 = 0xFFFFFFFF + X00 + X12 + X20 + X21 - X23;
472
57.4M
   const int64_t S1 = 0x00000000 + X01 + X13 + X22 + X23 - X12 - X20;
473
57.4M
   const int64_t S2 = 0x00000000 + X02 + X14 + X23 - X13 - X21;
474
57.4M
   const int64_t S3 = 0xFFFFFFFF + X03 + X12 + X15 + X20 + X21 - X14 - X22 - X23;
475
57.4M
   const int64_t S4 = 0xFFFFFFFE + X04 + X12 + X13 + X16 + X20 + X21*2 + X22 - X15 - X23*2;
476
57.4M
   const int64_t S5 = 0xFFFFFFFF + X05 + X13 + X14 + X17 + X21 + X22*2 + X23 - X16;
477
57.4M
   const int64_t S6 = 0xFFFFFFFF + X06 + X14 + X15 + X18 + X22 + X23*2 - X17;
478
57.4M
   const int64_t S7 = 0xFFFFFFFF + X07 + X15 + X16 + X19 + X23 - X18;
479
57.4M
   const int64_t S8 = 0xFFFFFFFF + X08 + X16 + X17 + X20 - X19;
480
57.4M
   const int64_t S9 = 0xFFFFFFFF + X09 + X17 + X18 + X21 - X20;
481
57.4M
   const int64_t SA = 0xFFFFFFFF + X10 + X18 + X19 + X22 - X21;
482
57.4M
   const int64_t SB = 0xFFFFFFFF + X11 + X19 + X20 + X23 - X22;
483
57.4M
484
57.4M
   int64_t S = 0;
485
57.4M
486
57.4M
   uint32_t R0 = 0, R1 = 0;
487
57.4M
488
57.4M
   S += S0;
489
57.4M
   R0 = static_cast<uint32_t>(S);
490
57.4M
   S >>= 32;
491
57.4M
492
57.4M
   S += S1;
493
57.4M
   R1 = static_cast<uint32_t>(S);
494
57.4M
   S >>= 32;
495
57.4M
496
57.4M
   set_words(xw, 0, R0, R1);
497
57.4M
498
57.4M
   S += S2;
499
57.4M
   R0 = static_cast<uint32_t>(S);
500
57.4M
   S >>= 32;
501
57.4M
502
57.4M
   S += S3;
503
57.4M
   R1 = static_cast<uint32_t>(S);
504
57.4M
   S >>= 32;
505
57.4M
506
57.4M
   set_words(xw, 2, R0, R1);
507
57.4M
508
57.4M
   S += S4;
509
57.4M
   R0 = static_cast<uint32_t>(S);
510
57.4M
   S >>= 32;
511
57.4M
512
57.4M
   S += S5;
513
57.4M
   R1 = static_cast<uint32_t>(S);
514
57.4M
   S >>= 32;
515
57.4M
516
57.4M
   set_words(xw, 4, R0, R1);
517
57.4M
518
57.4M
   S += S6;
519
57.4M
   R0 = static_cast<uint32_t>(S);
520
57.4M
   S >>= 32;
521
57.4M
522
57.4M
   S += S7;
523
57.4M
   R1 = static_cast<uint32_t>(S);
524
57.4M
   S >>= 32;
525
57.4M
526
57.4M
   set_words(xw, 6, R0, R1);
527
57.4M
528
57.4M
   S += S8;
529
57.4M
   R0 = static_cast<uint32_t>(S);
530
57.4M
   S >>= 32;
531
57.4M
532
57.4M
   S += S9;
533
57.4M
   R1 = static_cast<uint32_t>(S);
534
57.4M
   S >>= 32;
535
57.4M
536
57.4M
   set_words(xw, 8, R0, R1);
537
57.4M
538
57.4M
   S += SA;
539
57.4M
   R0 = static_cast<uint32_t>(S);
540
57.4M
   S >>= 32;
541
57.4M
542
57.4M
   S += SB;
543
57.4M
   R1 = static_cast<uint32_t>(S);
544
57.4M
   S >>= 32;
545
57.4M
546
57.4M
   set_words(xw, 10, R0, R1);
547
57.4M
548
57.4M
   /*
549
57.4M
   This is a table of (i*P-384) % 2**384 for i in 1...4
550
57.4M
   */
551
57.4M
   static const word p384_mults[5][p384_limbs] = {
552
57.4M
#if (BOTAN_MP_WORD_BITS == 64)
553
57.4M
      {0x00000000FFFFFFFF, 0xFFFFFFFF00000000, 0xFFFFFFFFFFFFFFFE, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
554
57.4M
      {0x00000001FFFFFFFE, 0xFFFFFFFE00000000, 0xFFFFFFFFFFFFFFFD, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
555
57.4M
      {0x00000002FFFFFFFD, 0xFFFFFFFD00000000, 0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
556
57.4M
      {0x00000003FFFFFFFC, 0xFFFFFFFC00000000, 0xFFFFFFFFFFFFFFFB, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
557
57.4M
      {0x00000004FFFFFFFB, 0xFFFFFFFB00000000, 0xFFFFFFFFFFFFFFFA, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF},
558
57.4M
559
#else
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},
570
#endif
571
   };
572
57.4M
573
57.4M
   CT::unpoison(S);
574
57.4M
   BOTAN_ASSERT(S >= 0 && S <= 4, "Expected overflow");
575
57.4M
576
57.4M
   BOTAN_ASSERT_NOMSG(x.size() >= p384_limbs + 1);
577
57.4M
   x.mask_bits(384);
578
57.4M
   word borrow = bigint_sub2(x.mutable_data(), p384_limbs + 1, p384_mults[S], p384_limbs);
579
57.4M
   BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1);
580
57.4M
   bigint_cnd_add(borrow, x.mutable_data(), p384_limbs + 1, p384_mults[0], p384_limbs);
581
57.4M
   }
582
583
}