int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
	DSA_SIG *sig, EC_KEY *ec)
	{
	BN_CTX *ctx=BN_CTX_new();
	const EC_GROUP *group = EC_KEY_get0_group(ec);
	BIGNUM *order;
	BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL;
	BIGNUM *X=NULL,*tmp=NULL;
	EC_POINT *C = NULL;
	const EC_POINT *pub_key=NULL;
	int ok=0;

	BN_CTX_start(ctx);
	order = BN_CTX_get(ctx);
	e = BN_CTX_get(ctx);
	z1 = BN_CTX_get(ctx);
	z2 = BN_CTX_get(ctx);
	tmp = BN_CTX_get(ctx);
	X= BN_CTX_get(ctx);	
	R=BN_CTX_get(ctx);
	v=BN_CTX_get(ctx);
	
	EC_GROUP_get_order(group,order,ctx);
	pub_key = EC_KEY_get0_public_key(ec);
	if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
		(BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1)) 
		{
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
		goto err;

		}
	md = hashsum2bn(dgst);

	BN_mod(e,md,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"digest as bignum: ");
	BN_print_fp(stderr,md);
	fprintf(stderr,"\ndigest mod q: ");
	BN_print_fp(stderr,e);
#endif	
	if (BN_is_zero(e)) BN_one(e);
	v=BN_mod_inverse(v,e,order,ctx);
	BN_mod_mul(z1,sig->s,v,order,ctx);
	BN_sub(tmp,order,sig->r);
	BN_mod_mul(z2,tmp,v,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"\nInverted digest value: ");
	BN_print_fp(stderr,v);
	fprintf(stderr,"\nz1: ");
	BN_print_fp(stderr,z1);
	fprintf(stderr,"\nz2: ");
	BN_print_fp(stderr,z2);
#endif	
	C = EC_POINT_new(group);
	if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) 
		{	
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
		goto err;
		}	
	if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) 
		{
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
		goto err;
		}
	BN_mod(R,X,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"\nX=");
	BN_print_fp(stderr,X);
	fprintf(stderr,"\nX mod q=");
	BN_print_fp(stderr,R);
	fprintf(stderr,"\n");
#endif	
	if (BN_cmp(R,sig->r)!=0)
		{
		GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
		}
	else
		{
		ok = 1;
		}
	err:
	EC_POINT_free(C);
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	BN_free(md);
	return ok;
	}