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 }
void mr_psub(_MIPD_ big x,big y,big z) { /* subtract two big numbers z=x-y * * where x and y are positive and x>y */ int i,lx,ly; mr_small borrow,pdiff; mr_small *gx,*gy,*gz; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif lx = (int)x->len; ly = (int)y->len; if (ly>lx) { mr_berror(_MIPP_ MR_ERR_NEG_RESULT); return; } if (y!=z) copy(x,z); else ly=lx; z->len=lx; gx=x->w; gy=y->w; gz=z->w; borrow=0; #ifndef MR_SIMPLE_BASE if (mr_mip->base==0) { #endif for (i=0;i<ly || borrow>0;i++) { /* subtract by columns */ if (i>lx) { mr_berror(_MIPP_ MR_ERR_NEG_RESULT); return; } pdiff=gx[i]-gy[i]-borrow; if (pdiff<gx[i]) borrow=0; else if (pdiff>gx[i]) borrow=1; gz[i]=pdiff; } #ifndef MR_SIMPLE_BASE } else for (i=0;i<ly || borrow>0;i++) { /* subtract by columns */ if (i>lx) { mr_berror(_MIPP_ MR_ERR_NEG_RESULT); return; } pdiff=gy[i]+borrow; borrow=0; if (gx[i]>=pdiff) pdiff=gx[i]-pdiff; else { /* set borrow */ pdiff=mr_mip->base+gx[i]-pdiff; borrow=1; } gz[i]=pdiff; } #endif mr_lzero(z); }
void fadd2(big a,big b,big c) { mr_small *aa,*bb,*cc; aa=a->w; bb=b->w; cc=c->w; cc[0]=aa[0]^bb[0]; cc[1]=aa[1]^bb[1]; cc[2]=aa[2]^bb[2]; cc[3]=aa[3]^bb[3]; cc[4]=aa[4]^bb[4]; c->len=WORDS; if (cc[4]==0) mr_lzero(c); }
void fincr2(big a,big c) { mr_small *aa,*cc; aa=a->w; cc=c->w; cc[0]^=aa[0]; cc[1]^=aa[1]; cc[2]^=aa[2]; cc[3]^=aa[3]; cc[4]^=aa[4]; c->len=WORDS; if (cc[4]==0) mr_lzero(c); }
void fadd2(big a,big b,big c) { mr_small *aa,*bb,*cc; aa=a->w; bb=b->w; cc=c->w; cc[0]=aa[0]^bb[0]; cc[1]=aa[1]^bb[1]; cc[2]=aa[2]^bb[2]; cc[3]=aa[3]^bb[3]; cc[4]=aa[4]^bb[4]; cc[5]=aa[5]^bb[5]; cc[6]=aa[6]^bb[6]; cc[7]=aa[7]^bb[7]; cc[8]=aa[8]^bb[8]; cc[9]=aa[9]^bb[9]; cc[10]=aa[10]^bb[10]; cc[11]=aa[11]^bb[11]; cc[12]=aa[12]^bb[12]; cc[13]=aa[13]^bb[13]; cc[14]=aa[14]^bb[14]; cc[15]=aa[15]^bb[15]; cc[16]=aa[16]^bb[16]; cc[17]=aa[17]^bb[17]; cc[18]=aa[18]^bb[18]; cc[19]=aa[19]^bb[19]; cc[20]=aa[20]^bb[20]; cc[21]=aa[21]^bb[21]; cc[22]=aa[22]^bb[22]; cc[23]=aa[23]^bb[23]; cc[24]=aa[24]^bb[24]; cc[25]=aa[25]^bb[25]; cc[26]=aa[26]^bb[26]; cc[27]=aa[27]^bb[27]; cc[28]=aa[28]^bb[28]; cc[29]=aa[29]^bb[29]; cc[30]=aa[30]^bb[30]; cc[31]=aa[31]^bb[31]; cc[32]=aa[32]^bb[32]; cc[33]=aa[33]^bb[33]; c->len=WORDS; if (cc[33]==0) mr_lzero(c); }
void fincr2(big a,big c) { mr_small *aa,*cc; aa=a->w; cc=c->w; cc[0]^=aa[0]; cc[1]^=aa[1]; cc[2]^=aa[2]; cc[3]^=aa[3]; cc[4]^=aa[4]; cc[5]^=aa[5]; cc[6]^=aa[6]; cc[7]^=aa[7]; cc[8]^=aa[8]; cc[9]^=aa[9]; cc[10]^=aa[10]; cc[11]^=aa[11]; cc[12]^=aa[12]; cc[13]^=aa[13]; cc[14]^=aa[14]; cc[15]^=aa[15]; cc[16]^=aa[16]; cc[17]^=aa[17]; cc[18]^=aa[18]; cc[19]^=aa[19]; cc[20]^=aa[20]; cc[21]^=aa[21]; cc[22]^=aa[22]; cc[23]^=aa[23]; cc[24]^=aa[24]; cc[25]^=aa[25]; cc[26]^=aa[26]; cc[27]^=aa[27]; cc[28]^=aa[28]; cc[29]^=aa[29]; cc[30]^=aa[30]; cc[31]^=aa[31]; cc[32]^=aa[32]; cc[33]^=aa[33]; c->len=WORDS; if (cc[33]==0) mr_lzero(c); }
void fastmodmult(_MIPD_ big x,big y,big z) { int ij; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif big w0=mr_mip->w0; big modulus=mr_mip->modulus; mr_small *wg,*mg,*xg,*yg; wg=w0->w; mg=modulus->w; xg=x->w; yg=y->w; for (ij=2*MR_PENTIUM;ij<(int)(w0->len&MR_OBITS);ij++) w0->w[ij]=0.0; w0->len=2*MR_PENTIUM; ASM { FSTEP MACRO i,j /* some fancy Pentium scheduling going on here ... */ fld POINTER [PBX+N*i] fmul POINTER [PSI+N*j] fxch st(2) fadd ENDM FRSTEP MACRO i,j fld POINTER [PDI+N*i] fmul POINTER [PSI+N*j] fxch st(2) fadd ENDM FDSTEP MACRO i,j fld POINTER [PBX+N*i] fmul POINTER [PBX+N*j] fxch st(2) fadd ENDM SELF MACRO k fld POINTER [PBX+N*k] fmul st,st(0) fadd ENDM RFINU MACRO k fld st(0) fadd st,st(2) fsub st,st(2) fsubr st,st(1) fmul st,st(4) fld st(0) fadd st,st(3) fsub st,st(3) fsub fst POINTER [PDI+N*k] fmul POINTER [PSI] fadd fmul st,st(2) ENDM RFIND MACRO k fld st(0) fadd st,st(2) fsub st,st(2) fsub st(1),st fmul st,st(3) fxch st(1) fstp POINTER [PDI+N*k] ENDM DIAG MACRO ns,ne CNT1=ns CNT2=ne fld POINTER [PBX+N*CNT1] fmul POINTER [PSI+N*CNT2] CNT1=CNT1+1 CNT2=CNT2-1 WHILE CNT1 LE ne FSTEP CNT1,CNT2 CNT1=CNT1+1 CNT2=CNT2-1 ENDM fadd ENDM SDIAG MACRO ns,ne CNT1=ns CNT2=ne IF CNT1 LT CNT2 fstp st(5) /* store carry */ fldz fld POINTER [PBX+N*CNT1] fmul POINTER [PBX+N*CNT2] CNT1=CNT1+1 CNT2=CNT2-1 WHILE CNT1 LT CNT2 FDSTEP CNT1,CNT2 CNT1=CNT1+1 CNT2=CNT2-1 ENDM fadd fld st(0) /* now double it ... */ fadd fadd st,st(5) /* add in carry */ ENDIF ENDM RDIAGU MACRO ns,ne CNT1=ns CNT2=ne IF CNT1 LT ne fld POINTER [PDI+N*CNT1] fmul POINTER [PSI+N*CNT2] CNT1=CNT1+1 CNT2=CNT2-1 WHILE CNT1 LT ne FRSTEP CNT1,CNT2 CNT1=CNT1+1 CNT2=CNT2-1 ENDM fadd ENDIF ENDM RDIAGD MACRO ns,ne CNT1=ns CNT2=ne fld POINTER [PDI+N*CNT1] fmul POINTER [PSI+N*CNT2] CNT1=CNT1+1 CNT2=CNT2-1 WHILE CNT1 LE ne FRSTEP CNT1,CNT2 CNT1=CNT1+1 CNT2=CNT2-1 ENDM fadd ENDM MODMULT MACRO CNT=0 WHILE CNT LT MR_PENTIUM DIAG 0,CNT xchg PSI,PCX RDIAGU 0,CNT RFINU CNT xchg PSI,PCX CNT=CNT+1 ENDM SCNT=0 WHILE SCNT LT (MR_PENTIUM-1) SCNT=SCNT+1 DIAG SCNT,(MR_PENTIUM-1) xchg PSI,PCX RDIAGD SCNT,(MR_PENTIUM-1) RFIND CNT xchg PSI,PCX CNT=CNT+1 ENDM RFIND CNT CNT=CNT+1 fstp POINTER [PDI+N*CNT] ENDM MODSQUARE MACRO CNT=0 WHILE CNT LT MR_PENTIUM SDIAG 0,CNT IF (CNT MOD 2) EQ 0 SELF (CNT/2) ENDIF RDIAGU 0,CNT RFINU CNT CNT=CNT+1 ENDM SCNT=0 WHILE SCNT LT (MR_PENTIUM-1) SCNT=SCNT+1 SDIAG SCNT,(MR_PENTIUM-1) IF (CNT MOD 2) EQ 0 SELF (CNT/2) ENDIF RDIAGD SCNT,(MR_PENTIUM-1) RFIND CNT CNT=CNT+1 ENDM RFIND CNT CNT=CNT+1 fstp POINTER [PDI+N*CNT] ENDM } ASM { push PDI push PSI mov PBX,xg mov PSI,yg mov PCX,mg mov PDI,wg fldz MODMULT pop PSI pop PDI } for (ij=MR_PENTIUM;ij<(int)(z->len&MR_OBITS);ij++) z->w[ij]=0.0; z->len=MR_PENTIUM; for (ij=0;ij<MR_PENTIUM;ij++) z->w[ij]=w0->w[ij+MR_PENTIUM]; if (z->w[MR_PENTIUM-1]==0.0) mr_lzero(z); }