int i,j,c2=0,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); }  if (!BN_is_odd(a)) return(0); if (ctx_passed != NULL) ctx=ctx_passed; else if ((ctx=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++]);   if (!BN_MONT_CTX_set(mont,a,ctx2)) goto err;  for (i=0; i<checks; i++) { if (!BN_pseudo_rand(check,BN_num_bits(a)-1,0,0)) goto err; 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); } ret=1; err: ctx->tos--; if ((ctx_passed == NULL) && (ctx != NULL)) BN_CTX_free(ctx); if (ctx2 != NULL) BN_CTX_free(ctx2); if (mont != NULL) BN_MONT_CTX_free(mont);  return(ret);
return BN_is_prime_fasttest(a, checks, callback, ctx_passed, NULL, cb_arg, 0);
int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),	     BN_CTX *ctx_passed, void *cb_arg)	{	int i,j,c2=0,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);		}	if (!BN_is_odd(a))		return(0);	if (ctx_passed != NULL)		ctx=ctx_passed;	else		if ((ctx=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++]);	/* Setup the montgomery structure */	if (!BN_MONT_CTX_set(mont,a,ctx2)) goto err;	for (i=0; i<checks; i++)		{		if (!BN_pseudo_rand(check,BN_num_bits(a)-1,0,0)) goto err;		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);		}	ret=1;err:	ctx->tos--;	if ((ctx_passed == NULL) && (ctx != NULL))		BN_CTX_free(ctx);	if (ctx2 != NULL)		BN_CTX_free(ctx2);	if (mont != NULL) BN_MONT_CTX_free(mont);			return(ret);	}