📄 mrcore.c
字号:
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_unsign32 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
}
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_unsign32 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;
}
w->len=(bl|s);
MR_OUT
}
int size(big x)
{ /* get size of big number; convert to *
* integer - if possible */
int n,m;
mr_unsign32 s;
if (x==NULL) return 0;
s=(x->len&MR_MSBIT);
m=(int)(x->len&MR_OBITS);
if (m==0) return 0;
if (m==1 && x->w[0]<(mr_small)MR_TOOBIG) n=(int)x->w[0];
else n=MR_TOOBIG;
if (s==MR_MSBIT) return (-n);
return n;
}
int compare(big x,big y)
{ /* compare x and y: =1 if x>y =-1 if x<y *
* =0 if x=y */
int m,n,sig;
mr_unsign32 sx,sy;
if (x==y) return 0;
sx=(x->len&MR_MSBIT);
sy=(y->len&MR_MSBIT);
if (sx==0) sig=PLUS;
else sig=MINUS;
if (sx!=sy) return sig;
m=(int)(x->len&MR_OBITS);
n=(int)(y->len&MR_OBITS);
if (m>n) return sig;
if (m<n) return -sig;
while (m>0)
{ /* check digit by digit */
m--;
if (x->w[m]>y->w[m]) return sig;
if (x->w[m]<y->w[m]) return -sig;
}
return 0;
}
#ifdef MR_FLASH
void fpack(_MIPD_ big n,big d,flash x)
{ /* create floating-slash number x=n/d from *
* big integer numerator and denominator */
mr_unsign32 s;
int i,ld,ln;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(31)
ld=(int)(d->len&MR_OBITS);
if (ld==0) mr_berror(_MIPP_ MR_ERR_FLASH_OVERFLOW);
if (ld==1 && d->w[0]==1) ld=0;
if (x==d) mr_berror(_MIPP_ MR_ERR_BAD_PARAMETERS);
if (mr_notint(n) || mr_notint(d)) mr_berror(_MIPP_ MR_ERR_INT_OP);
s=(n->len&MR_MSBIT);
ln=(int)(n->len&MR_OBITS);
if (ln==1 && n->w[0]==1) ln=0;
if ((ld+ln>mr_mip->nib) && (mr_mip->check || ld+ln>2*mr_mip->nib))
mr_berror(_MIPP_ MR_ERR_FLASH_OVERFLOW);
if (mr_mip->ERNUM)
{
MR_OUT
return;
}
copy(n,x);
if (n->len==0)
{
MR_OUT
return;
}
s^=(d->len&MR_MSBIT);
if (ld==0)
{
if (x->len!=0) x->len|=s;
MR_OUT
return;
}
for (i=0;i<ld;i++)
x->w[ln+i]=d->w[i];
x->len=(s|(ln+((mr_unsign32)ld<<MR_BTS)));
MR_OUT
}
void numer(_MIPD_ flash x,big y)
{ /* extract numerator of x */
int i,ln,ld;
mr_unsign32 s,ly;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
if (mr_notint(x))
{
s=(x->len&MR_MSBIT);
ly=(x->len&MR_OBITS);
ln=(int)(ly&MR_MSK);
if (ln==0)
{
if(s==MR_MSBIT) convert(_MIPP_ (-1),y);
else convert(_MIPP_ 1,y);
return;
}
ld=(int)((ly>>MR_BTS)&MR_MSK);
if (x!=y)
{
for (i=0;i<ln;i++) y->w[i]=x->w[i];
for (i=ln;i<mr_lent(y);i++) y->w[i]=0;
}
else for (i=0;i<ld;i++) y->w[ln+i]=0;
y->len=(ln|s);
}
else copy(x,y);
}
void denom(_MIPD_ flash x,big y)
{ /* extract denominator of x */
int i,ln,ld;
mr_unsign32 ly;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
if (!mr_notint(x))
{
convert(_MIPP_ 1,y);
return;
}
ly=(x->len&MR_OBITS);
ln=(int)(ly&MR_MSK);
ld=(int)((ly>>MR_BTS)&MR_MSK);
for (i=0;i<ld;i++)
y->w[i]=x->w[ln+i];
if (x==y) for (i=0;i<ln;i++) y->w[ld+i]=0;
else for (i=ld;i<mr_lent(y);i++) y->w[i]=0;
y->len=ld;
}
#endif
unsigned int igcd(unsigned int x,unsigned int y)
{ /* integer GCD, returns GCD of x and y */
unsigned int r;
if (y==0) return x;
while ((r=x%y)!=0)
x=y,y=r;
return y;
}
unsigned int isqrt(unsigned int num,unsigned int guess)
{ /* square root of an integer */
unsigned int sqr;
unsigned int oldguess=guess;
if (num==0) return 0;
if (num<4) return 1;
for (;;)
{ /* Newtons iteration */
/* sqr=guess+(((num/guess)-guess)/2); */
sqr=((num/guess)+guess)/2;
if (sqr==guess || sqr==oldguess)
{
if (sqr*sqr>num) sqr--;
return sqr;
}
oldguess=guess;
guess=sqr;
}
}
mr_small sgcd(mr_small x,mr_small y)
{ /* integer GCD, returns GCD of x and y */
mr_small r;
#ifdef MR_FP
mr_small dres;
#endif
if (y==(mr_small)0) return x;
while ((r=MR_REMAIN(x,y))!=(mr_small)0)
x=y,y=r;
return y;
}
/* routines to support sliding-windows exponentiation *
* in various contexts */
int mr_testbit(_MIPD_ big x,int n)
{ /* return value of n-th bit of big */
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
#ifdef MR_FP
mr_small m,a,dres;
m=mr_shiftbits((mr_small)1,n%mr_mip->lg2b);
a=x->w[n/mr_mip->lg2b];
a=MR_DIV(a,m);
if ((MR_DIV(a,2.0)*2.0) != a) return 1;
#else
if ((x->w[n/mr_mip->lg2b] & ((mr_small)1<<(n%mr_mip->lg2b))) >0) return 1;
#endif
return 0;
}
int mr_window(_MIPD_ big x,int i,int *nbs,int * nzs)
{ /* returns sliding window value, max. of 5 bits, *
* starting at i-th bit of big x. nbs is number of bits *
* processed, nzs is the number of additional trailing *
* zeros detected. Returns valid bit pattern 1x..x1 with *
* no two adjacent 0's. So 10101 will return 21 with *
* nbs=5, nzs=0. 11001 will return 3, with nbs=2, nzs=2, *
* having stopped after the first 11.. */
int j,r,w;
w=5;
/* check for leading 0 bit */
*nbs=1;
*nzs=0;
if (!mr_testbit(_MIPP_ x,i)) return 0;
/* adjust window size if not enough bits left */
if (i-w+1<0) w=i+1;
r=1;
for (j=i-1;j>i-w;j--)
{ /* accumulate bits. Abort if two 0's in a row */
(*nbs)++;
r*=2;
if (mr_testbit(_MIPP_ x,j)) r+=1;
if (r%4==0)
{ /* oops - too many zeros - shorten window */
r/=4;
*nbs-=2;
*nzs=2;
break;
}
}
if (r%2==0)
{ /* remove trailing 0 */
r/=2;
*nzs=1;
(*nbs)--;
}
return r;
}
int mr_window2(_MIPD_ big x,big y,int i,int *nbs,int *nzs)
{ /* two bit window for double exponentiation */
int r,w;
BOOL a,b,c,d;
w=2;
*nbs=1;
*nzs=0;
/* check for two leading 0's */
a=mr_testbit(_MIPP_ x,i); b=mr_testbit(_MIPP_ y,i);
if (!a && !b) return 0;
if (i<1) w=1;
if (a)
{
if (b) r=3;
else r=2;
}
else r=1;
if (w==1) return r;
c=mr_testbit(_MIPP_ x,i-1); d=mr_testbit(_MIPP_ y,i-1);
if (!c && !d)
{
*nzs=1;
return r;
}
*nbs=2;
r*=4;
if (c)
{
if (d) r+=3;
else r+=2;
}
else r+=1;
return r;
}
int mr_naf_window(_MIPD_ big x,big x3,int i,int *nbs,int *nzs)
{ /* returns sliding window value, max of 5 bits *
* starting at i-th bit of x. nbs is number of bits *
* processed. nzs is number of additional trailing *
* zeros detected. x and x3 (which is 3*x) are *
* combined to produce the NAF (non-adjacent form) *
* So if x=11011(27) and x3 is 1010001, the LSB is *
* ignored and the value 100T0T (32-4-1=27) processed, *
* where T is -1. Note x.P = (3x-x)/2.P. This value will *
* return +7, with nbs=4 and nzs=1, having stopped after *
* the first 4 bits. Note in an NAF non-zero elements *
* are never side by side, so 10T10T won't happen *
* NOTE: return value n zero or odd, -21 <= n <= +21 */
int nb,j,r,w;
BOOL last;
w=5;
/* get first bit */
nb=mr_testbit(_MIPP_ x3,i)-mr_testbit(_MIPP_ x,i);
*nbs=1;
*nzs=0;
if (nb==0) return 0;
last=FALSE;
if (i<=w)
{
w=i;
last=TRUE;
}
if (nb>0) r=1;
else r=(-1);
for (j=i-1;j>i-w;j--)
{ /* scan the bits */
(*nbs)++;
r*=2;
nb=mr_testbit(_MIPP_ x3,j)-mr_testbit(_MIPP_ x,j);
if (nb==0) continue;
if (nb>0) r+=1;
if (nb<0) r-=1;
}
if (!last && r%2!=0) (*nzs)++;
while (r%2==0)
{ /* remove trailing zeros */
r/=2;
(*nzs)++;
(*nbs)--;
}
return r;
}
/* Some general purpose elliptic curve stuff */
BOOL point_at_infinity(epoint *p)
{
if (p==NULL) return FALSE;
if (p->marker==MR_EPOINT_INFINITY) return TRUE;
return FALSE;
}
#ifndef MR_STATIC
epoint* epoint_init(_MIPDO_ )
{ /* initialise epoint to point at infinity. */
epoint *p;
char *ptr;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return NULL;
MR_IN(96)
/* Create space for whole structure in one heap access */
p=(epoint *)mr_alloc(_MIPP_ mr_esize(mr_mip->nib-1),1);
ptr=(char *)p+sizeof(epoint);
p->X=mirvar_mem(_MIPP_ ptr,0);
p->Y=mirvar_mem(_MIPP_ ptr,1);
#ifndef MR_AFFINE_ONLY
p->Z=mirvar_mem(_MIPP_ ptr,2);
#endif
p->marker=MR_EPOINT_INFINITY;
MR_OUT
return p;
}
#endif
epoint* epoint_init_mem_variable(char *mem,int index,int sz)
{
epoint *p;
char *ptr;
int offset,r;
offset=0;
r=(unsigned long)mem%MR_SL;
if (r>0) offset=MR_SL-r;
p=(epoint *)&mem[offset+index*mr_esize(sz)];
ptr=(char *)p+sizeof(epoint);
p->X=mirvar_mem_variable(ptr,0,sz);
p->Y=mirvar_mem_variable(ptr,1,sz);
#ifndef MR_AFFINE_ONLY
p->Z=mirvar_mem_variable(ptr,2,sz);
#endif
p->marker=MR_EPOINT_INFINITY;
return p;
}
epoint* epoint_init_mem(_MIPD_ char *mem,int index)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return NULL;
return epoint_init_mem_variable(mem,index,mr_mip->nib-1);
}
#ifndef MR_STATIC
/* allocate space for a number of epoints from the heap */
void *ecp_memalloc(_MIPD_ int num)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
return mr_alloc(_MIPP_ mr_ecp_reserve(num,mr_mip->nib-1),1);
}
#endif
void ecp_memkill(_MIPD_ char *mem,int num)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mem==NULL) return;
memset(mem,0,mr_ecp_reserve(num,mr_mip->nib-1));
#ifndef MR_STATIC
mr_free(mem);
#endif
}
#ifndef MR_STATIC
void epoint_free(epoint *p)
{ /* clean up point */
if (p==NULL) return;
zero(p->X);
zero(p->Y);
#ifndef MR_AFFINE_ONLY
zero(p->Z);
#endif
mr_free(p);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -