*/
#include "bn_prime.h"
-/* number of Miller-Rabin iterations for an error rate of less than 2^-80
- * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
- * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
- * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
- * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
-#define BN_prime_checks_size(b) ((b) >= 1300 ? 2 : \
- (b) >= 850 ? 3 : \
- (b) >= 650 ? 4 : \
- (b) >= 550 ? 5 : \
- (b) >= 450 ? 6 : \
- (b) >= 400 ? 7 : \
- (b) >= 350 ? 8 : \
- (b) >= 300 ? 9 : \
- (b) >= 250 ? 12 : \
- (b) >= 200 ? 15 : \
- (b) >= 150 ? 18 : \
- /* b >= 100 */ 27)
-
static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2,
BN_MONT_CTX *mont);
static int probable_prime(BIGNUM *rnd, int bits);
int found=0;
int i,j,c1=0;
BN_CTX *ctx;
- int checks = BN_prime_checks_size(bits);
+ int checks = BN_prime_checks_for_size(bits);
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
return(found ? rnd : NULL);
}
-int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
- BN_CTX *ctx_passed, void *cb_arg)
+int BN_is_prime_fasttest(BIGNUM *a, int checks,
+ void (*callback)(int,int,void *),
+ BN_CTX *ctx_passed, BN_CTX *ctx2_passed, void *cb_arg,
+ int do_trial_division)
{
- int i,j,c2=0,ret= -1;
+ int i,j,ret= -1;
BIGNUM *check;
BN_CTX *ctx=NULL,*ctx2=NULL;
BN_MONT_CTX *mont=NULL;
if (checks == BN_prime_checks)
{
int bits = BN_num_bits(a);
- checks = BN_prime_checks_size(bits);
+ checks = BN_prime_checks_for_size(bits);
}
if (!BN_is_odd(a))
return(0);
+ if (do_trial_division)
+ for (i = 1; i < NUMPRIMES; i++)
+ if (BN_mod_word(a, primes[i]) == 0)
+ return 0;
+
if (ctx_passed != NULL)
ctx=ctx_passed;
else
if ((ctx=BN_CTX_new()) == NULL) goto err;
+ if (ctx2_passed != NULL)
+ ctx2=ctx2_passed;
+ else
+ if ((ctx2=BN_CTX_new()) == NULL) goto err;
- if ((ctx2=BN_CTX_new()) == NULL) goto err;
if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
check= &(ctx->bn[ctx->tos++]);
for (i=0; i<checks; i++)
{
- if (!BN_rand(check,BN_num_bits(a)-1,0,0)) goto err;
+ if (!BN_pseudo_rand(check,BN_num_bits(a),0,0)) goto err;
+ if (BN_cmp(check, a) >= 0)
+ BN_sub(check, check, a);
j=witness(check,a,ctx,ctx2,mont);
if (j == -1) goto err;
if (j)
ret=0;
goto err;
}
- if (callback != NULL) callback(1,c2++,cb_arg);
+ if (callback != NULL) callback(1,i,cb_arg);
}
ret=1;
err:
ctx->tos--;
if ((ctx_passed == NULL) && (ctx != NULL))
BN_CTX_free(ctx);
- if (ctx2 != NULL)
+ if ((ctx2_passed == NULL) && (ctx2 != NULL))
BN_CTX_free(ctx2);
if (mont != NULL) BN_MONT_CTX_free(mont);
return(ret);
}
-#define RECP_MUL_MOD
+int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
+ BN_CTX *ctx_passed, void *cb_arg)
+ {
+ return BN_is_prime_fasttest(a, checks, callback, ctx_passed, NULL, cb_arg, 0);
+ }
static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx, BN_CTX *ctx2,
BN_MONT_CTX *mont)
static int probable_prime(BIGNUM *rnd, int bits)
{
int i;
- MS_STATIC BN_ULONG mods[NUMPRIMES];
+ BN_ULONG mods[NUMPRIMES];
BN_ULONG delta,d;
again:
}
#if 0
-static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx)
+
+#define RECP_MUL_MOD
+
+static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,
+ BN_CTX *unused, BN_MONT_CTX *unused2)
{
- int k,i,nb,ret= -1;
+ int k,i,ret= -1;
BIGNUM *d,*dd,*tmp;
- BIGNUM *d1,*d2,*x,*n1,*inv;
+ BIGNUM *d1,*d2,*x,*n1;
+ BN_RECP_CTX recp;
d1= &(ctx->bn[ctx->tos]);
d2= &(ctx->bn[ctx->tos+1]);
x= &(ctx->bn[ctx->tos+2]);
n1= &(ctx->bn[ctx->tos+3]);
- inv=&(ctx->bn[ctx->tos+4]);
- ctx->tos+=5;
+ ctx->tos+=4;
d=d1;
dd=d2;
/* i=BN_num_bits(n); */
#ifdef RECP_MUL_MOD
- nb=BN_reciprocal(inv,n,ctx); /**/
- if (nb == -1) goto err;
+ BN_RECP_CTX_init(&recp);
+ if (BN_RECP_CTX_set(&recp,n,ctx) <= 0) goto err;
#endif
for (i=k-1; i>=0; i--)
#ifndef RECP_MUL_MOD
if (!BN_mod_mul(dd,d,d,n,ctx)) goto err;
#else
- if (!BN_mod_mul_reciprocal(dd,d,d,n,inv,nb,ctx)) goto err;
+ if (!BN_mod_mul_reciprocal(dd,d,d,&recp,ctx)) goto err;
#endif
if ( BN_is_one(dd) &&
!BN_is_one(x) &&
#ifndef RECP_MUL_MOD
if (!BN_mod_mul(d,dd,a,n,ctx)) goto err;
#else
- if (!BN_mod_mul_reciprocal(d,dd,a,n,inv,nb,ctx)) goto err;
+ if (!BN_mod_mul_reciprocal(d,dd,a,&recp,ctx)) goto err;
#endif
}
else
else i=1;
ret=i;
err:
- ctx->tos-=5;
+ ctx->tos-=4;
+#ifdef RECP_MUL_MOD
+ BN_RECP_CTX_free(&recp);
+#endif
return(ret);
}
#endif