if (!BN_mul(T,D,X,ctx)) goto err; if (!BN_add(T,T,Y)) goto err; M=Y;
if (!BN_mul(tmp,D,X,ctx)) goto err; if (!BN_add(tmp,tmp,Y)) goto err; M=Y;
BIGNUM *BN_mod_inverse(BIGNUM *in,	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)	{	BIGNUM *A,*B,*X,*Y,*M,*D,*R=NULL;	BIGNUM *T,*ret=NULL;	int sign;	bn_check_top(a);	bn_check_top(n);	BN_CTX_start(ctx);	A = BN_CTX_get(ctx);	B = BN_CTX_get(ctx);	X = BN_CTX_get(ctx);	D = BN_CTX_get(ctx);	M = BN_CTX_get(ctx);	Y = BN_CTX_get(ctx);	if (Y == NULL) goto err;	if (in == NULL)		R=BN_new();	else		R=in;	if (R == NULL) goto err;	BN_zero(X);	BN_one(Y);	if (BN_copy(A,a) == NULL) goto err;	if (BN_copy(B,n) == NULL) goto err;	sign=1;	while (!BN_is_zero(B))		{		if (!BN_div(D,M,A,B,ctx)) goto err;		T=A;		A=B;		B=M;		/* T has a struct, M does not */		if (!BN_mul(T,D,X,ctx)) goto err;		if (!BN_add(T,T,Y)) goto err;		M=Y;		Y=X;		X=T;		sign= -sign;		}	if (sign < 0)		{		if (!BN_sub(Y,n,Y)) goto err;		}	if (BN_is_one(A))		{ if (!BN_mod(R,Y,n,ctx)) goto err; }	else		{		BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);		goto err;		}	ret=R;err:	if ((ret == NULL) && (in == NULL)) BN_free(R);	BN_CTX_end(ctx);	return(ret);	}