1 /* Microsoft Reference Implementation for TPM 2.0
2 *
3 * The copyright in this software is being made available under the BSD License,
4 * included below. This software may be subject to other third party and
5 * contributor rights, including patent rights, and no such rights are granted
6 * under this license.
7 *
8 * Copyright (c) Microsoft Corporation
9 *
10 * All rights reserved.
11 *
12 * BSD License
13 *
14 * Redistribution and use in source and binary forms, with or without modification,
15 * are permitted provided that the following conditions are met:
16 *
17 * Redistributions of source code must retain the above copyright notice, this list
18 * of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice, this
21 * list of conditions and the following disclaimer in the documentation and/or
22 * other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ""AS IS""
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 //** Includes and defines
36
37 #include "Tpm.h"
38
39 #if RSA_KEY_SIEVE
40
41 #include "CryptPrimeSieve_fp.h"
42
43 // This determines the number of bits in the largest sieve field.
44 #define MAX_FIELD_SIZE 2048
45
46 extern const uint32_t s_LastPrimeInTable;
47 extern const uint32_t s_PrimeTableSize;
48 extern const uint32_t s_PrimesInTable;
49 extern const unsigned char s_PrimeTable[];
50
51 // This table is set of prime markers. Each entry is the prime value
52 // for the ((n + 1) * 1024) prime. That is, the entry in s_PrimeMarkers[1]
53 // is the value for the 2,048th prime. This is used in the PrimeSieve
54 // to adjust the limit for the prime search. When processing smaller
55 // prime candidates, fewer primes are checked directly before going to
56 // Miller-Rabin. As the prime grows, it is worth spending more time eliminating
57 // primes as, a) the density is lower, and b) the cost of Miller-Rabin is
58 // higher.
59 const uint32_t s_PrimeMarkersCount = 6;
60 const uint32_t s_PrimeMarkers[] = {
61 8167, 17881, 28183, 38891, 49871, 60961 };
62 uint32_t primeLimit;
63
64 //** Functions
65
66 //*** RsaAdjustPrimeLimit()
67 // This used during the sieve process. The iterator for getting the
68 // next prime (RsaNextPrime()) will return primes until it hits the
69 // limit (primeLimit) set up by this function. This causes the sieve
70 // process to stop when an appropriate number of primes have been
71 // sieved.
72 LIB_EXPORT void
RsaAdjustPrimeLimit(uint32_t requestedPrimes)73 RsaAdjustPrimeLimit(
74 uint32_t requestedPrimes
75 )
76 {
77 if(requestedPrimes == 0 || requestedPrimes > s_PrimesInTable)
78 requestedPrimes = s_PrimesInTable;
79 requestedPrimes = (requestedPrimes - 1) / 1024;
80 if(requestedPrimes < s_PrimeMarkersCount)
81 primeLimit = s_PrimeMarkers[requestedPrimes];
82 else
83 primeLimit = s_LastPrimeInTable;
84 primeLimit >>= 1;
85
86 }
87
88 //*** RsaNextPrime()
89 // This the iterator used during the sieve process. The input is the
90 // last prime returned (or any starting point) and the output is the
91 // next higher prime. The function returns 0 when the primeLimit is
92 // reached.
93 LIB_EXPORT uint32_t
RsaNextPrime(uint32_t lastPrime)94 RsaNextPrime(
95 uint32_t lastPrime
96 )
97 {
98 if(lastPrime == 0)
99 return 0;
100 lastPrime >>= 1;
101 for(lastPrime += 1; lastPrime <= primeLimit; lastPrime++)
102 {
103 if(((s_PrimeTable[lastPrime >> 3] >> (lastPrime & 0x7)) & 1) == 1)
104 return ((lastPrime << 1) + 1);
105 }
106 return 0;
107 }
108
109 // This table contains a previously sieved table. It has
110 // the bits for 3, 5, and 7 removed. Because of the
111 // factors, it needs to be aligned to 105 and has
112 // a repeat of 105.
113 const BYTE seedValues[] = {
114 0x16, 0x29, 0xcb, 0xa4, 0x65, 0xda, 0x30, 0x6c,
115 0x99, 0x96, 0x4c, 0x53, 0xa2, 0x2d, 0x52, 0x96,
116 0x49, 0xcb, 0xb4, 0x61, 0xd8, 0x32, 0x2d, 0x99,
117 0xa6, 0x44, 0x5b, 0xa4, 0x2c, 0x93, 0x96, 0x69,
118 0xc3, 0xb0, 0x65, 0x5a, 0x32, 0x4d, 0x89, 0xb6,
119 0x48, 0x59, 0x26, 0x2d, 0xd3, 0x86, 0x61, 0xcb,
120 0xb4, 0x64, 0x9a, 0x12, 0x6d, 0x91, 0xb2, 0x4c,
121 0x5a, 0xa6, 0x0d, 0xc3, 0x96, 0x69, 0xc9, 0x34,
122 0x25, 0xda, 0x22, 0x65, 0x99, 0xb4, 0x4c, 0x1b,
123 0x86, 0x2d, 0xd3, 0x92, 0x69, 0x4a, 0xb4, 0x45,
124 0xca, 0x32, 0x69, 0x99, 0x36, 0x0c, 0x5b, 0xa6,
125 0x25, 0xd3, 0x94, 0x68, 0x8b, 0x94, 0x65, 0xd2,
126 0x32, 0x6d, 0x18, 0xb6, 0x4c, 0x4b, 0xa6, 0x29,
127 0xd1};
128
129 #define USE_NIBBLE
130
131 #ifndef USE_NIBBLE
132 static const BYTE bitsInByte[256] = {
133 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
134 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
135 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
136 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
137 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
138 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
139 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
140 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
141 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
142 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
143 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
144 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
145 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
146 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
147 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
148 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
149 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
150 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
151 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
152 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
153 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
154 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
155 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
156 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
157 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05,
158 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
159 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
160 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
161 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06,
162 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
163 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
164 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08
165 };
166 #define BitsInByte(x) bitsInByte[(unsigned char)x]
167 #else
168 const BYTE bitsInNibble[16] = {
169 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03,
170 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04};
171 #define BitsInByte(x) \
172 (bitsInNibble[(unsigned char)(x) & 0xf] \
173 + bitsInNibble[((unsigned char)(x) >> 4) & 0xf])
174 #endif
175
176 //*** BitsInArry()
177 // This function counts the number of bits set in an array of bytes.
178 static int
BitsInArray(const unsigned char * a,unsigned int aSize)179 BitsInArray(
180 const unsigned char *a, // IN: A pointer to an array of bytes
181 unsigned int aSize // IN: the number of bytes to sum
182 )
183 {
184 int j = 0;
185 for(; aSize; a++, aSize--)
186 j += BitsInByte(*a);
187 return j;
188 }
189
190 //*** FindNthSetBit()
191 // This function finds the nth SET bit in a bit array. The 'n' parameter is
192 // between 1 and the number of bits in the array (always a multiple of 8).
193 // If called when the array does not have n bits set, it will return -1
194 // Return Type: unsigned int
195 // <0 no bit is set or no bit with the requested number is set
196 // >=0 the number of the bit in the array that is the nth set
197 LIB_EXPORT int
FindNthSetBit(const UINT16 aSize,const BYTE * a,const UINT32 n)198 FindNthSetBit(
199 const UINT16 aSize, // IN: the size of the array to check
200 const BYTE *a, // IN: the array to check
201 const UINT32 n // IN, the number of the SET bit
202 )
203 {
204 UINT16 i;
205 int retValue;
206 UINT32 sum = 0;
207 BYTE sel;
208
209 //find the bit
210 for(i = 0; (i < (int)aSize) && (sum < n); i++)
211 sum += BitsInByte(a[i]);
212 i--;
213 // The chosen bit is in the byte that was just accessed
214 // Compute the offset to the start of that byte
215 retValue = i * 8 - 1;
216 sel = a[i];
217 // Subtract the bits in the last byte added.
218 sum -= BitsInByte(sel);
219 // Now process the byte, one bit at a time.
220 for(; (sel != 0) && (sum != n); retValue++, sel = sel >> 1)
221 sum += (sel & 1) != 0;
222 return (sum == n) ? retValue : -1;
223 }
224
225 typedef struct
226 {
227 UINT16 prime;
228 UINT16 count;
229 } SIEVE_MARKS;
230
231 const SIEVE_MARKS sieveMarks[5] = {
232 {31, 7}, {73, 5}, {241, 4}, {1621, 3}, {UINT16_MAX, 2}};
233
234
235 //*** PrimeSieve()
236 // This function does a prime sieve over the input 'field' which has as its
237 // starting address the value in bnN. Since this initializes the Sieve
238 // using a precomputed field with the bits associated with 3, 5 and 7 already
239 // turned off, the value of pnN may need to be adjusted by a few counts to allow
240 // the precomputed field to be used without modification.
241 //
242 // To get better performance, one could address the issue of developing the
243 // composite numbers. When the size of the prime gets large, the time for doing
244 // the divisions goes up, noticeably. It could be better to develop larger composite
245 // numbers even if they need to be bigNum's themselves. The object would be to
246 // reduce the number of times that the large prime is divided into a few large
247 // divides and then use smaller divides to get to the final 16 bit (or smaller)
248 // remainders.
249 LIB_EXPORT UINT32
PrimeSieve(bigNum bnN,UINT32 fieldSize,BYTE * field)250 PrimeSieve(
251 bigNum bnN, // IN/OUT: number to sieve
252 UINT32 fieldSize, // IN: size of the field area in bytes
253 BYTE *field // IN: field
254 )
255 {
256 UINT32 i;
257 UINT32 j;
258 UINT32 fieldBits = fieldSize * 8;
259 UINT32 r;
260 BYTE *pField;
261 INT32 iter;
262 UINT32 adjust;
263 UINT32 mark = 0;
264 UINT32 count = sieveMarks[0].count;
265 UINT32 stop = sieveMarks[0].prime;
266 UINT32 composite;
267 UINT32 pList[8];
268 UINT32 next;
269
270 pAssert(field != NULL && bnN != NULL);
271
272 // If the remainder is odd, then subtracting the value will give an even number,
273 // but we want an odd number, so subtract the 105+rem. Otherwise, just subtract
274 // the even remainder.
275 adjust = (UINT32)BnModWord(bnN, 105);
276 if(adjust & 1)
277 adjust += 105;
278
279 // Adjust the input number so that it points to the first number in a
280 // aligned field.
281 BnSubWord(bnN, bnN, adjust);
282 // pAssert(BnModWord(bnN, 105) == 0);
283 pField = field;
284 for(i = fieldSize; i >= sizeof(seedValues);
285 pField += sizeof(seedValues), i -= sizeof(seedValues))
286 {
287 memcpy(pField, seedValues, sizeof(seedValues));
288 }
289 if(i != 0)
290 memcpy(pField, seedValues, i);
291
292 // Cycle through the primes, clearing bits
293 // Have already done 3, 5, and 7
294 iter = 7;
295
296 #define NEXT_PRIME(iter) (iter = RsaNextPrime(iter))
297 // Get the next N primes where N is determined by the mark in the sieveMarks
298 while((composite = NEXT_PRIME(iter)) != 0)
299 {
300 next = 0;
301 i = count;
302 pList[i--] = composite;
303 for(; i > 0; i--)
304 {
305 next = NEXT_PRIME(iter);
306 pList[i] = next;
307 if(next != 0)
308 composite *= next;
309 }
310 // Get the remainder when dividing the base field address
311 // by the composite
312 composite = (UINT32)BnModWord(bnN, composite);
313 // 'composite' is divisible by the composite components. for each of the
314 // composite components, divide 'composite'. That remainder (r) is used to
315 // pick a starting point for clearing the array. The stride is equal to the
316 // composite component. Note, the field only contains odd numbers. If the
317 // field were expanded to contain all numbers, then half of the bits would
318 // have already been cleared. We can save the trouble of clearing them a
319 // second time by having a stride of 2*next. Or we can take all of the even
320 // numbers out of the field and use a stride of 'next'
321 for(i = count; i > 0; i--)
322 {
323 next = pList[i];
324 if(next == 0)
325 goto done;
326 r = composite % next;
327 // these computations deal with the fact that we have picked a field-sized
328 // range that is aligned to a 105 count boundary. The problem is, this field
329 // only contains odd numbers. If we take our prime guess and walk through all
330 // the numbers using that prime as the 'stride', then every other 'stride' is
331 // going to be an even number. So, we are actually counting by 2 * the stride
332 // We want the count to start on an odd number at the start of our field. That
333 // is, we want to assume that we have counted up to the edge of the field by
334 // the 'stride' and now we are going to start flipping bits in the field as we
335 // continue to count up by 'stride'. If we take the base of our field and
336 // divide by the stride, we find out how much we find out how short the last
337 // count was from reaching the edge of the bit field. Say we get a quotient of
338 // 3 and remainder of 1. This means that after 3 strides, we are 1 short of
339 // the start of the field and the next stride will either land within the
340 // field or step completely over it. The confounding factor is that our field
341 // only contains odd numbers and our stride is actually 2 * stride. If the
342 // quoitent is even, then that means that when we add 2 * stride, we are going
343 // to hit another even number. So, we have to know if we need to back off
344 // by 1 stride before we start couting by 2 * stride.
345 // We can tell from the remainder whether we are on an even or odd
346 // stride when we hit the beginning of the table. If we are on an odd stride
347 // (r & 1), we would start half a stride in (next - r)/2. If we are on an
348 // even stride, we need 0.5 strides (next - r/2) because the table only has
349 // odd numbers. If the remainder happens to be zero, then the start of the
350 // table is on stride so no adjustment is necessary.
351 if(r & 1) j = (next - r) / 2;
352 else if(r == 0) j = 0;
353 else j = next - (r / 2);
354 for(; j < fieldBits; j += next)
355 ClearBit(j, field, fieldSize);
356 }
357 if(next >= stop)
358 {
359 mark++;
360 count = sieveMarks[mark].count;
361 stop = sieveMarks[mark].prime;
362 }
363 }
364 done:
365 INSTRUMENT_INC(totalFieldsSieved[PrimeIndex]);
366 i = BitsInArray(field, fieldSize);
367 INSTRUMENT_ADD(bitsInFieldAfterSieve[PrimeIndex], i);
368 INSTRUMENT_ADD(emptyFieldsSieved[PrimeIndex], (i == 0));
369 return i;
370 }
371
372
373
374 #ifdef SIEVE_DEBUG
375 static uint32_t fieldSize = 210;
376
377 //***SetFieldSize()
378 // Function to set the field size used for prime generation. Used for tuning.
379 LIB_EXPORT uint32_t
SetFieldSize(uint32_t newFieldSize)380 SetFieldSize(
381 uint32_t newFieldSize
382 )
383 {
384 if(newFieldSize == 0 || newFieldSize > MAX_FIELD_SIZE)
385 fieldSize = MAX_FIELD_SIZE;
386 else
387 fieldSize = newFieldSize;
388 return fieldSize;
389 }
390 #endif // SIEVE_DEBUG
391
392 //*** PrimeSelectWithSieve()
393 // This function will sieve the field around the input prime candidate. If the
394 // sieve field is not empty, one of the one bits in the field is chosen for testing
395 // with Miller-Rabin. If the value is prime, 'pnP' is updated with this value
396 // and the function returns success. If this value is not prime, another
397 // pseudo-random candidate is chosen and tested. This process repeats until
398 // all values in the field have been checked. If all bits in the field have
399 // been checked and none is prime, the function returns FALSE and a new random
400 // value needs to be chosen.
401 // Return Type: TPM_RC
402 // TPM_RC_FAILURE TPM in failure mode, probably due to entropy source
403 // TPM_RC_SUCCESS candidate is probably prime
404 // TPM_RC_NO_RESULT candidate is not prime and couldn't find and alternative
405 // in the field
406 LIB_EXPORT TPM_RC
PrimeSelectWithSieve(bigNum candidate,UINT32 e,RAND_STATE * rand)407 PrimeSelectWithSieve(
408 bigNum candidate, // IN/OUT: The candidate to filter
409 UINT32 e, // IN: the exponent
410 RAND_STATE *rand // IN: the random number generator state
411 )
412 {
413 BYTE field[MAX_FIELD_SIZE];
414 UINT32 first;
415 UINT32 ones;
416 INT32 chosen;
417 BN_PRIME(test);
418 UINT32 modE;
419 #ifndef SIEVE_DEBUG
420 UINT32 fieldSize = MAX_FIELD_SIZE;
421 #endif
422 UINT32 primeSize;
423 //
424 // Adjust the field size and prime table list to fit the size of the prime
425 // being tested. This is done to try to optimize the trade-off between the
426 // dividing done for sieving and the time for Miller-Rabin. When the size
427 // of the prime is large, the cost of Miller-Rabin is fairly high, as is the
428 // cost of the sieving. However, the time for Miller-Rabin goes up considerably
429 // faster than the cost of dividing by a number of primes.
430 primeSize = BnSizeInBits(candidate);
431
432 if(primeSize <= 512)
433 {
434 RsaAdjustPrimeLimit(1024); // Use just the first 1024 primes
435 }
436 else if(primeSize <= 1024)
437 {
438 RsaAdjustPrimeLimit(4096); // Use just the first 4K primes
439 }
440 else
441 {
442 RsaAdjustPrimeLimit(0); // Use all available
443 }
444
445 // Save the low-order word to use as a search generator and make sure that
446 // it has some interesting range to it
447 first = (UINT32)(candidate->d[0] | 0x80000000);
448
449 // Sieve the field
450 ones = PrimeSieve(candidate, fieldSize, field);
451 pAssert(ones > 0 && ones < (fieldSize * 8));
452 for(; ones > 0; ones--)
453 {
454 // Decide which bit to look at and find its offset
455 chosen = FindNthSetBit((UINT16)fieldSize, field, ((first % ones) + 1));
456
457 if((chosen < 0) || (chosen >= (INT32)(fieldSize * 8)))
458 FAIL(FATAL_ERROR_INTERNAL);
459
460 // Set this as the trial prime
461 BnAddWord(test, candidate, (crypt_uword_t)(chosen * 2));
462
463 // The exponent might not have been one of the tested primes so
464 // make sure that it isn't divisible and make sure that 0 != (p-1) mod e
465 // Note: This is the same as 1 != p mod e
466 modE = (UINT32)BnModWord(test, e);
467 if((modE != 0) && (modE != 1) && MillerRabin(test, rand))
468 {
469 BnCopy(candidate, test);
470 return TPM_RC_SUCCESS;
471 }
472 // Clear the bit just tested
473 ClearBit(chosen, field, fieldSize);
474 }
475 // Ran out of bits and couldn't find a prime in this field
476 INSTRUMENT_INC(noPrimeFields[PrimeIndex]);
477 return (g_inFailureMode ? TPM_RC_FAILURE : TPM_RC_NO_RESULT);
478 }
479
480 #if RSA_INSTRUMENT
481 static char a[256];
482
483 //*** PrintTuple()
484 char *
PrintTuple(UINT32 * i)485 PrintTuple(
486 UINT32 *i
487 )
488 {
489 sprintf(a, "{%d, %d, %d}", i[0], i[1], i[2]);
490 return a;
491 }
492
493 #define CLEAR_VALUE(x) memset(x, 0, sizeof(x))
494
495 //*** RsaSimulationEnd()
496 void
RsaSimulationEnd(void)497 RsaSimulationEnd(
498 void
499 )
500 {
501 int i;
502 UINT32 averages[3];
503 UINT32 nonFirst = 0;
504 if((PrimeCounts[0] + PrimeCounts[1] + PrimeCounts[2]) != 0)
505 {
506 printf("Primes generated = %s\n", PrintTuple(PrimeCounts));
507 printf("Fields sieved = %s\n", PrintTuple(totalFieldsSieved));
508 printf("Fields with no primes = %s\n", PrintTuple(noPrimeFields));
509 printf("Primes checked with Miller-Rabin = %s\n",
510 PrintTuple(MillerRabinTrials));
511 for(i = 0; i < 3; i++)
512 averages[i] = (totalFieldsSieved[i]
513 != 0 ? bitsInFieldAfterSieve[i] / totalFieldsSieved[i]
514 : 0);
515 printf("Average candidates in field %s\n", PrintTuple(averages));
516 for(i = 1; i < (sizeof(failedAtIteration) / sizeof(failedAtIteration[0]));
517 i++)
518 nonFirst += failedAtIteration[i];
519 printf("Miller-Rabin failures not in first round = %d\n", nonFirst);
520
521 }
522 CLEAR_VALUE(PrimeCounts);
523 CLEAR_VALUE(totalFieldsSieved);
524 CLEAR_VALUE(noPrimeFields);
525 CLEAR_VALUE(MillerRabinTrials);
526 CLEAR_VALUE(bitsInFieldAfterSieve);
527 }
528
529 //*** GetSieveStats()
530 LIB_EXPORT void
GetSieveStats(uint32_t * trials,uint32_t * emptyFields,uint32_t * averageBits)531 GetSieveStats(
532 uint32_t *trials,
533 uint32_t *emptyFields,
534 uint32_t *averageBits
535 )
536 {
537 uint32_t totalBits;
538 uint32_t fields;
539 *trials = MillerRabinTrials[0] + MillerRabinTrials[1] + MillerRabinTrials[2];
540 *emptyFields = noPrimeFields[0] + noPrimeFields[1] + noPrimeFields[2];
541 fields = totalFieldsSieved[0] + totalFieldsSieved[1]
542 + totalFieldsSieved[2];
543 totalBits = bitsInFieldAfterSieve[0] + bitsInFieldAfterSieve[1]
544 + bitsInFieldAfterSieve[2];
545 if(fields != 0)
546 *averageBits = totalBits / fields;
547 else
548 *averageBits = 0;
549 CLEAR_VALUE(PrimeCounts);
550 CLEAR_VALUE(totalFieldsSieved);
551 CLEAR_VALUE(noPrimeFields);
552 CLEAR_VALUE(MillerRabinTrials);
553 CLEAR_VALUE(bitsInFieldAfterSieve);
554
555 }
556 #endif
557
558 #endif // RSA_KEY_SIEVE
559
560 #if !RSA_INSTRUMENT
561
562 //*** RsaSimulationEnd()
563 // Stub for call when not doing instrumentation.
564 void
RsaSimulationEnd(void)565 RsaSimulationEnd(
566 void
567 )
568 {
569 return;
570 }
571 #endif