📄 mrcore.c
字号:
{
b=MR_DIV(b,2);
mr_mip->lg2b++;
mr_mip->base2*=2;
}
#endif
mr_mip->base_mask=mr_mip->base-1;
#ifdef MR_ALWAYS_BINARY
if (mr_mip->base!=mr_mip->base2)
{
mr_berror(_MIPP_ MR_ERR_NOT_BINARY);
MR_OUT
return mr_mip;
}
#endif
/* calculate total space for bigs */
/*
big -> |int len|small *ptr| alignment space | size in words +1| alignment up to multiple of 4 |
*/
if (nd>0) nw=MR_ROUNDUP(nd,mr_mip->pack);
else nw=MR_ROUNDUP(8*(-nd),mr_mip->lg2b);
if (nw<1) nw=1;
mr_mip->nib=(int)(nw+1); /* add one extra word for small overflows */
#ifdef MR_STATIC
if (nw>MR_STATIC)
{
mr_berror(_MIPP_ MR_ERR_TOO_BIG);
MR_OUT
return mr_mip;
}
#endif
mr_mip->nib=(int)(nw+1); /* add one extra word for small overflows */
#ifdef MR_FLASH
mr_mip->workprec=mr_mip->nib;
mr_mip->stprec=mr_mip->nib;
while (mr_mip->stprec>2 && mr_mip->stprec>MR_FLASH/mr_mip->lg2b)
mr_mip->stprec=(mr_mip->stprec+1)/2;
if (mr_mip->stprec<2) mr_mip->stprec=2;
#endif
#ifndef MR_DOUBLE_BIG
mr_mip->check=ON;
#else
mr_mip->check=OFF;
#endif
#ifndef MR_SIMPLE_BASE
#ifndef MR_SIMPLE_IO
mr_mip->IOBASE=10; /* defaults */
#endif
#endif
mr_mip->ERNUM=0;
mr_mip->NTRY=6;
mr_mip->MONTY=ON;
#ifdef MR_FLASH
mr_mip->EXACT=TRUE;
mr_mip->RPOINT=OFF;
#endif
#ifndef MR_STRIPPED_DOWN
mr_mip->TRACER=OFF;
#endif
#ifndef MR_SIMPLE_IO
mr_mip->INPLEN=0;
mr_mip->IOBSIZ=MR_DEFAULT_BUFFER_SIZE;
#endif
#ifdef MR_STATIC
mr_mip->PRIMES=mr_small_primes;
#else
mr_mip->PRIMES=NULL;
#ifndef MR_SIMPLE_IO
mr_mip->IOBUFF=(char *)mr_alloc(_MIPP_ MR_DEFAULT_BUFFER_SIZE+1,1);
#endif
#endif
#ifndef MR_SIMPLE_IO
mr_mip->IOBUFF[0]='\0';
#endif
mr_mip->qnr=0;
mr_mip->cnr=0;
mr_mip->TWIST=FALSE;
mr_mip->pmod8=0;
/* quick start for rng. irand(.) should be called first before serious use.. */
#ifndef MR_NO_RAND
mr_mip->ira[0]=0x55555555;
mr_mip->ira[1]=0x12345678;
for (i=2;i<NK;i++)
mr_mip->ira[i]=mr_mip->ira[i-1]+mr_mip->ira[i-2]+0x1379BDF1;
mr_mip->rndptr=NK;
mr_mip->borrow=0;
#endif
mr_mip->nib=2*mr_mip->nib+1;
#ifdef MR_FLASH
if (mr_mip->nib!=(mr_mip->nib&(MR_MSK)))
#else
if (mr_mip->nib!=(int)(mr_mip->nib&(MR_OBITS)))
#endif
{
mr_berror(_MIPP_ MR_ERR_TOO_BIG);
mr_mip->nib=(mr_mip->nib-1)/2;
MR_OUT
return mr_mip;
}
#ifndef MR_STATIC
mr_mip->workspace=(char *)memalloc(_MIPP_ MR_SPACES); /* grab workspace */
#else
memset(mr_mip->workspace,0,MR_BIG_RESERVE(MR_SPACES));
#endif
mr_mip->M=0;
mr_mip->fin=FALSE;
mr_mip->fout=FALSE;
mr_mip->active=ON;
mr_mip->nib=(mr_mip->nib-1)/2;
/* allocate memory for workspace variables */
#ifndef MR_DOUBLE_BIG
mr_mip->w0=mirvar_mem(_MIPP_ mr_mip->workspace,0); /* double length */
mr_mip->w1=mirvar_mem(_MIPP_ mr_mip->workspace,2);
mr_mip->w2=mirvar_mem(_MIPP_ mr_mip->workspace,3);
mr_mip->w3=mirvar_mem(_MIPP_ mr_mip->workspace,4);
mr_mip->w4=mirvar_mem(_MIPP_ mr_mip->workspace,5);
mr_mip->w5=mirvar_mem(_MIPP_ mr_mip->workspace,6); /* double length */
mr_mip->w6=mirvar_mem(_MIPP_ mr_mip->workspace,8); /* double length */
mr_mip->w7=mirvar_mem(_MIPP_ mr_mip->workspace,10); /* double length */
mr_mip->w8=mirvar_mem(_MIPP_ mr_mip->workspace,12);
mr_mip->w9=mirvar_mem(_MIPP_ mr_mip->workspace,13);
mr_mip->w10=mirvar_mem(_MIPP_ mr_mip->workspace,14);
mr_mip->w11=mirvar_mem(_MIPP_ mr_mip->workspace,15);
mr_mip->w12=mirvar_mem(_MIPP_ mr_mip->workspace,16);
mr_mip->w13=mirvar_mem(_MIPP_ mr_mip->workspace,17);
mr_mip->w14=mirvar_mem(_MIPP_ mr_mip->workspace,18);
mr_mip->w15=mirvar_mem(_MIPP_ mr_mip->workspace,19);
mr_mip->sru=mirvar_mem(_MIPP_ mr_mip->workspace,20);
mr_mip->modulus=mirvar_mem(_MIPP_ mr_mip->workspace,21);
mr_mip->pR=mirvar_mem(_MIPP_ mr_mip->workspace,22); /* double length */
mr_mip->A=mirvar_mem(_MIPP_ mr_mip->workspace,24);
mr_mip->B=mirvar_mem(_MIPP_ mr_mip->workspace,25);
mr_mip->one=mirvar_mem(_MIPP_ mr_mip->workspace,26);
#ifdef MR_KCM
mr_mip->big_ndash=mirvar_mem(_MIPP_ mr_mip->workspace,27);
mr_mip->ws=mirvar_mem(_MIPP_ mr_mip->workspace,28);
mr_mip->wt=mirvar_mem(_MIPP_ mr_mip->workspace,29); /* double length */
#endif
#ifdef MR_FLASH
#ifdef MR_KCM
mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,31);
#else
mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,27);
#endif
#endif
#else
/* w0-w7 are double normal length */
mr_mip->w0=mirvar_mem(_MIPP_ mr_mip->workspace,0); /* quad length */
mr_mip->w1=mirvar_mem(_MIPP_ mr_mip->workspace,4); /* double length */
mr_mip->w2=mirvar_mem(_MIPP_ mr_mip->workspace,6);
mr_mip->w3=mirvar_mem(_MIPP_ mr_mip->workspace,8);
mr_mip->w4=mirvar_mem(_MIPP_ mr_mip->workspace,10);
mr_mip->w5=mirvar_mem(_MIPP_ mr_mip->workspace,12); /* quad length */
mr_mip->w6=mirvar_mem(_MIPP_ mr_mip->workspace,16); /* quad length */
mr_mip->w7=mirvar_mem(_MIPP_ mr_mip->workspace,20); /* quad length */
mr_mip->w8=mirvar_mem(_MIPP_ mr_mip->workspace,24);
mr_mip->w9=mirvar_mem(_MIPP_ mr_mip->workspace,25);
mr_mip->w10=mirvar_mem(_MIPP_ mr_mip->workspace,26);
mr_mip->w11=mirvar_mem(_MIPP_ mr_mip->workspace,27);
mr_mip->w12=mirvar_mem(_MIPP_ mr_mip->workspace,28);
mr_mip->w13=mirvar_mem(_MIPP_ mr_mip->workspace,29);
mr_mip->w14=mirvar_mem(_MIPP_ mr_mip->workspace,30);
mr_mip->w15=mirvar_mem(_MIPP_ mr_mip->workspace,31);
mr_mip->sru=mirvar_mem(_MIPP_ mr_mip->workspace,32);
mr_mip->modulus=mirvar_mem(_MIPP_ mr_mip->workspace,33);
mr_mip->pR=mirvar_mem(_MIPP_ mr_mip->workspace,34); /* double length */
mr_mip->A=mirvar_mem(_MIPP_ mr_mip->workspace,36);
mr_mip->B=mirvar_mem(_MIPP_ mr_mip->workspace,37);
mr_mip->one=mirvar_mem(_MIPP_ mr_mip->workspace,38);
#ifdef MR_KCM
mr_mip->big_ndash=mirvar_mem(_MIPP_ mr_mip->workspace,39);
mr_mip->ws=mirvar_mem(_MIPP_ mr_mip->workspace,40);
mr_mip->wt=mirvar_mem(_MIPP_ mr_mip->workspace,41); /* double length */
#endif
#ifdef MR_FLASH
#ifdef MR_KCM
mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,43);
#else
mr_mip->pi=mirvar_mem(_MIPP_ mr_mip->workspace,39);
#endif
#endif
#endif
MR_OUT
return mr_mip;
}
#ifndef MR_STATIC
/* allocate space for a number of bigs from the heap */
void *memalloc(_MIPD_ int num)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
return mr_alloc(_MIPP_ mr_big_reserve(num,mr_mip->nib-1),1);
}
#endif
void memkill(_MIPD_ char *mem,int len)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mem==NULL) return;
memset(mem,0,mr_big_reserve(len,mr_mip->nib-1));
#ifndef MR_STATIC
mr_free(mem);
#endif
}
#ifndef MR_STATIC
void mirkill(big x)
{ /* kill a big/flash variable, that is set it to zero
and free its memory */
if (x==NULL) return;
zero(x);
mr_free(x);
}
#endif
void mirexit(_MIPDO_ )
{ /* clean up after miracl */
int i;
#ifdef MR_WINDOWS_MT
miracl *mr_mip=get_mip();
#endif
#ifdef MR_UNIX_MT
miracl *mr_mip=get_mip();
#endif
#ifdef MR_OPENMP_MT
miracl *mr_mip=get_mip();
#endif
mr_mip->ERCON=FALSE;
mr_mip->active=OFF;
memkill(_MIPP_ mr_mip->workspace,MR_SPACES);
#ifndef MR_NO_RAND
for (i=0;i<NK;i++) mr_mip->ira[i]=0L;
#endif
#ifndef MR_STATIC
#ifndef MR_SIMPLE_IO
set_io_buffer_size(_MIPP_ 0);
#endif
if (mr_mip->PRIMES!=NULL) mr_free(mr_mip->PRIMES);
#else
#ifndef MR_SIMPLE_IO
for (i=0;i<=MR_DEFAULT_BUFFER_SIZE;i++)
mr_mip->IOBUFF[i]=0;
#endif
#endif
#ifndef MR_STATIC
mr_free(mr_mip);
#ifdef MR_WINDOWS_MT
TlsSetValue(mr_key, NULL); //Thank you Thales
#endif
#endif
#ifndef MR_GENERIC_MT
#ifndef MR_WINDOWS_MT
#ifndef MR_UNIX_MT
#ifndef MR_STATIC
mr_mip=NULL;
#endif
#endif
#endif
#endif
#ifdef MR_OPENMP_MT
mr_mip=NULL;
#endif
}
int exsign(flash x)
{ /* extract sign of big/flash number */
if ((x->len&(MR_MSBIT))==0) return PLUS;
else return MINUS;
}
void insign(int s,flash x)
{ /* assert sign of big/flash number */
if (x->len==0) return;
if (s<0) x->len|=MR_MSBIT;
else x->len&=MR_OBITS;
}
void mr_lzero(big x)
{ /* strip leading zeros from big number */
mr_lentype s;
int m;
s=(x->len&(MR_MSBIT));
m=(int)(x->len&(MR_OBITS));
while (m>0 && x->w[m-1]==0)
m--;
x->len=m;
if (m>0) x->len|=s;
}
#ifndef MR_SIMPLE_IO
int getdig(_MIPD_ big x,int i)
{ /* extract a packed digit */
int k;
mr_small n;
#ifdef MR_FP
mr_small dres;
#endif
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
i--;
n=x->w[i/mr_mip->pack];
if (mr_mip->pack==1) return (int)n;
k=i%mr_mip->pack;
for (i=1;i<=k;i++)
n=MR_DIV(n,mr_mip->apbase);
return (int)MR_REMAIN(n,mr_mip->apbase);
}
int numdig(_MIPD_ big x)
{ /* returns number of digits in x */
int nd;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (x->len==0) return 0;
nd=(int)(x->len&(MR_OBITS))*mr_mip->pack;
while (getdig(_MIPP_ x,nd)==0)
nd--;
return nd;
}
void putdig(_MIPD_ int n,big x,int i)
{ /* insert a digit into a packed word */
int j,k,lx;
mr_small m,p;
mr_lentype s;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(26)
s=(x->len&(MR_MSBIT));
lx=(int)(x->len&(MR_OBITS));
m=getdig(_MIPP_ x,i);
p=n;
i--;
j=i/mr_mip->pack;
k=i%mr_mip->pack;
for (i=1;i<=k;i++)
{
m*=mr_mip->apbase;
p*=mr_mip->apbase;
}
if (j>=mr_mip->nib && (mr_mip->check || j>=2*mr_mip->nib))
{
mr_berror(_MIPP_ MR_ERR_OVERFLOW);
MR_OUT
return;
}
x->w[j]=(x->w[j]-m)+p;
if (j>=lx) x->len=((j+1)|s);
mr_lzero(x);
MR_OUT
}
#endif
#ifndef MR_FP
void mr_and(big x,big y,big z)
{ /* z= bitwise logical AND of x and y */
int i,nx,ny,nz,nr;
if (x==y)
{
copy(x,z);
return;
}
#ifdef MR_FLASH
nx=mr_lent(x);
ny=mr_lent(y);
nz=mr_lent(z);
#else
ny=(y->len&(MR_OBITS));
nx=(x->len&(MR_OBITS));
nz=(z->len&(MR_OBITS));
#endif
if (ny<nx) nr=ny;
else nr=nx;
for (i=0;i<nr;i++)
z->w[i]=x->w[i]&y->w[i];
for (i=nr;i<nz;i++)
z->w[i]=0;
z->len=nr;
}
/*
void mr_or(big x,big y,big z)
{
int i,nx,ny,nz,nr;
if (x==y)
{
copy(x,z);
return;
}
#ifdef MR_FLASH
nx=mr_lent(x);
ny=mr_lent(y);
nz=mr_lent(z);
#else
ny=(y->len&(MR_OBITS));
nx=(x->len&(MR_OBITS));
nz=(z->len&(MR_OBITS));
#endif
if (ny<nx) nr=ny;
else nr=nx;
for (i=0;i<nr;i++)
z->w[i]=x->w[i]|y->w[i];
for (i=nr;i<nz;i++)
z->w[i]=0;
z->len=nr;
}
*/
#endif
void copy(flash x,flash y)
{ /* copy x to y: y=x */
int i,nx,ny;
mr_small *gx,*gy;
if (x==y || y==NULL) return;
if (x==NULL)
{
zero(y);
return;
}
#ifdef MR_FLASH
ny=mr_lent(y);
nx=mr_lent(x);
#else
ny=(y->len&(MR_OBITS));
nx=(x->len&(MR_OBITS));
#endif
gx=x->w;
gy=y->w;
for (i=nx;i<ny;i++)
gy[i]=0;
for (i=0;i<nx;i++)
gy[i]=gx[i];
y->len=x->len;
}
void negify(flash x,flash y)
{ /* negate a big/flash variable: y=-x */
copy(x,y);
if (y->len!=0) y->len^=MR_MSBIT;
}
void absol(flash x,flash y)
{ /* y=abs(x) */
copy(x,y);
y->len&=MR_OBITS;
}
BOOL mr_notint(flash x)
{ /* returns TRUE if x is Flash */
#ifdef MR_FLASH
if ((((x->len&(MR_OBITS))>>(MR_BTS))&(MR_MSK))!=0) return TRUE;
#endif
return FALSE;
}
void mr_shift(_MIPD_ big x,int n,big w)
{ /* set w=x.(mr_base^n) by shifting */
mr_lentype s;
int i,bl;
mr_small *gw=w->w;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
copy(x,w);
if (w->len==0 || n==0) return;
MR_IN(33)
if (mr_notint(w)) mr_berror(_MIPP_ MR_ERR_INT_OP);
s=(w->len&(MR_MSBIT));
bl=(int)(w->len&(MR_OBITS))+n;
if (bl<=0)
{
zero(w);
MR_OUT
return;
}
if (bl>mr_mip->nib && mr_mip->check) mr_berror(_MIPP_ MR_ERR_OVERFLOW);
if (mr_mip->ERNUM)
{
MR_OUT
return;
}
if (n>0)
{
for (i=bl-1;i>=n;i--)
gw[i]=gw[i-n];
for (i=0;i<n;i++)
gw[i]=0;
}
else
{
n=(-n);
for (i=0;i<bl;i++)
gw[i]=gw[i+n];
for (i=0;i<n;i++)
gw[bl+i]=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -