Example #1
0
void ecurve_init(_MIPD_ big a,big b,big p,int type)
{ /* Initialize the active ecurve    *
   * Asize indicate size of A        *
   * Bsize indicate size of B        */
    int as;
#ifndef MR_GENERIC_MT
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return;

    MR_IN(93)

    prepare_monty(_MIPP_ p);

    mr_mip->Asize=size(a);
    if (mr_abs(mr_mip->Asize)==MR_TOOBIG)
    {
        if (mr_mip->Asize>=0)
        { /* big positive number - check it isn't minus something small */
           copy(a,mr_mip->w1);
           divide(_MIPP_ mr_mip->w1,p,p);
           subtract(_MIPP_ p,mr_mip->w1,mr_mip->w1);
           as=size(mr_mip->w1);
           if (as<MR_TOOBIG) mr_mip->Asize=-as;
           else
           {
               if (mr_mip->A==NULL) mr_mip->A=mirvar(_MIPP_ 0);
               nres(_MIPP_ a,mr_mip->A);
           }
        }
        else
        {
               if (mr_mip->A==NULL) mr_mip->A=mirvar(_MIPP_ 0);
               nres(_MIPP_ a,mr_mip->A);
        }
    }
    mr_mip->Bsize=size(b);
    if (mr_abs(mr_mip->Bsize)==MR_TOOBIG)
    {
        if (mr_mip->B==NULL) mr_mip->B=mirvar(_MIPP_ 0);
        nres(_MIPP_ b,mr_mip->B);

    }
    mr_mip->coord=type;
    MR_OUT
    return;
}
Example #2
0
void sftbit(_MIPD_ big x,int n,big z)
{ /* shift x by n bits */
    int m;
    mr_small sm;
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return;
    copy(x,z);
    if (n==0) return;

    MR_IN(47)

    m=mr_abs(n);
    sm=mr_shiftbits((mr_small)1,m%mr_mip->lg2b);
    if (n>0)
    { /* shift left */

#ifndef MR_ALWAYS_BINARY
        if (mr_mip->base==mr_mip->base2)
        {
#endif
            mr_shift(_MIPP_ z,n/mr_mip->lg2b,z);
            mr_pmul(_MIPP_ z,sm,z);
#ifndef MR_ALWAYS_BINARY
        }
        else
        {
            expb2(_MIPP_ m,mr_mip->w1);
            multiply(_MIPP_ z,mr_mip->w1,z);
        }
#endif
    }
    else
    { /* shift right */

#ifndef MR_ALWAYS_BINARY
        if (mr_mip->base==mr_mip->base2)
        {
#endif
            mr_shift(_MIPP_ z,n/mr_mip->lg2b,z);
#ifdef MR_FP_ROUNDING
            mr_sdiv(_MIPP_ z,sm,mr_invert(sm),z);
#else
            mr_sdiv(_MIPP_ z,sm,z);
#endif

#ifndef MR_ALWAYS_BINARY
        }
        else
        {
            expb2(_MIPP_ m,mr_mip->w1);
            divide(_MIPP_ z,mr_mip->w1,z);
        }
#endif
    }
    MR_OUT
}
Example #3
0
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return;

    MR_IN(32)

    zero(w);
    if (d==0.0)
    {
        MR_OUT
        return;
    }
    mr_mip->D=d;
    s=sign(mr_mip->D);
    mr_mip->D=mr_abs(mr_mip->D);
    build(_MIPP_ w,dquot);
    insign(s,w);

    MR_OUT
}
        
double fdsize(_MIPD_ flash w)
{ /* express flash number as double. */
    int i,s,en,ed;
    double n,d,b,BIGGEST;
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM || size(w)==0) return (0.0);
Example #4
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));
}
Example #5
0
static int euclid(_MIPD_ big x,int num)
{ /* outputs next c.f. quotient from gcd(w5,w6) */
    mr_small sr,m;
#ifdef MR_FP
    mr_small dres;
#endif
    mr_small lr,lq;
    big t;
#ifndef MR_GENERIC_MT
    miracl *mr_mip=get_mip();
#endif
    if (num==0)
    {
        mr_mip->oldn=(-1);
        mr_mip->carryon=FALSE;
        mr_mip->last=FALSE;
        if (compare(mr_mip->w6,mr_mip->w5)>0)
        { /* ensure w5>w6 */
            t=mr_mip->w5,mr_mip->w5=mr_mip->w6,mr_mip->w6=t;
            return (mr_mip->q=0);
        }
    }
    else if (num==mr_mip->oldn || mr_mip->q<0) return mr_mip->q;
    mr_mip->oldn=num;
    if (mr_mip->carryon) goto middle;
start:
    if (size(mr_mip->w6)==0) return (mr_mip->q=(-1));
    mr_mip->ndig=(int)mr_mip->w5->len;
    mr_mip->carryon=TRUE;
    mr_mip->a=1;
    mr_mip->b=0;
    mr_mip->c=0;
    mr_mip->d=1;
    if (mr_mip->ndig==1)
    {
        mr_mip->last=TRUE;
        mr_mip->u=mr_mip->w5->w[0];
        mr_mip->v=mr_mip->w6->w[0];
    }
    else
    {
        m=mr_mip->w5->w[mr_mip->ndig-1]+1;
        if (mr_mip->base==0)
        {
#ifndef MR_NOFULLWIDTH
            if (m==0)
            {
                mr_mip->u=mr_mip->w5->w[mr_mip->ndig-1];
                mr_mip->v=mr_mip->w6->w[mr_mip->ndig-1];
            }
            else
            {
                mr_mip->u=muldvm(mr_mip->w5->w[mr_mip->ndig-1],mr_mip->w5->w[mr_mip->ndig-2],m,&sr);
                mr_mip->v=muldvm(mr_mip->w6->w[mr_mip->ndig-1],mr_mip->w6->w[mr_mip->ndig-2],m,&sr);
            }
#endif
        }
        else
        {
            mr_mip->u=muldiv(mr_mip->w5->w[mr_mip->ndig-1],mr_mip->base,mr_mip->w5->w[mr_mip->ndig-2],m,&sr);
            mr_mip->v=muldiv(mr_mip->w6->w[mr_mip->ndig-1],mr_mip->base,mr_mip->w6->w[mr_mip->ndig-2],m,&sr);
        }
    }
    mr_mip->ku=mr_mip->u;
    mr_mip->kv=mr_mip->v;
middle:
    forever
    { /* work only with most significant piece */
        if (mr_mip->last)
        {
            if (mr_mip->v==0) return (mr_mip->q=(-1));
            lq=MR_DIV(mr_mip->u,mr_mip->v);
        }
        else
        {
            if (((mr_mip->v+mr_mip->c)==0) || ((mr_mip->v+mr_mip->d)==0)) break;
            lq=MR_DIV((mr_mip->u+mr_mip->a),(mr_mip->v+mr_mip->c));
            if (lq!=MR_DIV((mr_mip->u+mr_mip->b),(mr_mip->v+mr_mip->d))) break;
        }
        if (lq>=(mr_small)(MR_TOOBIG/mr_abs(mr_mip->d))) break;

        mr_mip->q=(int)lq;
        mr_mip->r=mr_mip->a-mr_mip->q*mr_mip->c;
        mr_mip->a=mr_mip->c;
        mr_mip->c=mr_mip->r;
        mr_mip->r=mr_mip->b-mr_mip->q*mr_mip->d;
        mr_mip->b=mr_mip->d;
        mr_mip->d=mr_mip->r;
        lr=mr_mip->u-lq*mr_mip->v;
        mr_mip->u=mr_mip->v;
        mr_mip->v=lr;
        return mr_mip->q;
    }
    mr_mip->carryon=FALSE;
    if (mr_mip->b==0)
    { /* update w5 and w6 */
        mr_mip->check=OFF;
        divide(_MIPP_ mr_mip->w5,mr_mip->w6,mr_mip->w7);
        mr_mip->check=ON;
        if (mr_lent(mr_mip->w7)>mr_mip->nib) return (mr_mip->q=(-2));
        t=mr_mip->w5,mr_mip->w5=mr_mip->w6,mr_mip->w6=t;   /* swap(w5,w6) */
        copy(mr_mip->w7,x);
        return (mr_mip->q=size(x));
    }
    else
    {
        mr_mip->check=OFF;
        premult(_MIPP_ mr_mip->w5,mr_mip->c,mr_mip->w7);
        premult(_MIPP_ mr_mip->w5,mr_mip->a,mr_mip->w5);
        premult(_MIPP_ mr_mip->w6,mr_mip->b,mr_mip->w0);
        premult(_MIPP_ mr_mip->w6,mr_mip->d,mr_mip->w6);
        add(_MIPP_ mr_mip->w5,mr_mip->w0,mr_mip->w5);
        add(_MIPP_ mr_mip->w6,mr_mip->w7,mr_mip->w6);
        mr_mip->check=ON;
    }
    goto start;
}
Example #6
0
void build(_MIPD_ flash x,int (*gen)(_MIPT_ big,int))
{ /* Build x from its regular c.f. *
   * generated by gen()            */
    mr_small ex1,ex2,ex,st,sr;
    int a,b,c,d,rm,q,n,prc,lw2,lw4,lz;
    BOOL finoff,last;
    big t;
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return;

    MR_IN(48)

    zero(mr_mip->w1);
    convert(_MIPP_ 1,mr_mip->w2);
    convert(_MIPP_ 1,mr_mip->w3);
    zero(mr_mip->w4);
    finoff=FALSE;
    last=FALSE;
    n=0;
    q=(*gen)(_MIPP_ x,n);   /* Note - first quotient may be zero */
    ex=mr_mip->base-1;
    if (mr_mip->nib==mr_mip->workprec) prc=mr_mip->nib;
    else prc=mr_mip->workprec+1;
    while (!mr_mip->ERNUM && q>=0)
    {
        if (q==MR_TOOBIG || n==0 || finoff)
        {
            if (q!=MR_TOOBIG) convert(_MIPP_ q,x);
            else last=FALSE;
            mr_mip->check=OFF;
            multiply(_MIPP_ mr_mip->w2,x,mr_mip->w0);
            subtract(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w7);
            mr_mip->check=ON;
            if ((int)(mr_mip->w7->len&MR_OBITS)>mr_mip->nib) break;
            copy(mr_mip->w7,mr_mip->w1);
            t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t;   /* swap(w1,w2) */
            mr_mip->check=OFF;
            multiply(_MIPP_ mr_mip->w4,x,mr_mip->w0);
            subtract(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w7);
            mr_mip->check=ON;
            if ((int)(mr_mip->w7->len&MR_OBITS)>mr_mip->nib)
            { /* oops! */
                fpack(_MIPP_ mr_mip->w1,mr_mip->w4,x);
                negify(x,x);
                mr_mip->EXACT=FALSE;
                MR_OUT
                return;
            }
            copy(mr_mip->w7,mr_mip->w3);
            t=mr_mip->w3,mr_mip->w3=mr_mip->w4,mr_mip->w4=t;   /* swap(w3,w4) */
            n++;
        }
        lw2=(int)(mr_mip->w2->len&MR_OBITS);
        lw4=(int)(mr_mip->w4->len&MR_OBITS);
        lz=lw2+lw4;
        if (lz > prc) break;  /* too big - exit */
        if (last)
        {
            if (finoff) break;
            finoff=TRUE;
            q=(*gen)(_MIPP_ x,n);
            continue;
        }
        if (lz>=prc-1)
        { /* nearly finished - so be careful not to overshoot */
            if (mr_mip->base==0)
            {
#ifndef MR_NOFULLWIDTH
                st=mr_mip->w2->w[lw2-1]+1;
                if (st==0) ex1=1;
                else ex1=muldvm((mr_small)1,(mr_small)0,st,&sr);
                st=mr_mip->w4->w[lw4-1]+1;
                if (st==0) ex2=1;
                else ex2=muldvm((mr_small)1,(mr_small)0,st,&sr);
#endif
            }
            else
            {
                ex1=mr_mip->base/(mr_mip->w2->w[lw2-1]+1);
                ex2=mr_mip->base/(mr_mip->w4->w[lw4-1]+1);
            }
            if (ex2>ex1) ex=ex1,ex1=ex2,ex2=ex;
            if (lz==prc) ex=ex2;
            else         ex=ex1;
            last=TRUE;
        }
        a=1;
        b=0;
        c=0;
        d=1;
        forever
        {
            q=(*gen)(_MIPP_ x,n);          
            if (q<0 || q>=MR_TOOBIG/mr_abs(d))
            { /* there could be more.... *** V3.21 mod *** */
                last=FALSE;
                break;
            }
            rm=b-q*d;
            b=d;
            d=rm;
            rm=a-q*c;
            a=c;
            c=rm;
            n++;
            if ((mr_small)(mr_abs(c-d))>ex) break;
        }
        premult(_MIPP_ mr_mip->w1,c,mr_mip->w7);
        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,mr_mip->w7,mr_mip->w2);
        premult(_MIPP_ mr_mip->w3,c,mr_mip->w7);
        premult(_MIPP_ mr_mip->w3,a,mr_mip->w3);
        premult(_MIPP_ mr_mip->w4,b,mr_mip->w0);
        premult(_MIPP_ mr_mip->w4,d,mr_mip->w4);
        add(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3);
        add(_MIPP_ mr_mip->w4,mr_mip->w7,mr_mip->w4);
    }