36 #if defined( INC_ALL )
57 #if defined( CONFIG_CONSERVE_MEMORY )
63 #if defined( INC_ALL )
99 #if defined( __WIN32__ ) && !defined( NDEBUG ) && 0
100 #define CHECK_PRIMETEST
107 #define SIEVE_SIZE 4096
114 #if NUMPRIMES < ( 21 * 8 )
115 #define FAST_SIEVE_NUMPRIMES NUMPRIMES
117 #define FAST_SIEVE_NUMPRIMES ( 21 * 8 )
135 memset( sieveArray, 0, sieveSize *
sizeof(
BOOLEAN ) );
142 unsigned int step = primes[ i ];
147 sieveIndex = ( step - sieveIndex ) / 2;
151 sieveIndex = ( ( step * 2 ) - sieveIndex ) / 2;
155 while( sieveIndex >= 0 && sieveIndex < sieveSize )
157 sieveArray[ sieveIndex ] = 1;
168 #define LFSR_POLYNOMIAL 0x1053
169 #define LFSR_MASK 0x1000
204 primes[ i ] < candidateWord; i++ )
206 if( candidateWord % primes[ i ] == 0 )
228 #ifdef CHECK_PRIMETEST
242 BIGNUM *y = &pkcInfo->param6;
243 BIGNUM *yPrime = &pkcInfo->param7;
244 BN_CTX *ctx = pkcInfo->bnCTX;
245 BIGNUM *mont_a = &ctx->bn[ ctx->tos++ ];
249 assert(
isWritePtr( pkcInfo,
sizeof( PKC_INFO ) ) );
266 for ( i = k - 1; i >= 0; i-- )
273 ( !
BN_cmp( yPrime, mont_1 ) && \
292 tmp = y; y = yPrime; yPrime = tmp;
306 static
int primeProbableOld(
INOUT PKC_INFO *pkcInfo,
308 IN_RANGE( 1, 100 )
const int noChecks )
310 BIGNUM *check = &pkcInfo->tmp1;
311 BIGNUM *candidate_1 = &pkcInfo->tmp2;
312 BIGNUM *mont_candidate_1 = &pkcInfo->tmp3;
313 BIGNUM *mont_1 = &pkcInfo->param8;
314 BN_MONT_CTX *montCTX_candidate = &pkcInfo->montCTX1;
317 assert(
isWritePtr( pkcInfo,
sizeof( PKC_INFO ) ) );
320 REQUIRES( noChecks >= 1 && noChecks <= 100 );
336 for( i = 0; i < noChecks; i++ )
362 status = witnessOld( pkcInfo, check, candidate, candidate_1,
363 mont_candidate_1, mont_1, montCTX_candidate );
401 assert(
isWritePtr( pkcInfo,
sizeof( PKC_INFO ) ) );
418 for( i = 1; i < k; i++ )
447 int primeProbable(
INOUT PKC_INFO *pkcInfo,
449 IN_RANGE( 1, 100 )
const int noChecks )
451 BIGNUM *a = &pkcInfo->tmp1, *n_1 = &pkcInfo->tmp2, *u = &pkcInfo->tmp3;
454 assert(
isWritePtr( pkcInfo,
sizeof( PKC_INFO ) ) );
457 REQUIRES( noChecks >= 1 && noChecks <= 100 );
473 for( k = 1, iterationCount = 0;
476 k++, iterationCount++ );
477 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
483 for( i = 0; i < noChecks; i++ )
511 status = witness( pkcInfo, a, n, n_1, u, k, &pkcInfo->montCTX1 );
526 int generatePrime(
INOUT PKC_INFO *pkcInfo,
534 int offset, oldOffset = 0, startPoint, iterationCount;
537 assert(
isWritePtr( pkcInfo,
sizeof( PKC_INFO ) ) );
545 ( exponent >= 17 && exponent < INT_MAX - 1000 ) );
551 status = generateBignum( candidate, noBits, 0xC0, 0x1 );
556 if( ( sieveArray =
clAlloc(
"generatePrime", \
560 for( iterationCount = 0;
564 int innerIterationCount;
568 initSieve( sieveArray,
SIEVE_SIZE, candidate );
572 CRYPT_IATTRIBUTE_RANDOM );
576 if( startPoint <= 0 )
585 for( offset = nextEntry( startPoint ), innerIterationCount = 0; \
586 offset != startPoint && innerIterationCount <
SIEVE_SIZE + 1; \
587 offset = nextEntry( offset ), innerIterationCount++ )
589 #ifdef CHECK_PRIMETEST
590 LARGE_INTEGER tStart, tStop;
591 BOOLEAN passedFermat, passedOldPrimeTest;
592 int oldTicks, newTicks, ratio;
596 ENSURES( offset > 0 && offset < SIEVE_SIZE );
597 ENSURES( offset != oldOffset );
600 if( sieveArray[ offset ] != 0 )
605 if( offset > oldOffset )
616 #if defined( CHECK_PRIMETEST )
629 candidate, pkcInfo->bnCTX,
630 &pkcInfo->montCTX1 ) );
632 BN_is_word( &pkcInfo->tmp2, 2 ) ) ?
TRUE :
FALSE;
635 QueryPerformanceCounter( &tStart );
636 status = primeProbableOld( pkcInfo, candidate, noChecks );
637 QueryPerformanceCounter( &tStop );
638 assert( tStart.HighPart == tStop.HighPart );
639 oldTicks = tStop.LowPart - tStart.LowPart;
642 passedOldPrimeTest =
status;
645 QueryPerformanceCounter( &tStart );
646 status = primeProbable( pkcInfo, candidate, noChecks );
647 QueryPerformanceCounter( &tStop );
648 assert( tStart.HighPart == tStop.HighPart );
649 newTicks = tStop.LowPart - tStart.LowPart;
650 ratio = ( oldTicks * 100 ) / newTicks;
651 printf(
"%4d bits, old MR = %6d ticks, new MR = %6d ticks, "
652 "ratio = %d.%d\n", noBits, oldTicks, newTicks,
653 ratio / 100, ratio % 100 );
654 if( status != passedFermat || status != passedOldPrimeTest )
656 printf(
"Fermat reports %d, old Miller-Rabin reports %d, "
657 "new Miller-Rabin reports %d.\n",
658 passedFermat, passedOldPrimeTest, status );
662 status = primeProbable( pkcInfo, candidate, noChecks );
666 if( status ==
FALSE )
697 ENSURES( innerIterationCount < SIEVE_SIZE + 1 );
699 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
704 clFree(
"generatePrime", sieveArray );
745 REQUIRES( high > 0 && high <= 0xFF );
746 REQUIRES( low >= 0 && low <= 0xFF );
756 &msgData, CRYPT_IATTRIBUTE_RANDOM );
767 buffer[ noBytes - 1 ] |= low;
768 buffer[ 0 ] &= 0xFF >> ( -noBits & 7 );
769 buffer[ 0 ] |= high >> ( -noBits & 7 );
771 buffer[ 1 ] |= ( high << ( noBits & 7 ) ) & 0xFF;
778 status = importBignum( bn, buffer, noBytes,
max( noBytes - 8, 1 ),
784 status = importBignum( bn, buffer, noBytes,
max( noBytes - 8, 1 ),