apps/dsaparam.c:320: error: BUFFER_OVERRUN_L3
  Offset: [16, +oo] Size: [0, +oo] by call to `DSA_generate_key`.
Showing all 24 steps of the trace


apps/dsaparam.c:217:14: Call
215.   		BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num);
216.   	        BIO_printf(bio_err,"This could take some time\n");
217.   	        dsa=DSA_generate_parameters(num,NULL,0,NULL,NULL,
                    ^
218.   			dsa_cb,(char *)bio_err);
219.   		}

crypto/dsa/dsa_gen.c:224:3: Call
  222.   		{
  223.   		/* g=test^r0%p */
  224.   		BN_mod_exp_mont(g,test,r0,p,ctx,mont);
           ^
  225.   		if (!BN_is_one(g)) break;
  226.   		BN_add(test,test,BN_value_one());

crypto/bn/bn_exp.c:346:3: Call
    344.   	if (BN_ucmp(a,m) >= 0)
    345.   		{
    346.   		BN_mod(&(val[0]),a,m,ctx);
             ^
    347.   		aa= &(val[0]);
    348.   		}

crypto/bn/bn_div.c:313:9: Call
      311.   	return(1);
      312.   #else
      313.   	return(BN_div(NULL,rem,m,d,ctx));
                     ^
      314.   #endif
      315.   	}

crypto/bn/bn_div.c:121:1: Parameter `dv->top`
        119.   #else
        120.   
        121. > int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
        122.   	   BN_CTX *ctx)
        123.   	{

apps/dsaparam.c:320:8: Call
318.   
319.   		if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;
320.   		if (!DSA_generate_key(dsakey)) goto end;
              ^
321.   		if 	(outformat == FORMAT_ASN1)
322.   			i=i2d_DSAPrivateKey_bio(out,dsakey);

crypto/dsa/dsa_key.c:68:1: Parameter `dsa->p->top`
  66.   #include <openssl/rand.h>
  67.   
  68. > int DSA_generate_key(DSA *dsa)
  69.   	{
  70.   	int ok=0;

crypto/dsa/dsa_key.c:100:7: Call
  98.   		pub_key=dsa->pub_key;
  99.   
  100.   	if (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err;
               ^
  101.   
  102.   	dsa->priv_key=priv_key;

crypto/bn/bn_exp.c:157:1: Parameter `m->top`
    155.   	}
    156.   
    157. > int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
    158.   	       BN_CTX *ctx)
    159.   	{

crypto/bn/bn_exp.c:178:9: Call
    176.   #endif
    177.   #ifdef RECP_MUL_MOD
    178.   		{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }
                   ^
    179.   #else
    180.   		{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }

crypto/bn/bn_exp.c:205:6: Call
      203.   		}
      204.   	BN_RECP_CTX_init(&recp);
      205.   	if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
                  ^
      206.   
      207.   	BN_init(&(val[0]));

crypto/bn/bn_recp.c:96:2: Call
        94.   int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
        95.   	{
        96.   	BN_copy(&(recp->N),d);
               ^
        97.   	BN_zero(&(recp->Nr));
        98.   	recp->num_bits=BN_num_bits(d);

crypto/bn/bn_lib.c:499:1: Parameter `a->top`
          497.   	}
          498.   
          499. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
          500.   	{
          501.   	int i;

crypto/bn/bn_exp.c:211:7: Call
      209.   
      210.   	if (!BN_mod(&(val[0]),a,m,ctx)) goto err;		/* 1 */
      211.   	if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
                   ^
      212.   		goto err;				/* 2 */
      213.   

crypto/bn/bn_recp.c:103:1: Parameter `*recp->N.d`
        101.   	}
        102.   
        103. > int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,
        104.   	     BN_CTX *ctx)
        105.   	{

crypto/bn/bn_recp.c:120:2: Call
        118.   		a=x; /* Just do the mod */
        119.   
        120.   	BN_div_recp(NULL,r,a,recp,ctx);
                ^
        121.   	ret=1;
        122.   err:

crypto/bn/bn_recp.c:127:1: Parameter `*recp->N.d`
          125.   	}
          126.   
          127. > int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,
          128.   	     BN_CTX *ctx)
          129.   	{

crypto/bn/bn_recp.c:181:7: Call
          179.   	if (!BN_rshift(d,b,j+ex)) goto err;
          180.   	d->neg=0;
          181.   	if (!BN_mul(b,&(recp->N),d,ctx)) goto err;
                       ^
          182.   	if (!BN_usub(r,m,b)) goto err;
          183.   	r->neg=0;

crypto/bn/bn_mul.c:560:1: <Offset trace>
558.   #endif
559.   
560. > int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
561.   	{
562.   	int top,al,bl;

crypto/bn/bn_mul.c:560:1: Parameter `a->top`
            558.   #endif
            559.   
            560. > int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
            561.   	{
            562.   	int top,al,bl;

crypto/bn/bn_mul.c:577:2: Assignment
            575.   	bn_check_top(r);
            576.   
            577.   	al=a->top;
                    ^
            578.   	bl=b->top;
            579.   	r->neg=a->neg^b->neg;

crypto/bn/bn_mul.c:560:1: <Length trace>
558.   #endif
559.   
560. > int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
561.   	{
562.   	int top,al,bl;

crypto/bn/bn_mul.c:560:1: Parameter `*a->d`
            558.   #endif
            559.   
            560. > int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
            561.   	{
            562.   	int top,al,bl;

crypto/bn/bn_mul.c:648:4: Array access: Offset: [16, +oo] Size: [0, +oo] by call to `DSA_generate_key` 
            646.   			{
            647.   			bn_wexpand(a,bl);
            648.   			a->d[al]=0;
                      ^
            649.   			al++;
            650.   			goto symetric;

int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
	{
	int top,al,bl;
	BIGNUM *rr;
#ifdef BN_RECURSION
	BIGNUM *t;
	int i,j,k;
#endif
#ifdef BN_COUNT
printf("BN_mul %d * %d\n",a->top,b->top);
#endif
	bn_check_top(a);
	bn_check_top(b);
	bn_check_top(r);
	al=a->top;
	bl=b->top;
	r->neg=a->neg^b->neg;
	if ((al == 0) || (bl == 0))
		{
		BN_zero(r);
		return(1);
		}
	top=al+bl;
	if ((r == a) || (r == b))
		rr= &(ctx->bn[ctx->tos+1]);
	else
		rr=r;
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
	if (al == bl)
		{
#  ifdef BN_MUL_COMBA
  if (al == 8)
			{
			if (bn_wexpand(rr,16) == NULL) return(0);
			r->top=16;
			bn_mul_comba8(rr->d,a->d,b->d);
			goto end;
			}
		else
#  endif
#ifdef BN_RECURSION
		if (al < BN_MULL_SIZE_NORMAL)
#endif
			{
			if (bn_wexpand(rr,top) == NULL) return(0);
			rr->top=top;
			bn_mul_normal(rr->d,a->d,al,b->d,bl);
			goto end;
			}
#  ifdef BN_RECURSION
		goto symetric;
#  endif
		}
#endif
#ifdef BN_RECURSION
	else if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL))
		{
		if (bn_wexpand(rr,top) == NULL) return(0);
		rr->top=top;
		bn_mul_normal(rr->d,a->d,al,b->d,bl);
		goto end;
		}
	else
		{
		i=(al-bl);
		if ((i ==  1) && !BN_get_flags(b,BN_FLG_STATIC_DATA))
			{
			bn_wexpand(b,al);
			b->d[bl]=0;
			bl++;
			goto symetric;
			}
		else if ((i ==  -1) && !BN_get_flags(a,BN_FLG_STATIC_DATA))
			{
			bn_wexpand(a,bl);
			a->d[al]=0;
			al++;
			goto symetric;
			}
		}
#endif
	if (bn_wexpand(rr,top) == NULL) return(0);
	rr->top=top;
	bn_mul_normal(rr->d,a->d,al,b->d,bl);
#ifdef BN_RECURSION
	if (0)
		{
symetric:
		j=BN_num_bits_word((BN_ULONG)al);
		j=1<<(j-1);
		k=j+j;
		t= &(ctx->bn[ctx->tos]);
		if (al == j)
			{
			bn_wexpand(t,k*2);
			bn_wexpand(rr,k*2);
			bn_mul_recursive(rr->d,a->d,b->d,al,t->d);
			}
		else
			{
			bn_wexpand(a,k);
			bn_wexpand(b,k);
			bn_wexpand(t,k*4);
			bn_wexpand(rr,k*4);
			for (i=a->top; i<k; i++)
				a->d[i]=0;
			for (i=b->top; i<k; i++)
				b->d[i]=0;
			bn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);
			}
		rr->top=top;
		}
#endif
#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
end:
#endif
	bn_fix_top(rr);
	if (r != rr) BN_copy(r,rr);
	return(1);
	}
['int MAIN(int argc, char **argv)\n\t{\n\tDSA *dsa=NULL;\n\tint i,badops=0,text=0;\n\tBIO *in=NULL,*out=NULL;\n\tint informat,outformat,noout=0,C=0,ret=1;\n\tchar *infile,*outfile,*prog,*inrand=NULL;\n\tint numbits= -1,num,genkey=0;\n\tchar buffer[200],*randfile=NULL;\n\tapps_startup();\n\tif (bio_err == NULL)\n\t\tif ((bio_err=BIO_new(BIO_s_file())) != NULL)\n\t\t\tBIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);\n\tinfile=NULL;\n\toutfile=NULL;\n\tinformat=FORMAT_PEM;\n\toutformat=FORMAT_PEM;\n\tprog=argv[0];\n\targc--;\n\targv++;\n\twhile (argc >= 1)\n\t\t{\n\t\tif \t(strcmp(*argv,"-inform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tinformat=str2fmt(*(++argv));\n\t\t\t}\n\t\telse if (strcmp(*argv,"-outform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\toutformat=str2fmt(*(++argv));\n\t\t\t}\n\t\telse if (strcmp(*argv,"-in") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tinfile= *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-out") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\toutfile= *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-text") == 0)\n\t\t\ttext=1;\n\t\telse if (strcmp(*argv,"-C") == 0)\n\t\t\tC=1;\n\t\telse if (strcmp(*argv,"-genkey") == 0)\n\t\t\tgenkey=1;\n\t\telse if (strcmp(*argv,"-rand") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tinrand= *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-noout") == 0)\n\t\t\tnoout=1;\n\t\telse if (sscanf(*argv,"%d",&num) == 1)\n\t\t\t{\n\t\t\tnumbits=num;\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"unknown option %s\\n",*argv);\n\t\t\tbadops=1;\n\t\t\tbreak;\n\t\t\t}\n\t\targc--;\n\t\targv++;\n\t\t}\n\tif (badops)\n\t\t{\nbad:\n\t\tBIO_printf(bio_err,"%s [options] [bits] <infile >outfile\\n",prog);\n\t\tBIO_printf(bio_err,"where options are\\n");\n\t\tBIO_printf(bio_err," -inform arg   input format - one of DER TXT PEM\\n");\n\t\tBIO_printf(bio_err," -outform arg  output format - one of DER TXT PEM\\n");\n\t\tBIO_printf(bio_err," -in arg       input file\\n");\n\t\tBIO_printf(bio_err," -out arg      output file\\n");\n\t\tBIO_printf(bio_err," -text         check the DSA parameters\\n");\n\t\tBIO_printf(bio_err," -C            Output C code\\n");\n\t\tBIO_printf(bio_err," -noout        no output\\n");\n\t\tBIO_printf(bio_err," -rand         files to use for random number input\\n");\n\t\tBIO_printf(bio_err," number        number of bits to use for generating private key\\n");\n\t\tgoto end;\n\t\t}\n\tERR_load_crypto_strings();\n\tin=BIO_new(BIO_s_file());\n\tout=BIO_new(BIO_s_file());\n\tif ((in == NULL) || (out == NULL))\n\t\t{\n\t\tERR_print_errors(bio_err);\n\t\tgoto end;\n\t\t}\n\tif (infile == NULL)\n\t\tBIO_set_fp(in,stdin,BIO_NOCLOSE);\n\telse\n\t\t{\n\t\tif (BIO_read_filename(in,infile) <= 0)\n\t\t\t{\n\t\t\tperror(infile);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (outfile == NULL)\n\t\tBIO_set_fp(out,stdout,BIO_NOCLOSE);\n\telse\n\t\t{\n\t\tif (BIO_write_filename(out,outfile) <= 0)\n\t\t\t{\n\t\t\tperror(outfile);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (numbits > 0)\n\t\t{\n\t\trandfile=RAND_file_name(buffer,200);\n\t\tRAND_load_file(randfile,1024L*1024L);\n\t\tBIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\\n",num);\n\t        BIO_printf(bio_err,"This could take some time\\n");\n\t        dsa=DSA_generate_parameters(num,NULL,0,NULL,NULL,\n\t\t\tdsa_cb,(char *)bio_err);\n\t\t}\n\telse if\t(informat == FORMAT_ASN1)\n\t\tdsa=d2i_DSAparams_bio(in,NULL);\n\telse if (informat == FORMAT_PEM)\n\t\tdsa=PEM_read_bio_DSAparams(in,NULL,NULL);\n\telse\n\t\t{\n\t\tBIO_printf(bio_err,"bad input format specified\\n");\n\t\tgoto end;\n\t\t}\n\tif (dsa == NULL)\n\t\t{\n\t\tBIO_printf(bio_err,"unable to load DSA parameters\\n");\n\t\tERR_print_errors(bio_err);\n\t\tgoto end;\n\t\t}\n\tif (text)\n\t\t{\n\t\tDSAparams_print(out,dsa);\n\t\t}\n\tif (C)\n\t\t{\n\t\tunsigned char *data;\n\t\tint l,len,bits_p,bits_q,bits_g;\n\t\tlen=BN_num_bytes(dsa->p);\n\t\tbits_p=BN_num_bits(dsa->p);\n\t\tbits_q=BN_num_bits(dsa->q);\n\t\tbits_g=BN_num_bits(dsa->g);\n\t\tdata=(unsigned char *)Malloc(len+20);\n\t\tif (data == NULL)\n\t\t\t{\n\t\t\tperror("Malloc");\n\t\t\tgoto end;\n\t\t\t}\n\t\tl=BN_bn2bin(dsa->p,data);\n\t\tprintf("static unsigned char dsa%d_p[]={",bits_p);\n\t\tfor (i=0; i<l; i++)\n\t\t\t{\n\t\t\tif ((i%12) == 0) printf("\\n\\t");\n\t\t\tprintf("0x%02X,",data[i]);\n\t\t\t}\n\t\tprintf("\\n\\t};\\n");\n\t\tl=BN_bn2bin(dsa->q,data);\n\t\tprintf("static unsigned char dsa%d_q[]={",bits_p);\n\t\tfor (i=0; i<l; i++)\n\t\t\t{\n\t\t\tif ((i%12) == 0) printf("\\n\\t");\n\t\t\tprintf("0x%02X,",data[i]);\n\t\t\t}\n\t\tprintf("\\n\\t};\\n");\n\t\tl=BN_bn2bin(dsa->g,data);\n\t\tprintf("static unsigned char dsa%d_g[]={",bits_p);\n\t\tfor (i=0; i<l; i++)\n\t\t\t{\n\t\t\tif ((i%12) == 0) printf("\\n\\t");\n\t\t\tprintf("0x%02X,",data[i]);\n\t\t\t}\n\t\tprintf("\\n\\t};\\n\\n");\n\t\tprintf("DSA *get_dsa%d()\\n\\t{\\n",bits_p);\n\t\tprintf("\\tDSA *dsa;\\n\\n");\n\t\tprintf("\\tif ((dsa=DSA_new()) == NULL) return(NULL);\\n");\n\t\tprintf("\\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\\n",\n\t\t\tbits_p,bits_p);\n\t\tprintf("\\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\\n",\n\t\t\tbits_p,bits_p);\n\t\tprintf("\\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\\n",\n\t\t\tbits_p,bits_p);\n\t\tprintf("\\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\\n");\n\t\tprintf("\\t\\treturn(NULL);\\n");\n\t\tprintf("\\treturn(dsa);\\n\\t}\\n");\n\t\t}\n\tif (!noout)\n\t\t{\n\t\tif \t(outformat == FORMAT_ASN1)\n\t\t\ti=i2d_DSAparams_bio(out,dsa);\n\t\telse if (outformat == FORMAT_PEM)\n\t\t\ti=PEM_write_bio_DSAparams(out,dsa);\n\t\telse\t{\n\t\t\tBIO_printf(bio_err,"bad output format specified for outfile\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\tif (!i)\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"unable to write DSA paramaters\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (genkey)\n\t\t{\n\t\tDSA *dsakey;\n\t\tif ((dsakey=DSAparams_dup(dsa)) == NULL) goto end;\n\t\tif (!DSA_generate_key(dsakey)) goto end;\n\t\tif \t(outformat == FORMAT_ASN1)\n\t\t\ti=i2d_DSAPrivateKey_bio(out,dsakey);\n\t\telse if (outformat == FORMAT_PEM)\n\t\t\ti=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL);\n\t\telse\t{\n\t\t\tBIO_printf(bio_err,"bad output format specified for outfile\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\tDSA_free(dsakey);\n\t\t}\n\tret=0;\nend:\n\tif (in != NULL) BIO_free(in);\n\tif (out != NULL) BIO_free(out);\n\tif (dsa != NULL) DSA_free(dsa);\n\tEXIT(ret);\n\t}', 'DSA *DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len,\n\t     int *counter_ret, unsigned long *h_ret, void (*callback)(),\n\t     char *cb_arg)\n\t{\n\tint ok=0;\n\tunsigned char seed[SHA_DIGEST_LENGTH];\n\tunsigned char md[SHA_DIGEST_LENGTH];\n\tunsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];\n\tBIGNUM *r0,*W,*X,*c,*test;\n\tBIGNUM *g=NULL,*q=NULL,*p=NULL;\n\tBN_MONT_CTX *mont=NULL;\n\tint k,n=0,i,b,m=0;\n\tint counter=0;\n\tBN_CTX *ctx=NULL,*ctx2=NULL;\n\tunsigned int h=2;\n\tDSA *ret=NULL;\n\tif (bits < 512) bits=512;\n\tbits=(bits+63)/64*64;\n\tif ((seed_in != NULL) && (seed_len == 20))\n\t\tmemcpy(seed,seed_in,seed_len);\n\tif ((ctx=BN_CTX_new()) == NULL) goto err;\n\tif ((ctx2=BN_CTX_new()) == NULL) goto err;\n\tif ((ret=DSA_new()) == NULL) goto err;\n\tif ((mont=BN_MONT_CTX_new()) == NULL) goto err;\n\tr0= &(ctx2->bn[0]);\n\tg= &(ctx2->bn[1]);\n\tW= &(ctx2->bn[2]);\n\tq= &(ctx2->bn[3]);\n\tX= &(ctx2->bn[4]);\n\tc= &(ctx2->bn[5]);\n\tp= &(ctx2->bn[6]);\n\ttest= &(ctx2->bn[7]);\n\tBN_lshift(test,BN_value_one(),bits-1);\n\tfor (;;)\n\t\t{\n\t\tfor (;;)\n\t\t\t{\n\t\t\tif (callback != NULL) callback(0,m++,cb_arg);\n\t\t\tif (!seed_len)\n\t\t\t\tRAND_bytes(seed,SHA_DIGEST_LENGTH);\n\t\t\telse\n\t\t\t\tseed_len=0;\n\t\t\tmemcpy(buf,seed,SHA_DIGEST_LENGTH);\n\t\t\tmemcpy(buf2,seed,SHA_DIGEST_LENGTH);\n\t\t\tfor (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)\n\t\t\t\t{\n\t\t\t\tbuf[i]++;\n\t\t\t\tif (buf[i] != 0) break;\n\t\t\t\t}\n\t\t\tHASH(seed,SHA_DIGEST_LENGTH,md);\n\t\t\tHASH(buf,SHA_DIGEST_LENGTH,buf2);\n\t\t\tfor (i=0; i<SHA_DIGEST_LENGTH; i++)\n\t\t\t\tmd[i]^=buf2[i];\n\t\t\tmd[0]|=0x80;\n\t\t\tmd[SHA_DIGEST_LENGTH-1]|=0x01;\n\t\t\tif (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) abort();\n\t\t\tif (DSA_is_prime(q,callback,cb_arg) > 0) break;\n\t\t\t}\n\t\tif (callback != NULL) callback(2,0,cb_arg);\n\t\tif (callback != NULL) callback(3,0,cb_arg);\n\t\tcounter=0;\n\t\tn=(bits-1)/160;\n\t\tb=(bits-1)-n*160;\n\t\tfor (;;)\n\t\t\t{\n\t\t\tBN_zero(W);\n\t\t\tfor (k=0; k<=n; k++)\n\t\t\t\t{\n\t\t\t\tfor (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)\n\t\t\t\t\t{\n\t\t\t\t\tbuf[i]++;\n\t\t\t\t\tif (buf[i] != 0) break;\n\t\t\t\t\t}\n\t\t\t\tHASH(buf,SHA_DIGEST_LENGTH,md);\n\t\t\t\tif (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) abort();\n\t\t\t\tBN_lshift(r0,r0,160*k);\n\t\t\t\tBN_add(W,W,r0);\n\t\t\t\t}\n\t\t\tBN_mask_bits(W,bits-1);\n\t\t\tBN_copy(X,W);\n\t\t\tBN_add(X,X,test);\n\t\t\tBN_lshift1(r0,q);\n\t\t\tBN_mod(c,X,r0,ctx);\n\t\t\tBN_sub(r0,c,BN_value_one());\n\t\t\tBN_sub(p,X,r0);\n\t\t\tif (BN_cmp(p,test) >= 0)\n\t\t\t\t{\n\t\t\t\tif (DSA_is_prime(p,callback,cb_arg) > 0)\n\t\t\t\t\tgoto end;\n\t\t\t\t}\n\t\t\tcounter++;\n\t\t\tif (counter >= 4096) break;\n\t\t\tif (callback != NULL) callback(0,counter,cb_arg);\n\t\t\t}\n\t\t}\nend:\n\tif (callback != NULL) callback(2,1,cb_arg);\n        BN_sub(test,p,BN_value_one());\n        BN_div(r0,NULL,test,q,ctx);\n\tBN_set_word(test,h);\n\tBN_MONT_CTX_set(mont,p,ctx);\n\tfor (;;)\n\t\t{\n\t\tBN_mod_exp_mont(g,test,r0,p,ctx,mont);\n\t\tif (!BN_is_one(g)) break;\n\t\tBN_add(test,test,BN_value_one());\n\t\th++;\n\t\t}\n\tif (callback != NULL) callback(3,1,cb_arg);\n\tok=1;\nerr:\n\tif (!ok)\n\t\t{\n\t\tif (ret != NULL) DSA_free(ret);\n\t\t}\n\telse\n\t\t{\n\t\tret->p=BN_dup(p);\n\t\tret->q=BN_dup(q);\n\t\tret->g=BN_dup(g);\n\t\tif ((m > 1) && (seed_in != NULL)) memcpy(seed_in,seed,20);\n\t\tif (counter_ret != NULL) *counter_ret=counter;\n\t\tif (h_ret != NULL) *h_ret=h;\n\t\t}\n\tif (ctx != NULL) BN_CTX_free(ctx);\n\tif (ctx != NULL) BN_CTX_free(ctx2);\n\tif (mont != NULL) BN_MONT_CTX_free(mont);\n\treturn(ok?ret:NULL);\n\t}', 'int BN_mod_exp_mont(BIGNUM *rr, BIGNUM *a, const BIGNUM *p,\n\t\t    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)\n\t{\n\tint i,j,bits,ret=0,wstart,wend,window,wvalue;\n\tint start=1,ts=0;\n\tBIGNUM *d,*r;\n\tBIGNUM *aa;\n\tBIGNUM val[TABLE_SIZE];\n\tBN_MONT_CTX *mont=NULL;\n\tbn_check_top(a);\n\tbn_check_top(p);\n\tbn_check_top(m);\n\tif (!(m->d[0] & 1))\n\t\t{\n\t\tBNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS);\n\t\treturn(0);\n\t\t}\n\td= &(ctx->bn[ctx->tos++]);\n\tr= &(ctx->bn[ctx->tos++]);\n\tbits=BN_num_bits(p);\n\tif (bits == 0)\n\t\t{\n\t\tBN_one(r);\n\t\treturn(1);\n\t\t}\n#if 1\n\tif (in_mont != NULL)\n\t\tmont=in_mont;\n\telse\n#endif\n\t\t{\n\t\tif ((mont=BN_MONT_CTX_new()) == NULL) goto err;\n\t\tif (!BN_MONT_CTX_set(mont,m,ctx)) goto err;\n\t\t}\n\tBN_init(&val[0]);\n\tts=1;\n\tif (BN_ucmp(a,m) >= 0)\n\t\t{\n\t\tBN_mod(&(val[0]),a,m,ctx);\n\t\taa= &(val[0]);\n\t\t}\n\telse\n\t\taa=a;\n\tif (!BN_to_montgomery(&(val[0]),aa,mont,ctx)) goto err;\n\tif (!BN_mod_mul_montgomery(d,&(val[0]),&(val[0]),mont,ctx)) goto err;\n\tif (bits <= 20)\n\t\twindow=1;\n\telse if (bits >= 256)\n\t\twindow=5;\n\telse if (bits >= 128)\n\t\twindow=4;\n\telse\n\t\twindow=3;\n\tj=1<<(window-1);\n\tfor (i=1; i<j; i++)\n\t\t{\n\t\tBN_init(&(val[i]));\n\t\tif (!BN_mod_mul_montgomery(&(val[i]),&(val[i-1]),d,mont,ctx))\n\t\t\tgoto err;\n\t\t}\n\tts=i;\n\tstart=1;\n\twvalue=0;\n\twstart=bits-1;\n\twend=0;\n        if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;\n\tfor (;;)\n\t\t{\n\t\tif (BN_is_bit_set(p,wstart) == 0)\n\t\t\t{\n\t\t\tif (!start)\n\t\t\t\t{\n\t\t\t\tif (!BN_mod_mul_montgomery(r,r,r,mont,ctx))\n\t\t\t\tgoto err;\n\t\t\t\t}\n\t\t\tif (wstart == 0) break;\n\t\t\twstart--;\n\t\t\tcontinue;\n\t\t\t}\n\t\tj=wstart;\n\t\twvalue=1;\n\t\twend=0;\n\t\tfor (i=1; i<window; i++)\n\t\t\t{\n\t\t\tif (wstart-i < 0) break;\n\t\t\tif (BN_is_bit_set(p,wstart-i))\n\t\t\t\t{\n\t\t\t\twvalue<<=(i-wend);\n\t\t\t\twvalue|=1;\n\t\t\t\twend=i;\n\t\t\t\t}\n\t\t\t}\n\t\tj=wend+1;\n\t\tif (!start)\n\t\t\tfor (i=0; i<j; i++)\n\t\t\t\t{\n\t\t\t\tif (!BN_mod_mul_montgomery(r,r,r,mont,ctx))\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\tif (!BN_mod_mul_montgomery(r,r,&(val[wvalue>>1]),mont,ctx))\n\t\t\tgoto err;\n\t\twstart-=wend+1;\n\t\twvalue=0;\n\t\tstart=0;\n\t\tif (wstart < 0) break;\n\t\t}\n\tBN_from_montgomery(rr,r,mont,ctx);\n\tret=1;\nerr:\n\tif ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);\n\tctx->tos-=2;\n\tfor (i=0; i<ts; i++)\n\t\tBN_clear_free(&(val[i]));\n\treturn(ret);\n\t}', 'int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)\n\t{\n#if 0\n\tint i,nm,nd;\n\tBIGNUM *dv;\n\tif (BN_ucmp(m,d) < 0)\n\t\treturn((BN_copy(rem,m) == NULL)?0:1);\n\tdv= &(ctx->bn[ctx->tos]);\n\tif (!BN_copy(rem,m)) return(0);\n\tnm=BN_num_bits(rem);\n\tnd=BN_num_bits(d);\n\tif (!BN_lshift(dv,d,nm-nd)) return(0);\n\tfor (i=nm-nd; i>=0; i--)\n\t\t{\n\t\tif (BN_cmp(rem,dv) >= 0)\n\t\t\t{\n\t\t\tif (!BN_sub(rem,rem,dv)) return(0);\n\t\t\t}\n\t\tif (!BN_rshift1(dv,dv)) return(0);\n\t\t}\n\treturn(1);\n#else\n\treturn(BN_div(NULL,rem,m,d,ctx));\n#endif\n\t}', 'int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,\n\t   BN_CTX *ctx)\n\t{\n\tint norm_shift,i,j,loop;\n\tBIGNUM *tmp,wnum,*snum,*sdiv,*res;\n\tBN_ULONG *resp,*wnump;\n\tBN_ULONG d0,d1;\n\tint num_n,div_n;\n\tbn_check_top(num);\n\tbn_check_top(divisor);\n\tif (BN_is_zero(divisor))\n\t\t{\n\t\tBNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);\n\t\treturn(0);\n\t\t}\n\tif (BN_ucmp(num,divisor) < 0)\n\t\t{\n\t\tif (rm != NULL)\n\t\t\t{ if (BN_copy(rm,num) == NULL) return(0); }\n\t\tif (dv != NULL) BN_zero(dv);\n\t\treturn(1);\n\t\t}\n\ttmp= &(ctx->bn[ctx->tos]);\n\ttmp->neg=0;\n\tsnum= &(ctx->bn[ctx->tos+1]);\n\tsdiv= &(ctx->bn[ctx->tos+2]);\n\tif (dv == NULL)\n\t\tres= &(ctx->bn[ctx->tos+3]);\n\telse\tres=dv;\n\tnorm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2);\n\tBN_lshift(sdiv,divisor,norm_shift);\n\tsdiv->neg=0;\n\tnorm_shift+=BN_BITS2;\n\tBN_lshift(snum,num,norm_shift);\n\tsnum->neg=0;\n\tdiv_n=sdiv->top;\n\tnum_n=snum->top;\n\tloop=num_n-div_n;\n\tBN_init(&wnum);\n\twnum.d=\t &(snum->d[loop]);\n\twnum.top= div_n;\n\twnum.max= snum->max+1;\n\td0=sdiv->d[div_n-1];\n\td1=(div_n == 1)?0:sdiv->d[div_n-2];\n\twnump= &(snum->d[num_n-1]);\n\tres->neg= (num->neg^divisor->neg);\n\tif (!bn_wexpand(res,(loop+1))) goto err;\n\tres->top=loop;\n\tresp= &(res->d[loop-1]);\n\tif (!bn_wexpand(tmp,(div_n+1))) goto err;\n\tif (BN_ucmp(&wnum,sdiv) >= 0)\n\t\t{\n\t\tif (!BN_usub(&wnum,&wnum,sdiv)) goto err;\n\t\t*resp=1;\n\t\tres->d[res->top-1]=1;\n\t\t}\n\telse\n\t\tres->top--;\n\tresp--;\n\tfor (i=0; i<loop-1; i++)\n\t\t{\n\t\tBN_ULONG q,n0,n1;\n\t\tBN_ULONG l0;\n\t\twnum.d--; wnum.top++;\n\t\tn0=wnump[0];\n\t\tn1=wnump[-1];\n\t\tif (n0 == d0)\n\t\t\tq=BN_MASK2;\n\t\telse\n\t\t\tq=bn_div_words(n0,n1,d0);\n\t\t{\n#ifdef BN_LLONG\n\t\tBN_ULLONG t1,t2,rem;\n\t\tt1=((BN_ULLONG)n0<<BN_BITS2)|n1;\n\t\tfor (;;)\n\t\t\t{\n\t\t\tt2=(BN_ULLONG)d1*q;\n\t\t\trem=t1-(BN_ULLONG)q*d0;\n\t\t\tif ((rem>>BN_BITS2) ||\n\t\t\t\t(t2 <= ((BN_ULLONG)(rem<<BN_BITS2)+wnump[-2])))\n\t\t\t\tbreak;\n\t\t\tq--;\n\t\t\t}\n#else\n\t\tBN_ULONG t1l,t1h,t2l,t2h,t3l,t3h,ql,qh,t3t;\n\t\tt1h=n0;\n\t\tt1l=n1;\n\t\tfor (;;)\n\t\t\t{\n\t\t\tt2l=LBITS(d1); t2h=HBITS(d1);\n\t\t\tql =LBITS(q);  qh =HBITS(q);\n\t\t\tmul64(t2l,t2h,ql,qh);\n\t\t\tt3t=LBITS(d0); t3h=HBITS(d0);\n\t\t\tmul64(t3t,t3h,ql,qh);\n\t\t\tt3l=(t1l-t3t)&BN_MASK2;\n\t\t\tif (t3l > t1l) t3h++;\n\t\t\tt3h=(t1h-t3h)&BN_MASK2;\n\t\t\tif (t3h) break;\n\t\t\tif (t2h < t3l) break;\n\t\t\tif ((t2h == t3l) && (t2l <= wnump[-2])) break;\n\t\t\tq--;\n\t\t\t}\n#endif\n\t\t}\n\t\tl0=bn_mul_words(tmp->d,sdiv->d,div_n,q);\n\t\ttmp->d[div_n]=l0;\n\t\tfor (j=div_n+1; j>0; j--)\n\t\t\tif (tmp->d[j-1]) break;\n\t\ttmp->top=j;\n\t\tj=wnum.top;\n\t\tBN_sub(&wnum,&wnum,tmp);\n\t\tsnum->top=snum->top+wnum.top-j;\n\t\tif (wnum.neg)\n\t\t\t{\n\t\t\tq--;\n\t\t\tj=wnum.top;\n\t\t\tBN_add(&wnum,&wnum,sdiv);\n\t\t\tsnum->top+=wnum.top-j;\n\t\t\t}\n\t\t*(resp--)=q;\n\t\twnump--;\n\t\t}\n\tif (rm != NULL)\n\t\t{\n\t\tBN_rshift(rm,snum,norm_shift);\n\t\trm->neg=num->neg;\n\t\t}\n\treturn(1);\nerr:\n\treturn(0);\n\t}', 'int DSA_generate_key(DSA *dsa)\n\t{\n\tint ok=0;\n\tunsigned int i;\n\tBN_CTX *ctx=NULL;\n\tBIGNUM *pub_key=NULL,*priv_key=NULL;\n\tif ((ctx=BN_CTX_new()) == NULL) goto err;\n\tif (dsa->priv_key == NULL)\n\t\t{\n\t\tif ((priv_key=BN_new()) == NULL) goto err;\n\t\t}\n\telse\n\t\tpriv_key=dsa->priv_key;\n\ti=BN_num_bits(dsa->q);\n\tfor (;;)\n\t\t{\n\t\tBN_rand(priv_key,i,1,0);\n\t\tif (BN_cmp(priv_key,dsa->q) >= 0)\n\t\t\tBN_sub(priv_key,priv_key,dsa->q);\n\t\tif (!BN_is_zero(priv_key)) break;\n\t\t}\n\tif (dsa->pub_key == NULL)\n\t\t{\n\t\tif ((pub_key=BN_new()) == NULL) goto err;\n\t\t}\n\telse\n\t\tpub_key=dsa->pub_key;\n\tif (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err;\n\tdsa->priv_key=priv_key;\n\tdsa->pub_key=pub_key;\n\tok=1;\nerr:\n\tif ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);\n\tif ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);\n\tif (ctx != NULL) BN_CTX_free(ctx);\n\treturn(ok);\n\t}', 'int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m,\n\t       BN_CTX *ctx)\n\t{\n\tint ret;\n\tbn_check_top(a);\n\tbn_check_top(p);\n\tbn_check_top(m);\n#ifdef MONT_MUL_MOD\n\tif (BN_is_odd(m))\n\t\t{ ret=BN_mod_exp_mont(r,a,p,m,ctx,NULL); }\n\telse\n#endif\n#ifdef RECP_MUL_MOD\n\t\t{ ret=BN_mod_exp_recp(r,a,p,m,ctx); }\n#else\n\t\t{ ret=BN_mod_exp_simple(r,a,p,m,ctx); }\n#endif\n\treturn(ret);\n\t}', 'int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,\n\t\t    const BIGNUM *m, BN_CTX *ctx)\n\t{\n\tint i,j,bits,ret=0,wstart,wend,window,wvalue;\n\tint start=1,ts=0;\n\tBIGNUM *aa;\n\tBIGNUM val[TABLE_SIZE];\n\tBN_RECP_CTX recp;\n\taa= &(ctx->bn[ctx->tos++]);\n\tbits=BN_num_bits(p);\n\tif (bits == 0)\n\t\t{\n\t\tBN_one(r);\n\t\treturn(1);\n\t\t}\n\tBN_RECP_CTX_init(&recp);\n\tif (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;\n\tBN_init(&(val[0]));\n\tts=1;\n\tif (!BN_mod(&(val[0]),a,m,ctx)) goto err;\n\tif (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))\n\t\tgoto err;\n\tif (bits <= 17)\n\t\twindow=1;\n\telse if (bits >= 256)\n\t\twindow=5;\n\telse if (bits >= 128)\n\t\twindow=4;\n\telse\n\t\twindow=3;\n\tj=1<<(window-1);\n\tfor (i=1; i<j; i++)\n\t\t{\n\t\tBN_init(&val[i]);\n\t\tif (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))\n\t\t\tgoto err;\n\t\t}\n\tts=i;\n\tstart=1;\n\twvalue=0;\n\twstart=bits-1;\n\twend=0;\n\tif (!BN_one(r)) goto err;\n\tfor (;;)\n\t\t{\n\t\tif (BN_is_bit_set(p,wstart) == 0)\n\t\t\t{\n\t\t\tif (!start)\n\t\t\t\tif (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))\n\t\t\t\tgoto err;\n\t\t\tif (wstart == 0) break;\n\t\t\twstart--;\n\t\t\tcontinue;\n\t\t\t}\n\t\tj=wstart;\n\t\twvalue=1;\n\t\twend=0;\n\t\tfor (i=1; i<window; i++)\n\t\t\t{\n\t\t\tif (wstart-i < 0) break;\n\t\t\tif (BN_is_bit_set(p,wstart-i))\n\t\t\t\t{\n\t\t\t\twvalue<<=(i-wend);\n\t\t\t\twvalue|=1;\n\t\t\t\twend=i;\n\t\t\t\t}\n\t\t\t}\n\t\tj=wend+1;\n\t\tif (!start)\n\t\t\tfor (i=0; i<j; i++)\n\t\t\t\t{\n\t\t\t\tif (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\tif (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))\n\t\t\tgoto err;\n\t\twstart-=wend+1;\n\t\twvalue=0;\n\t\tstart=0;\n\t\tif (wstart < 0) break;\n\t\t}\n\tret=1;\nerr:\n\tctx->tos--;\n\tfor (i=0; i<ts; i++)\n\t\tBN_clear_free(&(val[i]));\n\tBN_RECP_CTX_free(&recp);\n\treturn(ret);\n\t}', 'int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)\n\t{\n\tBN_copy(&(recp->N),d);\n\tBN_zero(&(recp->Nr));\n\trecp->num_bits=BN_num_bits(d);\n\trecp->shift=0;\n\treturn(1);\n\t}', 'BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)\n\t{\n\tint i;\n\tBN_ULONG *A;\n\tconst BN_ULONG *B;\n\tbn_check_top(b);\n\tif (a == b) return(a);\n\tif (bn_wexpand(a,b->top) == NULL) return(NULL);\n#if 1\n\tA=a->d;\n\tB=b->d;\n\tfor (i=b->top>>2; i>0; i--,A+=4,B+=4)\n\t\t{\n\t\tBN_ULONG a0,a1,a2,a3;\n\t\ta0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];\n\t\tA[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;\n\t\t}\n\tswitch (b->top&3)\n\t\t{\n\t\tcase 3: A[2]=B[2];\n\t\tcase 2: A[1]=B[1];\n\t\tcase 1: A[0]=B[0];\n\t\tcase 0: ;\n\t\t}\n#else\n\tmemcpy(a->d,b->d,sizeof(b->d[0])*b->top);\n#endif\n\ta->top=b->top;\n\tif ((a->top == 0) && (a->d != NULL))\n\t\ta->d[0]=0;\n\ta->neg=b->neg;\n\treturn(a);\n\t}', 'int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BN_RECP_CTX *recp,\n\t     BN_CTX *ctx)\n\t{\n\tint ret=0;\n\tBIGNUM *a;\n\ta= &(ctx->bn[ctx->tos++]);\n\tif (y != NULL)\n\t\t{\n\t\tif (x == y)\n\t\t\t{ if (!BN_sqr(a,x,ctx)) goto err; }\n\t\telse\n\t\t\t{ if (!BN_mul(a,x,y,ctx)) goto err; }\n\t\t}\n\telse\n\t\ta=x;\n\tBN_div_recp(NULL,r,a,recp,ctx);\n\tret=1;\nerr:\n\tctx->tos--;\n\treturn(ret);\n\t}', 'int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BN_RECP_CTX *recp,\n\t     BN_CTX *ctx)\n\t{\n\tint i,j,tos,ret=0,ex;\n\tBIGNUM *a,*b,*d,*r;\n\ttos=ctx->tos;\n\ta= &(ctx->bn[ctx->tos++]);\n\tb= &(ctx->bn[ctx->tos++]);\n\tif (dv != NULL)\n\t\td=dv;\n\telse\n\t\td= &(ctx->bn[ctx->tos++]);\n\tif (rem != NULL)\n\t\tr=rem;\n\telse\n\t\tr= &(ctx->bn[ctx->tos++]);\n\tif (BN_ucmp(m,&(recp->N)) < 0)\n\t\t{\n\t\tBN_zero(d);\n\t\tBN_copy(r,m);\n\t\tctx->tos=tos;\n\t\treturn(1);\n\t\t}\n\ti=BN_num_bits(m);\n\tj=recp->num_bits*2;\n\tif (j > i)\n\t\t{\n\t\ti=j;\n\t\tex=0;\n\t\t}\n\telse\n\t\t{\n\t\tex=(i-j)/2;\n\t\t}\n\tj=i/2;\n\tif (i != recp->shift)\n\t\trecp->shift=BN_reciprocal(&(recp->Nr),&(recp->N),\n\t\t\ti,ctx);\n\tif (!BN_rshift(a,m,j-ex)) goto err;\n\tif (!BN_mul(b,a,&(recp->Nr),ctx)) goto err;\n\tif (!BN_rshift(d,b,j+ex)) goto err;\n\td->neg=0;\n\tif (!BN_mul(b,&(recp->N),d,ctx)) goto err;\n\tif (!BN_usub(r,m,b)) goto err;\n\tr->neg=0;\n\tj=0;\n#if 1\n\twhile (BN_ucmp(r,&(recp->N)) >= 0)\n\t\t{\n\t\tif (j++ > 2)\n\t\t\t{\n\t\t\tBNerr(BN_F_BN_MOD_MUL_RECIPROCAL,BN_R_BAD_RECIPROCAL);\n\t\t\tgoto err;\n\t\t\t}\n\t\tif (!BN_usub(r,r,&(recp->N))) goto err;\n\t\tif (!BN_add_word(d,1)) goto err;\n\t\t}\n#endif\n\tr->neg=BN_is_zero(r)?0:m->neg;\n\td->neg=m->neg^recp->N.neg;\n\tret=1;\nerr:\n\tctx->tos=tos;\n\treturn(ret);\n\t}', 'int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx)\n\t{\n\tint top,al,bl;\n\tBIGNUM *rr;\n#ifdef BN_RECURSION\n\tBIGNUM *t;\n\tint i,j,k;\n#endif\n#ifdef BN_COUNT\nprintf("BN_mul %d * %d\\n",a->top,b->top);\n#endif\n\tbn_check_top(a);\n\tbn_check_top(b);\n\tbn_check_top(r);\n\tal=a->top;\n\tbl=b->top;\n\tr->neg=a->neg^b->neg;\n\tif ((al == 0) || (bl == 0))\n\t\t{\n\t\tBN_zero(r);\n\t\treturn(1);\n\t\t}\n\ttop=al+bl;\n\tif ((r == a) || (r == b))\n\t\trr= &(ctx->bn[ctx->tos+1]);\n\telse\n\t\trr=r;\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\n\tif (al == bl)\n\t\t{\n#  ifdef BN_MUL_COMBA\n  if (al == 8)\n\t\t\t{\n\t\t\tif (bn_wexpand(rr,16) == NULL) return(0);\n\t\t\tr->top=16;\n\t\t\tbn_mul_comba8(rr->d,a->d,b->d);\n\t\t\tgoto end;\n\t\t\t}\n\t\telse\n#  endif\n#ifdef BN_RECURSION\n\t\tif (al < BN_MULL_SIZE_NORMAL)\n#endif\n\t\t\t{\n\t\t\tif (bn_wexpand(rr,top) == NULL) return(0);\n\t\t\trr->top=top;\n\t\t\tbn_mul_normal(rr->d,a->d,al,b->d,bl);\n\t\t\tgoto end;\n\t\t\t}\n#  ifdef BN_RECURSION\n\t\tgoto symetric;\n#  endif\n\t\t}\n#endif\n#ifdef BN_RECURSION\n\telse if ((al < BN_MULL_SIZE_NORMAL) || (bl < BN_MULL_SIZE_NORMAL))\n\t\t{\n\t\tif (bn_wexpand(rr,top) == NULL) return(0);\n\t\trr->top=top;\n\t\tbn_mul_normal(rr->d,a->d,al,b->d,bl);\n\t\tgoto end;\n\t\t}\n\telse\n\t\t{\n\t\ti=(al-bl);\n\t\tif ((i ==  1) && !BN_get_flags(b,BN_FLG_STATIC_DATA))\n\t\t\t{\n\t\t\tbn_wexpand(b,al);\n\t\t\tb->d[bl]=0;\n\t\t\tbl++;\n\t\t\tgoto symetric;\n\t\t\t}\n\t\telse if ((i ==  -1) && !BN_get_flags(a,BN_FLG_STATIC_DATA))\n\t\t\t{\n\t\t\tbn_wexpand(a,bl);\n\t\t\ta->d[al]=0;\n\t\t\tal++;\n\t\t\tgoto symetric;\n\t\t\t}\n\t\t}\n#endif\n\tif (bn_wexpand(rr,top) == NULL) return(0);\n\trr->top=top;\n\tbn_mul_normal(rr->d,a->d,al,b->d,bl);\n#ifdef BN_RECURSION\n\tif (0)\n\t\t{\nsymetric:\n\t\tj=BN_num_bits_word((BN_ULONG)al);\n\t\tj=1<<(j-1);\n\t\tk=j+j;\n\t\tt= &(ctx->bn[ctx->tos]);\n\t\tif (al == j)\n\t\t\t{\n\t\t\tbn_wexpand(t,k*2);\n\t\t\tbn_wexpand(rr,k*2);\n\t\t\tbn_mul_recursive(rr->d,a->d,b->d,al,t->d);\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tbn_wexpand(a,k);\n\t\t\tbn_wexpand(b,k);\n\t\t\tbn_wexpand(t,k*4);\n\t\t\tbn_wexpand(rr,k*4);\n\t\t\tfor (i=a->top; i<k; i++)\n\t\t\t\ta->d[i]=0;\n\t\t\tfor (i=b->top; i<k; i++)\n\t\t\t\tb->d[i]=0;\n\t\t\tbn_mul_part_recursive(rr->d,a->d,b->d,al-j,j,t->d);\n\t\t\t}\n\t\trr->top=top;\n\t\t}\n#endif\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\nend:\n#endif\n\tbn_fix_top(rr);\n\tif (r != rr) BN_copy(r,rr);\n\treturn(1);\n\t}']