Esempio n. 1
0
void force(ZZn& x,ZZn& y,ZZn& z,ECn& A)
{  // A=(x,y,z)
    copy(getbig(x),A.get_point()->X);
    copy(getbig(y),A.get_point()->Y);
    copy(getbig(z),A.get_point()->Z);
    A.get_point()->marker=MR_EPOINT_GENERAL;
}
Esempio n. 2
0
void endomorph(ECn &A,ZZn &Beta)
{ // apply endomorphism (x,y) = (Beta*x,y) where Beta is cube root of unity
	ZZn x;
	x=(A.get_point())->X;
	x*=Beta;
	copy(getbig(x),(A.get_point())->X);
}
Esempio n. 3
0
void reduce(const Poly2& p,Poly2Mod& rem)
{
    int m,d;
    GF2m t;
    big *G;
    term2 *ptr,*pos=NULL;
    int n=degree(p);
    int degm=degree(Modulus);

    if (n-degm < KARAT_BREAK_EVEN)
    {
        rem=(Poly2Mod)p;
        return;
    }

    G=(big *)mr_alloc(2*(N+2),sizeof(big));
    
    ptr=p.start;
    while (ptr!=NULL)
    {
        G[ptr->n]=getbig(ptr->an);
        ptr=ptr->next;
    }

    karmul2_poly(N,T,GRF,&G[N],W);   // W=(G/x^n) * h

    for (d=N-1;d<2*N;d++) copy(W[d],Q[d-N+1]);
    m=N+1; if(m%2==1) m=N+2;   // make sure m is even - pad if necessary

    for (d=m;d<2*m;d++) copy(G[d],W[d]);
   
    karmul2_poly_upper(m,T,GF,Q,W);

    pos=NULL;
    rem.clear();
    for (d=N-1;d>=0;d--)
    {
        add2(W[d],G[d],W[d]);
        t=W[d];
        if (t.iszero()) continue;
        pos=rem.addterm(t,d,pos);
    }
    
    mr_free(G);
}
Esempio n. 4
0
void force(ZZn& x,ZZn& y,ECn& A)
{ // A=(x,y)
    copy(getbig(x),A.get_point()->X);
    copy(getbig(y),A.get_point()->Y);
    A.get_point()->marker=MR_EPOINT_NORMALIZED;
}
Esempio n. 5
0
void setmod(const Poly2& p) 
{ 
    int i,n,m;
    Poly2 h;
    term2 *ptr;
    Modulus=p;

    n=degree(p);
    if (n<KARAT_BREAK_EVEN) return;
    h=reverse(p);
    h=invmodxn(h,n);
    h=reverse(h);   // h=RECIP(f)
    m=degree(h);
    if (m<n-1) h=mulxn(h,n-1-m);


    if (GF!=NULL)
    { // kill last Modulus
        for (i=0;i<N+2;i++)
        { 
            mr_free(GF[i]);
            mr_free(GRF[i]);
            mr_free(Q[i]); 
        }
        for (i=0;i<2*(N+INC);i++)
        {
            mr_free(W[i]);
            mr_free(T[i]);
        }
        mr_free(GF);
        mr_free(GRF);
        mr_free(Q);
        mr_free(W);
        mr_free(T);;
    }

    N=n;
    m=N; INC=0;
    while (m!=0) { m/=2; INC++; }

    GF=(big *)mr_alloc(N+2,sizeof(big));
    GRF=(big *)mr_alloc(N+2,sizeof(big));
    Q=(big *)mr_alloc(N+2,sizeof(big));

    W=(big *)mr_alloc(2*(N+INC),sizeof(big));
    T=(big *)mr_alloc(2*(N+INC),sizeof(big));

    for (i=0;i<N+2;i++)
    {
        GF[i]=mirvar(0);
        GRF[i]=mirvar(0);
        Q[i]=mirvar(0);
    }
    for (i=0;i<2*(N+INC);i++) 
    {
        W[i]=mirvar(0);
        T[i]=mirvar(0);
    }

    ptr=p.start;
    while (ptr!=NULL)
    {
        copy(getbig(ptr->an),GF[ptr->n]);
        ptr=ptr->next;
    }
    ptr=h.start;
    while (ptr!=NULL)
    {
        copy(getbig(ptr->an),GRF[ptr->n]);
        ptr=ptr->next;
    }
}
Esempio n. 6
0
Poly2Mod compose(const Poly2Mod& q,const Poly2Mod& p)
{ // compose polynomials
  // assume P(x) = P3x^3 + P2x^2 + P1x^1 +P0
  // Calculate P(Q(x)) = P3.(Q(x))^3 + P2.(Q(x))^2 ....   
    Poly2Mod C,Q,T; 
    big t; 
    term2 *xptr,*yptr;
    int i,j,ik,L,n=degree(Modulus);
    int k=isqrt(n+1,1);
    if (k*k<n+1) k++;

// step 1

    Poly2Mod *P=new Poly2Mod[k+1];
    P[0]=1;
    for (i=1;i<=k;i++) P[i]=(P[i-1]*p);

    big *x,*y;
    x=(big *)mr_alloc(k,sizeof(big));
    y=(big *)mr_alloc(k,sizeof(big));
    t=mirvar(0);

    T=1;
    for (i=0;i<k;i++)
    {
        ik=i*k;
        Q.clear();
        for (L=0;L<=n;L++)
        {
            zero(t);
            xptr=q.p.start;
            while (xptr!=NULL) 
            {
                if (xptr->n<=ik+k-1) break;
                xptr=xptr->next;
            }
            for (j=k-1;j>=0;j--)
            {
                x[j]=t;
                if (xptr!=NULL)
                {
                    if (ik+j==xptr->n) 
                    {
                        x[j]=getbig(xptr->an);
                        xptr=xptr->next;
                    }
                }                
                              // x[j]=q.coeff(i*k+j)
                y[j]=t;
                yptr=P[j].p.start;
                while (yptr!=NULL)
                {
                    if (yptr->n<=L)
                    {
                        if (yptr->n==L) y[j]=getbig(yptr->an);
                        break;
                    }
                    yptr=yptr->next;
                }
            }                // y[j]=P[j].coeff(L)

// Asymptotically slow, but fast in practise ...
            gf2m_dotprod(k,x,y,t);
            Q.addterm((GF2m)t,L);
        }
        C+=(Q*T);  
        if (i<k-1) T*=P[k]; 
    }
    mr_free(t);
    mr_free(y);
    mr_free(x);

    delete [] P;
    return C;
}
Esempio n. 7
0
Ps_ZZn operator*(Ps_ZZn& a,Ps_ZZn& b)
{
    Ps_ZZn prod;
    ZZn t;
    term_ps_zzn *aptr,*bptr,*pos;
    int ka,kb,i,pa,pb,d,deg,g;

    if (a.IsInt())
    {
        if (a.start==NULL) return prod;
        else return (a.start->an*b);
    }

    if (b.IsInt())
    {
        if (b.start==NULL) return prod;
        else return (b.start->an*a);
    }

    g=igcd(a.pwr,b.pwr);

    deg=psN/g;

#ifdef FFT
    if (deg>=FFT_BREAK_EVEN)
    { // use fast methods
        big *A,*B,*C;
        A=(big *)mr_alloc(deg,sizeof(big));
        B=(big *)mr_alloc(deg,sizeof(big));
        C=(big *)mr_alloc(deg,sizeof(big));
        char *memc=(char *)memalloc(deg);
        for (i=0;i<deg;i++) C[i]=mirvar_mem(memc,i);
       
        ka=a.pwr/g;
        a.decompress(ka);

        aptr=a.start;
        while (aptr!=NULL)
        {
            d=aptr->n;
            if (d >= deg) break;
            A[d]=getbig(aptr->an);
            aptr=aptr->next;
        }
        kb=b.pwr/g;
        b.decompress(kb);
        bptr=b.start;
        while (bptr!=NULL)
        {
            d=bptr->n;
            if (d >= deg) break;
            B[d]=getbig(bptr->an);
            bptr=bptr->next;
        }
        mr_ps_zzn_mul(deg,A,B,C);
        pos=NULL;
        for (d=0;d<deg;d++)
        {
            t=C[d];
            if (t.iszero()) continue;
            pos=prod.addterm(t,d*g,pos);
        }
        memkill(memc,deg);
        a.compress(ka); b.compress(kb);
        mr_free(C); mr_free(B); mr_free(A); 
    }
    else
    {
#endif
        bptr=b.start;

        while (bptr!=NULL)
        {
            aptr=a.start;
            pb=bptr->n*b.pwr-b.offset;
            pos=NULL;
            while (aptr!=NULL)
            {
                pa=aptr->n*a.pwr-a.offset;
                if (pb+pa>=psN) break;
                pos=prod.addterm(aptr->an*bptr->an,pa+pb,pos);
                aptr=aptr->next;
            }
            bptr=bptr->next;
        }
#ifdef FFT
    }
#endif

    if (prod.start!=NULL) prod.offset=a.offset+b.offset;
    return prod;
}
Esempio n. 8
0
Ps_ZZn& Ps_ZZn::operator*=(Ps_ZZn& b)
{
    term_ps_zzn *ptr,*bptr;
    int g,d,deg,ka,kb;
    if (IsInt())
    {
        if (start!=NULL) *this = start->an*b;
        return *this;
    }
    if (b.IsInt())
    {
        if (b.start==NULL) clear();
        else *this *=(b.start->an);
        return *this;
    }
    g=igcd(pwr,b.pwr);
    deg=psN/g;


#ifdef FFT
    if (deg>=FFT_BREAK_EVEN)
    {
        big *A,*B;
        A=(big *)mr_alloc(deg,sizeof(big));
        B=(big *)mr_alloc(deg,sizeof(big));
        ka=pwr/g;
        decompress(ka);
        pad();
        ptr=start;
        while (ptr!=NULL)
        {
            d=ptr->n;
            if (d>=deg) break;
            A[d]=getbig(ptr->an);
            ptr=ptr->next;
        }
        kb=b.pwr/g;
        b.decompress(kb);
        bptr=b.start;
        while (bptr!=NULL)
        {
            d=bptr->n;
            if (d>=deg) break;
            B[d]=getbig(bptr->an);
            bptr=bptr->next;
       } 
       mr_ps_zzn_mul(deg,A,B,A);
       mr_free(B); mr_free(A);
       b.compress(kb);
    }
    else
    {
#endif
        *this=*this*b;
        return *this;
#ifdef FFT
    }
#endif
    norm();
    offset+=b.offset;
    return *this;
}
Esempio n. 9
0
Poly2 operator*(const Poly2& a,const Poly2& b)
{
    int i,d,dega,degb,deg;
    GF2m t;
    Poly2 prod;
    term2 *iptr,*pos;
    term2 *ptr=b.start;
    if (&a==&b)
    { // squaring - only diagonal terms count!
        pos=NULL;
        while (ptr!=NULL)
        { // diagonal terms
            pos=prod.addterm(ptr->an*ptr->an,ptr->n+ptr->n,pos);
            ptr=ptr->next;
        }
        return prod;
    }

    dega=degree(a);
    deg=dega;
    degb=degree(b);
    if (degb<dega) deg=degb;  // deg is smallest

    if (deg>=KARAT_BREAK_EVEN)
    { // use fast method 
        int len,m,inc;

        big *A,*B,*C,*T;
        deg=dega;
        if (dega<degb) deg=degb;   // deg is biggest
        m=deg; inc=1;
        while (m!=0) { m/=2; inc++; }

        len=2*(deg+inc);

        A=(big *)mr_alloc(deg+1,sizeof(big));
        B=(big *)mr_alloc(deg+1,sizeof(big));
        C=(big *)mr_alloc(len,sizeof(big));
        T=(big *)mr_alloc(len,sizeof(big));

        char *memc=(char *)memalloc(len);
        char *memt=(char *)memalloc(len);

        for (i=0;i<len;i++)
        {
            C[i]=mirvar_mem(memc,i);
            T[i]=mirvar_mem(memt,i);
        }

        ptr=a.start;
        while (ptr!=NULL)
        {
            A[ptr->n]=getbig(ptr->an);
            ptr=ptr->next;
        }
        ptr=b.start;
        while (ptr!=NULL)
        {
            B[ptr->n]=getbig(ptr->an);
            ptr=ptr->next;
        }

        karmul2_poly(deg+1,T,A,B,C);

        pos=NULL;
        for (d=dega+degb;d>=0;d--)
        {
            t=C[d];
            if (t.iszero()) continue;
            pos=prod.addterm(t,d,pos);
        }

        memkill(memc,len);
        memkill(memt,len);

        mr_free(T);
        mr_free(C);
        mr_free(B);
        mr_free(A);
        return prod;
    }

    while (ptr!=NULL)
    {
        pos=NULL;
        iptr=a.start;
        while (iptr!=NULL)
        {
            pos=prod.addterm(ptr->an*iptr->an,ptr->n+iptr->n,pos);
            iptr=iptr->next;
        }
        ptr=ptr->next;
    }

    return prod;
}
Esempio n. 10
0
Poly operator*(const Poly& a,const Poly& b)
{
    int i,d,dega,degb,deg;
    BOOL squaring;
    ZZn t;
    Poly prod;
    term *iptr,*pos;
    term *ptr=b.start;

    squaring=FALSE;
    if (&a==&b) squaring=TRUE;

    dega=degree(a);
    deg=dega;
    if (!squaring)
    {
        degb=degree(b);
        if (degb<dega) deg=degb;
    }
    else degb=dega;
    if (deg>=FFT_BREAK_EVEN)      /* deg is minimum - both must be less than FFT_BREAK_EVEN */
    { // use fast methods 
        big *A,*B,*C;
        deg=dega+degb;     // degree of product
   
        A=(big *)mr_alloc(dega+1,sizeof(big));
        if (!squaring) B=(big *)mr_alloc(degb+1,sizeof(big));        
        C=(big *)mr_alloc(deg+1,sizeof(big));
        for (i=0;i<=deg;i++) C[i]=mirvar(0);
        ptr=a.start;
        while (ptr!=NULL)
        {
            A[ptr->n]=getbig(ptr->an);
            ptr=ptr->next;
        }

        if (!squaring)
        {
            ptr=b.start;
            while (ptr!=NULL)
            {
                B[ptr->n]=getbig(ptr->an);
                ptr=ptr->next;
            }
            mr_poly_mul(dega,A,degb,B,C);
        }
        else mr_poly_sqr(dega,A,C);
        pos=NULL;
        for (d=deg;d>=0;d--)
        {
            t=C[d];
            mr_free(C[d]);
            if (t.iszero()) continue;
            pos=prod.addterm(t,d,pos);
        }

        mr_free(C);
        mr_free(A);
        if (!squaring) mr_free(B);

        return prod;
    }

    if (squaring)
    { // squaring
        pos=NULL;
        while (ptr!=NULL)
        { // diagonal terms
            pos=prod.addterm(ptr->an*ptr->an,ptr->n+ptr->n,pos);
            ptr=ptr->next;
        }
        ptr=b.start;
        while (ptr!=NULL)
        { // above the diagonal
            iptr=ptr->next;
            pos=NULL;
            while (iptr!=NULL)
            {
                t=ptr->an*iptr->an;
                pos=prod.addterm(t+t,ptr->n+iptr->n,pos);
                iptr=iptr->next;
            }
            ptr=ptr->next; 
        }
    }
    else while (ptr!=NULL)
    {
        pos=NULL;
        iptr=a.start;
        while (iptr!=NULL)
        {
            pos=prod.addterm(ptr->an*iptr->an,ptr->n+iptr->n,pos);
            iptr=iptr->next;
        }
        ptr=ptr->next;
    }

    return prod;
}