Ejemplo n.º 1
0
/**
\brief 有限域Fp上多项式在Fp中的根(不含重数)
\param f Fp[x]中多项式
\param p 阶数
\return 根的集合
\note 利用因子分解算法求解
*/
void UniZpRootZp(std::vector<mpz_ptr> & rootlist,const poly_z & f,mpz_ptr p)
{
    resize_z_list(rootlist,0);
    poly_z h0,h;
    h0.resize(2);
    mpz_set_ui(h0[0],0);
    mpz_set_ui(h0[1],1);
    copy_poly_z(h,h0);

    PowerMod(h,p,f,p);

    mpz_sub_ui(h[1],h[1],1);
    UniGcdZp(h0,h,f,p);
    if(h0.size()==1)
    {
        h0.resize(0);
        h.resize(0);
        return ;
    }
    std::vector<poly_z> faclist;
    UniEqlDegFacZp(faclist,h0,p,1);
    for(uint i=0; i<faclist.size(); i++)
    {
        resize_z_list(rootlist,i+1);
        mpz_neg(rootlist[i],faclist[i][0]);
    }
    clear_poly_z_list(faclist);
    h0.resize(0);
    h.resize(0);
    std::sort(rootlist.begin(),rootlist.end(),mpz_ptr_less);
    return ;
}
Ejemplo n.º 2
0
//todo using iterated frobenius alg. to improve it?
void UniEqlDegFacZp_Odd(poly_z & factor,const poly_z & f,mpz_ptr p,uint d)
{
	uint deg_bound=f.size()-2;
	poly_z a;
	while(1)
	{
		UniRandomZp(a,deg_bound,p);
		if(a.size()>1)break;
	}
	UniGcdZp(factor,a,f,p);
	if(factor.size()>1&&factor.size()<f.size())
	{
		a.resize(0);
		return ;
	}

	power_specially_for_eqldegfactorization(a,f,p,d);

	//static mpz_t exp;
	//mpz_init(exp);
	//mpz_pow_ui(exp,p,d);
	//mpz_sub_ui(exp,exp,1);
	//mpz_divexact_ui(exp,exp,2);
	//PowerMod(a,exp,f,p);
	//mpz_clear(exp);

	mpz_sub_ui(a[0],a[0],1);
	UniGcdZp(factor,a,f,p);
	if(factor.size()>1&&factor.size()<f.size())
	{
		a.resize(0);
		return; 
	}
	a.resize(0);
	factor.resize(0);
	return ;
}
Ejemplo n.º 3
0
Archivo: unigcd.cpp Proyecto: AnZhg/mU
/** 
\brief 整系数多项式最大公因子.
\param f,g 整系数本原多项式,且\f$\deg f=n\ge\deg g\ge 1\f$.
\param r 最大公因子.
\note 小素数模方法.
\todo 理论文档此处有误.
*/
void UniGcdZ_SmallPrime1(poly_z & r,const poly_z & f,const poly_z & g)
{
	poly_z fp,gp,vp,v1;
	poly_z fstar,gstar;
	mpz_t c,s,t;
	mpz_init(c);mpz_init(s);mpz_init(t);
	mpz_t A,b,B,z_temp,k,p_bound,p,p_low_bound,p1,B2;
	mpf_t float_temp;
	mpz_init(A);mpz_init(b);mpz_init(B);mpz_init(z_temp);mpz_init(k);mpz_init(p_bound);mpz_init(p);mpz_init(p1);mpz_init(p_low_bound);mpf_init(float_temp);mpz_init(B2);
	UniMaxNormZ(A,f);UniMaxNormZ(b,g);
	int n=f.size()-1,m=g.size()-1;
	if(mpz_cmp(A,b)<0)mpz_set(A,b);
	mpz_gcd(b,f[n],g[m]);
	mpz_ui_pow_ui(B,2,n);
	mpz_mul(B,B,A);
	mpz_mul(B,B,b);
	mpf_sqrt_ui(float_temp,n+1);
	mpz_set_f(z_temp,float_temp);
	mpz_mul(B,B,z_temp);
	mpz_mul_ui(B2,B,2);
	mpz_set_si(z_temp,n);
	int tempint;
	tempint=2*n*mpz_sizeinbase(z_temp,2)+2*mpz_sizeinbase(b,2)+4*n*mpz_sizeinbase(A,2);
	//tempint=2*n*Modules::NumberTheory::IntegerLength(Z(n),2)+2*Modules::NumberTheory::IntegerLength(b,2)+4*n*Modules::NumberTheory::IntegerLength(A,2);
	mpz_set_si(k,tempint);
	mpz_mul_ui(p_bound,k,2);
	mpz_mul_ui(p_bound,p_bound,mpz_sizeinbase(k,2));
	mpz_set_ui(p_low_bound,3);
	fstar.resize(n+1);
	for(size_t i=0;i<=n;i++)
	{
		mpz_mul(fstar[i],f[i],b);
	}
	gstar.resize(m+1);
	for(size_t i=0;i<=m;i++)
	{
		mpz_mul(gstar[i],g[i],b);
	}
	while(1)
	{
		while(1)
		{
			random::randominteger(p,p_low_bound,p_bound);
			if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
		}
		UniPolynomialMod(fp,f,p);
		UniPolynomialMod(gp,g,p);
		UniGcdZp(vp,fp,gp,p);
		if(vp.size()==1)
		{
			r.resize(1);
			mpz_set_si(r[0],1);
			fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
			fstar.resize(0);gstar.resize(0);
			mpz_clear(c);mpz_clear(s);mpz_clear(t);
			mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
			return ;
		}
		mpz_set(p1,p);
		copy_poly_z(v1,vp);
		while(mpz_cmp(p1,B2)<0)
		{
			while(1)
			{
				random::randominteger(p,p_low_bound,p_bound);
				if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
			}
			UniPolynomialMod(fp,f,p);
			UniPolynomialMod(gp,g,p);
			UniGcdZp(vp,fp,gp,p);
			if(vp.size()==1)
			{
				r.resize(1);
				mpz_set_si(r[0],1);
				fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
				fstar.resize(0);gstar.resize(0);
				mpz_clear(c);mpz_clear(s);mpz_clear(t);
				mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
				return ;
			}
			if(vp.size()<v1.size())
			{
				mpz_set(p1,p);
				copy_poly_z(v1,vp);
				continue;
			}
			if(vp.size()==v1.size())
			{
				mpz_gcdext(c,s,t,p1,p);
				mpz_mul(t,p,t);
				mpz_mul(s,p1,s);
				mpz_mul(p1,p1,p);
				for(size_t i=0;i<vp.size();i++)
				{
					mpz_mul(c,v1[i],t);
					mpz_addmul(c,vp[i],s);
					mpz_set(v1[i],c);
				}
				UniPolynomialMod(v1,v1,p1);
			}
		}
		for(size_t i=0;i<v1.size();i++)mpz_mul(v1[i],v1[i],b);
		UniPolynomialMod(v1,v1,p1);
		if(poly_z_divisible(fstar,v1)&&poly_z_divisible(gstar,v1))
		{
			UniPPZ(r,v1);break;
		}
	}
	fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
	fstar.resize(0);gstar.resize(0);
	mpz_clear(c);mpz_clear(s);mpz_clear(t);
	mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
	return ;
}
Ejemplo n.º 4
0
//f and g should normalized first
void MultiGcdZp_Dense_Interpolation(sparse_z & r,const sparse_z & f, const sparse_z & g,uint n, mpz_ptr p)
{
	if(n==1)// problem of univariate polynomials
	{
		poly_z ff,gg,rr;
		sparse_z_to_poly_z(ff,f);
		sparse_z_to_poly_z(gg,g);
		UniGcdZp(rr,ff,gg,p);
		poly_z_to_sparse_z(r,rr,1,0);
		ff.resize(0);gg.resize(0);rr.resize(0);
		return ;
	}
	poly_z contf,contg,poly_temp,a,b;
	sparse_z _f,_g,sparse_temp;
	cont_in_last_zp(contf,f,p);
	cont_in_last_zp(contg,g,p);
	UniGcdZp(a,contf,contg,p);
	poly_z_to_sparse_z(sparse_temp,contf,n,n-1);
	MultiDivExactZp(_f,f,sparse_temp,p);
	poly_z_to_sparse_z(sparse_temp,contg,n,n-1);
	MultiDivExactZp(_g,g,sparse_temp,p);
	lc_in_last_zp(contf,_f,p);
	lc_in_last_zp(contg,_g,p);
	UniGcdZp(b,contf,contg,p);
	sparse_z q,h,fv,gv,hv;
	poly_z q_one_v;
	sparse_z h_temp;
	uint m,m1,size;
	mpz_t v,bv,inverse;
	q.resize(1);mpz_set_ui(q[0].coe,1);q[0].exponents.resize(n,0);
	q_one_v.resize(1);mpz_set_ui(q_one_v[0],1);
	h.resize(1);mpz_set_ui(h[0].coe,1);h[0].exponents.resize(n,0);
	m=std::min<uint>(_f.deg(0),_g.deg(0))+1;
	mpz_init(v);mpz_init(bv);mpz_init(inverse);
	mpz_set_si(v,-1);
	while(1)
	{
		mpz_add_ui(v,v,1);
		if(mpz_cmp(v,p)==0)
		{
			r.resize(0);
			break;
		}
		UniEvalZp(bv,b,v,p);
		if(mpz_cmp_ui(bv,0)==0)continue;
		eval_in_last_zp(fv,_f,v,p);
		eval_in_last_zp(gv,_g,v,p);
		MultiGcdZp_Dense_Interpolation(hv,fv,gv,n-1,p);
		if(hv.size()==0)
		{
			r.resize(0);
			break;
		}
		m1=hv.deg(0);
		size=hv.size();
		if(m1>m)continue;
		//正则化
		mpz_set(inverse,hv[size-1].coe);
		mpz_invert(inverse,inverse,p);
		for(uint i=0;i<size;++i)
		{
			mpz_mul(hv[i].coe,hv[i].coe,inverse);
			mpz_mul(hv[i].coe,hv[i].coe,bv);
		}
		MultiPolynomialMod(hv,hv,p);
		if(m1<m)
		{
			//q=x_n-v
			q.resize(2);
			mpz_neg(q[0].coe,v);q[0].exponents.resize(n);
			for(uint i=0;i<n;++i)q[0].exponents[i]=0;
			mpz_set_ui(q[1].coe,1);q[1].exponents.resize(n);
			for(uint i=0;i<n;++i)q[1].exponents[i]=0;
			q[1].exponents[n-1]=1;
			q_one_v.resize(2);
			mpz_neg(q_one_v[0],v);mpz_set_ui(q_one_v[1],1);
			//h=hv
			h.resize(hv.size());
			for(uint i=0;i<hv.size();++i)
			{
				mpz_set(h[i].coe,hv[i].coe);
				h[i].exponents=hv[i].exponents;
				h[i].exponents.push_back(0);
			}
			m=m1;
			continue;
		}
		//modification of h
		eval_in_last_zp(h_temp,h,v,p);
		size=hv.size();
		for(uint i=0;i<size;++i)hv[i].exponents.push_back(0);
		size=h_temp.size();
		for(uint i=0;i<size;++i)h_temp[i].exponents.push_back(0);
		MultiSubZ(h_temp,hv,h_temp);
		MultiPolynomialMod(sparse_temp,h_temp,p);
		MultiMulZ(h_temp,sparse_temp,q);
		MultiPolynomialMod(h_temp,h_temp,p);
		UniEvalZp(inverse,q_one_v,v,p);
		mpz_invert(inverse,inverse,p);
		MultiMulZ(h_temp,h_temp,inverse);
		MultiPolynomialMod(h_temp,h_temp,p);
		MultiAddZ(h,h,h_temp);
		MultiPolynomialMod(h,h,p);
		//modification of q
		sparse_temp.resize(2);
		mpz_neg(sparse_temp[0].coe,v);sparse_temp[0].exponents.resize(n);
		for(uint i=0;i<n;++i)sparse_temp[0].exponents[i]=0;
		mpz_set_ui(sparse_temp[1].coe,1);sparse_temp[1].exponents.resize(n);
		for(uint i=0;i<n;++i)sparse_temp[1].exponents[i]=0;
		sparse_temp[1].exponents[n-1]=1;
		MultiMulZ(h_temp,q,sparse_temp);
		MultiPolynomialMod(q,h_temp,p);
		contf.resize(2);
		mpz_neg(contf[0],v);mpz_set_ui(contf[1],1);
		UniMulZ(contg,contf,q_one_v);
		UniPolynomialMod(q_one_v,contg,p);
		//criteria
		lc_in_last_zp(poly_temp,h,p);
		UniSubZ(poly_temp,poly_temp,b);
		UniPolynomialMod(poly_temp,poly_temp,p);
		if(m==0)
		{
			poly_z_to_sparse_z(r,a,n,n-1);
			return ;
		}
		if(poly_temp.size()==0)
		{
			pp_in_last_zp(h_temp,h,p);
			if(MultiDivisibleZp(_f,h_temp,p)&&MultiDivisibleZp(_g,h_temp,p))
			{
				poly_z_to_sparse_z(sparse_temp,a,n,n-1);
				MultiMulZ(r,sparse_temp,h_temp);
				MultiPolynomialMod(r,r,p);
				return ;
			}
		}
	}
	contf.resize(0);contg.resize(0);poly_temp.resize(0);a.resize(0);b.resize(0);
	_f.resize(0);_g.resize(0);sparse_temp.resize(0);
	q.resize(0);h.resize(0);fv.resize(0);gv.resize(0);hv.resize(0);
	q_one_v.resize(0);
	h_temp.resize(0);
	mpz_clear(v);mpz_clear(bv);mpz_clear(inverse);
	return ;
}