Beispiel #1
0
mr_small smul(mr_small x,mr_small y,mr_small n)
{ /* returns x*y mod n */
    mr_small r;

#ifdef MR_ITANIUM
    mr_small tm;
#endif
#ifdef MR_WIN64
    mr_small tm;
#endif
#ifdef MR_FP
    mr_small dres;
#endif
#ifndef MR_NOFULLWIDTH
    if (n==0)
    { /* Assume n=2^MIRACL */
        muldvd(x,y,(mr_small)0,&r);
        return r;
    }
#endif
    x=MR_REMAIN(x,n);
    y=MR_REMAIN(y,n);
    muldiv(x,y,(mr_small)0,n,&r);
    return r;
}
Beispiel #2
0
mr_small invers(mr_small x,mr_small y)
{ /* returns inverse of x mod y */
    mr_small r,s,q,t,p;
#ifdef MR_FP
    mr_small dres;
#endif

    BOOL pos;
    if (y!=0) x=MR_REMAIN(x,y);
    r=1;
    s=0;
    p=y;
    pos=TRUE;
#ifndef MR_NOFULLWIDTH
    if (p==0)
    { /* if modulus is 0, assume its actually 2^MIRACL */
        if (x==1) return (mr_small)1;
        t=r; r=s; s=t;
        p=x;  
        q=muldvm((mr_small)1,(mr_small)0,p,&t);
        t=r+s*q;  r=s; s=t;
        t=0-p*q;  x=p; p=t; 
    }
#endif
    while (p!=0)
    { /* main euclidean loop */
        q=MR_DIV(x,p);
        t=r+s*q;  r=s; s=t;
        t=x-p*q;  x=p; p=t;
        pos=!pos;
    }
    if (!pos) r=y-r;
    return r;
}
Beispiel #3
0
void frand(_MIPD_ flash x)
{ /* generates random flash number 0<x<1 */
    int i;
#ifdef MR_FP
    mr_small dres;
#endif
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return;

    MR_IN(46)

    zero(mr_mip->w6);
    mr_mip->w6->len=mr_mip->nib;
    for (i=0;i<mr_mip->nib;i++) 
    { /* generate a full width random number */
        if (mr_mip->base==0) mr_mip->w6->w[i]=brand(_MIPPO_ );
        else                 mr_mip->w6->w[i]=MR_REMAIN(brand(_MIPPO_ ),mr_mip->base);
    }
    mr_mip->check=OFF;
    bigrand(_MIPP_ mr_mip->w6,mr_mip->w5);
    mr_mip->check=ON;
    mround(_MIPP_ mr_mip->w5,mr_mip->w6,x);

    MR_OUT
}
Beispiel #4
0
void strong_bigrand(_MIPD_ csprng *rng,big w,big x)
{
	int i, m;
	mr_small r;
    unsigned int ran;
    unsigned int ch;

#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return;
    MR_IN(20)
	
	m = 0;
    zero(mr_mip->w1);
	
    do
    {
		m++;
		mr_mip->w1->len=m;
		for (r = 0, i = 0; i < sizeof(mr_small); i++) {
			ch=(unsigned char)strong_rng(rng);
			ran=ch;
			r = (r << 8) ^ ran;
		}
        if (mr_mip->base==0) mr_mip->w1->w[m-1]=r;
        else                 mr_mip->w1->w[m-1]=MR_REMAIN(r,mr_mip->base);
    } while (mr_compare(mr_mip->w1,w)<0);
	mr_lzero(mr_mip->w1);
    divide(_MIPP_ mr_mip->w1,w,w);
	
    copy(mr_mip->w1,x);
    MR_OUT
}
Beispiel #5
0
void uconvert(_MIPD_ unsigned int n ,big x)
{  /*  convert integer n to big number format  */
    int m;
#ifdef MR_FP
    mr_small dres;
#endif
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    zero(x);
    if (n==0) return;
    
    m=0;
    if (mr_mip->base==0)
    {
#ifndef MR_NOFULLWIDTH
#if MR_IBITS > MIRACL
        while (n>0)
        {
            x->w[m++]=(mr_small)(n%((mr_small)1<<(MIRACL)));
            n/=((mr_small)1<<(MIRACL));
        }
#else
        x->w[m++]=(mr_small)n;
#endif
#endif
    }
    else while (n>0)
    {
        x->w[m++]=MR_REMAIN((mr_small)n,mr_mip->base);
        n/=mr_mip->base;
    }
    x->len=(m);
}
Beispiel #6
0
mr_small spmd(mr_small x,mr_small n,mr_small m) 
{ /*  returns x^n mod m  */
    mr_small r,sx;
#ifdef MR_FP
    mr_small dres;
#endif
    x=MR_REMAIN(x,m);
    r=0;
    if (x==0) return r;
    r=1;
    if (n==0) return r;
    sx=x;
    forever
    {
        if (MR_REMAIN(n,2)!=0) muldiv(r,sx,(mr_small)0,m,&r);
        n=MR_DIV(n,2);
        if (n==0) return r;
        muldiv(sx,sx,(mr_small)0,m,&sx);
    }
}
Beispiel #7
0
int jac(mr_small x,mr_small n)
{ /* finds (x/n) as (-1)^m */ 
    int m,k,n8,u4;
    mr_small t;
#ifdef MR_FP
    mr_small dres;
#endif
    if (x==0)
    {
        if (n==1) return 1;
        else return 0;
    } 
    if (MR_REMAIN(n,2)==0) return 0;
    x=MR_REMAIN(x,n);   
    m=0;
    while(n>1)
    { /* main loop */
        if (x==0) return 0;

/* extract powers of 2 */
        for (k=0;MR_REMAIN(x,2)==0;k++) x=MR_DIV(x,2);
        n8=(int)MR_REMAIN(n,8);
        if (k%2==1) m+=(n8*n8-1)/8;

/* quadratic reciprocity */
        u4=(int)MR_REMAIN(x,4);
        m+=(n8-1)*(u4-1)/4;
        t=n;  t=MR_REMAIN(t,x);
        n=x;  x=t;
        m%=2;
    }
    if (m==0) return 1;
    else      return (-1);
} 
Beispiel #8
0
void lgconv(_MIPD_ long n,big x)
{ /* convert long integer to big number format - rarely needed */
    int m;
    mr_unsign32 s;
#ifdef MR_FP
    mr_small dres;
#endif
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    zero(x);
    if (n==0) return;
    s=0;
    if (n<0)
    {
        s=MR_MSBIT;
        n=(-n);
    }
    m=0;
    if (mr_mip->base==0)
    {
#ifndef MR_NOFULLWIDTH
#if MR_LBITS > MIRACL
        while (n>0)
        {
            x->w[m++]=(mr_small)(n%(1L<<(MIRACL)));
            n/=(1L<<(MIRACL));
        }
#else
        x->w[m++]=(mr_small)n;
#endif
#endif
    }    
    else while (n>0)
    {
        x->w[m++]=MR_REMAIN(n,mr_mip->base);
        n/=mr_mip->base;
    }
    x->len=(m|s);
}
Beispiel #9
0
void dlconv(_MIPD_ mr_dltype n,big x)
{ /* convert double length integer to big number format - rarely needed */
    int m;
    mr_unsign32 s;
#ifdef MR_FP
    mr_small dres;
#endif
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    zero(x);
    if (n==0) return;
    s=0;
    if (n<0)
    {
        s=MR_MSBIT;
        n=(-n);
    }
    m=0;
    if (mr_mip->base==0)
    {
#ifndef MR_NOFULLWIDTH
        while (n>0)
        {
            x->w[m++]=(mr_small)(n%((mr_dltype)1<<(MIRACL)));
            n/=((mr_dltype)1<<(MIRACL));
        }
#endif
    }    
    else while (n>0)
    {
        x->w[m++]=(mr_small)MR_REMAIN(n,mr_mip->base);
        n/=mr_mip->base;
    }
    x->len=(m|s);
}
Beispiel #10
0
mr_small sqrmp(mr_small x,mr_small m)
{ /* square root mod a small prime by Shanks method  *
   * returns 0 if root does not exist or m not prime */
    mr_small z,y,v,w,t,q;
#ifdef MR_FP
    mr_small dres;
#endif
    int i,e,n,r;
    BOOL pp;
    x=MR_REMAIN(x,m);
    if (x==0) return 0;
    if (x==1) return 1;
    if (spmd(x,(mr_small)((m-1)/2),m)!=1) return 0;    /* Legendre symbol not 1   */
    if (MR_REMAIN(m,4)==3) return spmd(x,(mr_small)((m+1)/4),m);  /* easy case for m=4.k+3   */
    if (MR_REMAIN(m,8)==5)
    { /* also relatively easy */
        t=spmd(x,(mr_small)((m-1)/4),m);
        if (t==1) return spmd(x,(mr_small)((m+3)/8),m);
        if (t==(mr_small)(m-1))
        {
            muldiv((mr_small)4,x,(mr_small)0,m,&t);
            t=spmd(t,(mr_small)((m+3)/8),m);
            muldiv(t,(mr_small)((m+1)/2),(mr_small)0,m,&t);
            return t;
        }
        return 0;
    }
    q=m-1;
    e=0;
    while (MR_REMAIN(q,2)==0) 
    {
        q=MR_DIV(q,2);
        e++;
    }
    if (e==0) return 0;      /* even m */
    for (r=2;;r++)
    { /* find suitable z */
        z=spmd((mr_small)r,q,m);
        if (z==1) continue;
        t=z;
        pp=FALSE;
        for (i=1;i<e;i++)
        { /* check for composite m */
            if (t==(m-1)) pp=TRUE;
            muldiv(t,t,(mr_small)0,m,&t);
            if (t==1 && !pp) return 0;
        }
        if (t==(m-1)) break;
        if (!pp) return 0;   /* m is not prime */
    }
    y=z;
    r=e;
    v=spmd(x,(mr_small)((q+1)/2),m);
    w=spmd(x,q,m);
    while (w!=1)
    {
        t=w;
        for (n=0;t!=1;n++) muldiv(t,t,(mr_small)0,m,&t);
        if (n>=r) return 0;
        y=spmd(y,mr_shiftbits(1,r-n-1),m);
        muldiv(v,y,(mr_small)0,m,&v);
        muldiv(y,y,(mr_small)0,m,&y);
        muldiv(w,y,(mr_small)0,m,&w);
        r=n;
    }
    return v;
}
Beispiel #11
0
int egcd(_MIPD_ big x,big y,big z)
{ /* greatest common divisor z=gcd(x,y) by Euclids  *
   * method using Lehmers algorithm for big numbers */
    int q,r,a,b,c,d,n;
    mr_small sr,m,sm;
    mr_small u,v,lq,lr;
#ifdef MR_FP
    mr_small dres;
#endif
    big t;
#ifndef MR_GENERIC_MT
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return 0;

    MR_IN(12)

    copy(x,mr_mip->w1);
    copy(y,mr_mip->w2);
    insign(PLUS,mr_mip->w1);
    insign(PLUS,mr_mip->w2);
    a=b=c=d=0;
    while (size(mr_mip->w2)!=0)
    {
        if (b==0)
        { /* update w1 and w2 */
            divide(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w2);
            t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t;   /* swap(w1,w2) */
        }
        else
        {
            premult(_MIPP_ mr_mip->w1,c,z);
            premult(_MIPP_ mr_mip->w1,a,mr_mip->w1);
            premult(_MIPP_ mr_mip->w2,b,mr_mip->w0);
            premult(_MIPP_ mr_mip->w2,d,mr_mip->w2);
            add(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1);
            add(_MIPP_ mr_mip->w2,z,mr_mip->w2);
        }
        if (mr_mip->ERNUM || size(mr_mip->w2)==0) break;
        n=(int)mr_mip->w1->len;
        if (mr_mip->w2->len==1)
        { /* special case if mr_mip->w2 is now small */
            sm=mr_mip->w2->w[0];    
#ifdef MR_FP_ROUNDING
            sr=mr_sdiv(_MIPP_ mr_mip->w1,sm,mr_invert(sm),mr_mip->w1);
#else
            sr=mr_sdiv(_MIPP_ mr_mip->w1,sm,mr_mip->w1);
#endif
            if (sr==0)
            {
                copy(mr_mip->w2,mr_mip->w1);
                break;
            }
            zero(mr_mip->w1);
            mr_mip->w1->len=1;
            mr_mip->w1->w[0]=sr;
            while ((sr=MR_REMAIN(mr_mip->w2->w[0],mr_mip->w1->w[0]))!=0)
                  mr_mip->w2->w[0]=mr_mip->w1->w[0],mr_mip->w1->w[0]=sr;
            break;
        }
        a=1;
        b=0;
        c=0;
        d=1;
        m=mr_mip->w1->w[n-1]+1;
        if (mr_mip->base==0)
        {
#ifndef MR_NOFULLWIDTH
            if (m==0)
            {
                u=mr_mip->w1->w[n-1];
                v=mr_mip->w2->w[n-1];
            }
            else
            {
                u=muldvm(mr_mip->w1->w[n-1],mr_mip->w1->w[n-2],m,&sr);
                v=muldvm(mr_mip->w2->w[n-1],mr_mip->w2->w[n-2],m,&sr);
            }
#endif
        }
        else
        {
            u=muldiv(mr_mip->w1->w[n-1],mr_mip->base,mr_mip->w1->w[n-2],m,&sr);
            v=muldiv(mr_mip->w2->w[n-1],mr_mip->base,mr_mip->w2->w[n-2],m,&sr);
        }
        forever
        { /* work only with most significant piece */
            if (((v+c)==0) || ((v+d)==0)) break;
            lq=MR_DIV((u+a),(v+c));
            if (lq!=MR_DIV((u+b),(v+d))) break;
            if (lq>=(mr_small)(MR_TOOBIG/mr_abs(d))) break;
            q=(int)lq;
            r=a-q*c;
            a=c;
            c=r;
            r=b-q*d;
            b=d;
            d=r;
            lr=u-lq*v;
            u=v;
            v=lr;
        }
    }
    copy(mr_mip->w1,z);
    MR_OUT
    return (size(mr_mip->w1));
}