• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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