/* function validateF2mGenerator : This function checks if the accepted point is the generator of EC over F2m, by compare its values to the accepted x,y values * param m : miracl pointer * param generator : ellitic curve point to check * param xVal : x value of the generator * param yVal : y value of the generator * return : true if the generator is valid or not */ JNIEXPORT jboolean JNICALL Java_edu_biu_scapi_primitives_dlog_miracl_MiraclAdapterDlogEC_validateF2mGenerator (JNIEnv *env, jobject obj, jlong m, jlong generator, jbyteArray xVal, jbyteArray yVal){ /* convert the accepted parameters to MIRACL parameters*/ miracl* mip = (miracl*)m; big x = byteArrayToMiraclBig(env, mip, xVal); big y = byteArrayToMiraclBig(env, mip, yVal); /* get the point's x,y values */ big genX, genY; jboolean result; genX= mirvar(mip, 0); genY= mirvar(mip, 0); epoint2_get(mip, (epoint*)generator, genX, genY); /* check if the values are as expected, return the result */ if (mr_compare(genX, x)==0 && mr_compare(genY, y)==0) result = 1; else result = 0; mirkill(x); mirkill(y); mirkill(genX); mirkill(genY); return result; }
mr_small prepare_monty(_MIPD_ big n) { /* prepare Montgomery modulus */ #ifdef MR_KCM int nl; #endif #ifdef MR_PENTIUM mr_small ndash; mr_small base; mr_small magic=13835058055282163712.0; int control=0x1FFF; #endif #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return (mr_small)0; /* Is it set-up already? */ if (size(mr_mip->modulus)!=0) if (mr_compare(n,mr_mip->modulus)==0) return mr_mip->ndash; MR_IN(80) if (size(n)<=2) { mr_berror(_MIPP_ MR_ERR_BAD_MODULUS); MR_OUT return (mr_small)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 }
/* test if the big x is order n */ int Test_n(big x) { //bytes_to_big(32, SM2_n, n); if (mr_compare(x, para_n) == 0) return 1; else return 0; }
/* test if the big x is zero */ int Test_Zero(big x) { big zero; zero = mirvar(0); if (mr_compare(x, zero) == 0) return 1; else return 0; }
BOOL zzn3_isunity(_MIPD_ zzn3 *x) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM || size(x->b)!=0 || size(x->c)!=0) return FALSE; if (mr_compare(x->a,mr_mip->one)==0) return TRUE; return FALSE; }
int invmodp(_MIPD_ big a,big p,big z) { #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif big u,v,x1,x2; MR_IN(213); u=mr_mip->w1; v=mr_mip->w2; x1=mr_mip->w3; x2=mr_mip->w4; copy(a,u); copy(p,v); convert(_MIPP_ 1,x1); zero(x2); while (size(u)!=1 && size(v)!=1) { while (remain(_MIPP_ u,2)==0) { subdiv(_MIPP_ u,2,u); if (remain(_MIPP_ x1,2)!=0) add(_MIPP_ x1,p,x1); subdiv(_MIPP_ x1,2,x1); } while (remain(_MIPP_ v,2)==0) { subdiv(_MIPP_ v,2,v); if (remain(_MIPP_ x2,2)!=0) add(_MIPP_ x2,p,x2); subdiv(_MIPP_ x2,2,x2); } if (mr_compare(u,v)>=0) { mr_psub(_MIPP_ u,v,u); subtract(_MIPP_ x1,x2,x1); } else { mr_psub(_MIPP_ v,u,v); subtract(_MIPP_ x2,x1,x2); } } if (size(u)==1) copy(x1,z); else copy(x2,z); if (size(z)<0) add(_MIPP_ z,p,z); MR_OUT return 1; /* note - no checking that gcd=1 */ }
int mcl_ecpbs_verify(mcl_ecpbs_signature *signature, char *info, char *message, mcl_ecpbs_parameters *parameters, mcl_ecpbs_pk *pk, mcl_ecpbs_workspace *workspace) { add(signature->omega, signature->delta, workspace->result); mcl_ecpbs_mod(workspace->result, parameters->q); mcl_ecpbs_Fhash(workspace->z, info, parameters); ecurve_mult2(signature->rho, parameters->g, signature->omega, pk->key, workspace->alpha); ecurve_mult2(signature->sigma, parameters->g, signature->delta, workspace->z, workspace->beta); mcl_ecpbs_hash_epsilon(workspace->check, workspace->alpha, workspace->beta, workspace->z, message, parameters); return mr_compare(workspace->result, workspace->check); }
int fcomp(_MIPD_ flash x,flash y) { /* compares two Flash numbers * * returns -1 if y>x; +1 if x>y; 0 if x=y */ #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif if (mr_mip->ERNUM) return 0; MR_IN(39) numer(_MIPP_ x,mr_mip->w1); denom(_MIPP_ y,mr_mip->w2); mr_mip->check=OFF; multiply(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w5); numer(_MIPP_ y,mr_mip->w1); denom(_MIPP_ x,mr_mip->w2); multiply(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w0); mr_mip->check=ON; MR_OUT return (mr_compare(mr_mip->w5,mr_mip->w0)); }
BOOL zzn2_compare(zzn2 *x,zzn2 *y) { if (mr_compare(x->a,y->a)==0 && mr_compare(x->b,y->b)==0) return TRUE; return FALSE; }
int main() { FILE *fp; big p,q,h,g,n,s,t; long seed; miracl *mip=mirsys(100,0); p=mirvar(0); q=mirvar(0); h=mirvar(0); g=mirvar(0); n=mirvar(0); s=mirvar(0); t=mirvar(0); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(seed); /* generate q */ forever { bigbits(QBITS,q); nxprime(q,q); if (logb2(q)>QBITS) continue; break; } printf("q= "); cotnum(q,stdout); /* generate p */ expb2(PBITS,t); decr(t,1,t); premult(q,2,n); divide(t,n,t); expb2(PBITS-1,s); decr(s,1,s); divide(s,n,s); forever { bigrand(t,p); if (mr_compare(p,s)<=0) continue; premult(p,2,p); multiply(p,q,p); incr(p,1,p); copy(p,n); if (isprime(p)) break; } printf("p= "); cotnum(p,stdout); /* generate g */ do { decr(p,1,t); bigrand(t,h); divide(t,q,t); powmod(h,t,p,g); } while (size(g)==1); printf("g= "); cotnum(g,stdout); fp=fopen("common.dss","wt"); fprintf(fp,"%d\n",PBITS); mip->IOBASE=16; cotnum(p,fp); cotnum(q,fp); cotnum(g,fp); fclose(fp); return 0; }
/* SM2 verification algorithm */ int SM2_standard_verify(unsigned char *message, int len, unsigned char ZA[], unsigned char Px[], unsigned char Py[], unsigned char R[], unsigned char S[]) { unsigned char hash[SM3_len / 8]; int M_len = len + SM3_len / 8; unsigned char *M = NULL; int i; big PAx, PAy, r, s, e, t, rem, x1, y1; big RR; epoint *PA, *sG, *tPA; i = SM2_standard_init(); if (i) return i; PAx = mirvar(0); PAy = mirvar(0); r = mirvar(0); s = mirvar(0); e = mirvar(0); t = mirvar(0); x1 = mirvar(0); y1 = mirvar(0); rem = mirvar(0); RR = mirvar(0); PA = epoint_init(); sG = epoint_init(); tPA = epoint_init(); bytes_to_big(SM2_NUMWORD, Px, PAx); bytes_to_big(SM2_NUMWORD, Py, PAy); bytes_to_big(SM2_NUMWORD, R, r); bytes_to_big(SM2_NUMWORD, S, s); if (!epoint_set(PAx, PAy, 0, PA)) //initialise public key { return ERR_PUBKEY_INIT; } //step1: test if r belong to [1, n-1] if (Test_Range(r)) return ERR_OUTRANGE_R; //step2: test if s belong to [1, n-1] if (Test_Range(s)) return ERR_OUTRANGE_S; //step3, generate M M = (char *)malloc(sizeof(char)*(M_len + 1)); memcpy(M, ZA, SM3_len / 8); memcpy(M + SM3_len / 8, message, len); //step4, generate e = H(M) SM3_256(M, M_len, hash); bytes_to_big(SM3_len / 8, hash, e); //step5:generate t add(r, s, t); divide(t, para_n, rem); if (Test_Zero(t)) return ERR_GENERATE_T; //step 6: generate(x1, y1) ecurve_mult(s, G, sG); ecurve_mult(t, PA, tPA); ecurve_add(sG, tPA); epoint_get(tPA, x1, y1); //step7:generate RR add(e, x1, RR); divide(RR, para_n, rem); free(M); if (mr_compare(RR, r) == 0) return 0; else return ERR_DATA_MEMCMP; }
epoint* computeLL(miracl* mip, epoint** elements, big* exponents, int n, int field){ big bigExp = mirvar(mip, 0); big two = mirvar(mip, 2); big zero = mirvar(mip, 0); int t = 0, w, h, i, j; epoint*** preComp; epoint* result; //get the biggest exponent for (i=0; i<n; i++) if (mr_compare(bigExp, exponents[i]) < 0) bigExp = exponents[i]; //num of bitf in the biggest exponent t = logb2(mip, bigExp); //choose w according to the value of t w = getLLW(t); //h = n/w if ((n % w) == 0){ h = n / w; } else{ h = ((int) (n / w)) + 1; } //printf("n is: %d\n", n); //printf("t is: %d\n", t); //printf("w is: %d\n", w); //printf("h is: %d\n", h); //creates pre computation table preComp = createLLPreCompTable(mip, elements, w, h, n, field); result = getIdentity(mip, field); //holds the computation result //computes the loop of the computation result = computeLoop(mip, exponents, w, h, preComp, result, t-1, n, field); //third part of computation for (j=t-2; j>=0; j--){ //operate y^2 differently. depends on the field type if (field==1) ecurve_mult(mip, two, result, result); else ecurve2_mult(mip, two, result, result); //computes the loop of the computation result = computeLoop(mip, exponents, w, h, preComp, result, j, n, field); } //free the allocated memeory mirkill(two); mirkill(zero); for (i=0; i<h; i++){ for (j=0; j<pow((double)2, w); j++){ epoint_free(preComp[i][j]); } free(preComp[i]); } free(preComp); return result; }
static void mr_select(_MIPD_ big x,int d,big y,big z) { /* perform required add or subtract operation */ int sx,sy,sz,jf,xgty; #ifdef MR_FLASH if (mr_notint(x) || mr_notint(y)) { mr_berror(_MIPP_ MR_ERR_INT_OP); return; } #endif sx=exsign(x); sy=exsign(y); sz=0; x->len&=MR_OBITS; /* force operands to be positive */ y->len&=MR_OBITS; xgty=mr_compare(x,y); jf=(1+sx)+(1+d*sy)/2; switch (jf) { /* branch according to signs of operands */ case 0: if (xgty>=0) mr_padd(_MIPP_ x,y,z); else mr_padd(_MIPP_ y,x,z); sz=MINUS; break; case 1: if (xgty<=0) { mr_psub(_MIPP_ y,x,z); sz=PLUS; } else { mr_psub(_MIPP_ x,y,z); sz=MINUS; } break; case 2: if (xgty>=0) { mr_psub(_MIPP_ x,y,z); sz=PLUS; } else { mr_psub(_MIPP_ y,x,z); sz=MINUS; } break; case 3: if (xgty>=0) mr_padd(_MIPP_ x,y,z); else mr_padd(_MIPP_ y,x,z); sz=PLUS; break; } if (sz<0) z->len^=MR_MSBIT; /* set sign of result */ if (x!=z && sx<0) x->len^=MR_MSBIT; /* restore signs to operands */ if (y!=z && y!=x && sy<0) y->len^=MR_MSBIT; }
int main() { /* decode using private key */ int i; big e,ep[NP],m,ke,kd,p[NP],kp[NP],mn,mx; FILE *ifile; FILE *ofile; char ifname[13],ofname[13]; BOOL flo; big_chinese ch; mip=mirsys(100,0); for (i=0;i<NP;i++) { p[i]=mirvar(0); ep[i]=mirvar(0); kp[i]=mirvar(0); } e=mirvar(0); m=mirvar(0); kd=mirvar(0); ke=mirvar(0); mn=mirvar(0); mx=mirvar(0); mip->IOBASE=16; if ((ifile=fopen("private.key","rt"))==NULL) { printf("Unable to open file private.key\n"); return 0; } for (i=0;i<NP;i++) { cinnum(p[i],ifile); } fclose(ifile); /* generate public and private keys */ convert(1,ke); for (i=0;i<NP;i++) { multiply(ke,p[i],ke); } for (i=0;i<NP;i++) { /* kp[i]=(2*(p[i]-1)+1)/3 = 1/3 mod p[i]-1 */ decr(p[i],1,kd); premult(kd,2,kd); incr(kd,1,kd); subdiv(kd,3,kp[i]); } crt_init(&ch,NP,p); nroot(ke,3,mn); multiply(mn,mn,m); multiply(mn,m,mx); subtract(mx,m,mx); do { /* get input file */ printf("file to be decoded = "); gets(ifname); } while (strlen(ifname)==0); strip(ifname); strcat(ifname,".rsa"); printf("output filename = "); gets(ofname); flo=FALSE; if (strlen(ofname)>0) { /* set up output file */ flo=TRUE; ofile=fopen(ofname,"wt"); } printf("decoding message\n"); if ((ifile=fopen(ifname,"rt"))==NULL) { printf("Unable to open file %s\n",ifname); return 0; } forever { /* decode line by line */ mip->IOBASE=16; cinnum(m,ifile); if (size(m)==0) break; for (i=0;i<NP;i++) powmod(m,kp[i],p[i],ep[i]); crt(&ch,ep,e); /* Chinese remainder thereom */ if (mr_compare(e,mx)>=0) divide(e,mn,mn); mip->IOBASE=128; if (flo) cotnum(e,ofile); cotnum(e,stdout); } crt_end(&ch); fclose(ifile); if (flo) fclose(ofile); printf("message ends\n"); return 0; }
int main() { FILE *fp; big q,p,p1,h,t,g,low,high; big pool[POOL_SIZE]; BOOL fail; int i,j,p1bits,np; long seed,m,permutation; miracl *mip=mirsys(100,0); q=mirvar(0); p=mirvar(0); h=mirvar(0); t=mirvar(0); g=mirvar(0); p1=mirvar(0); low=mirvar(0); high=mirvar(0); gprime(10000); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(seed); p1bits=PBITS-QBITS-1; /* find number of primes pa, pb, pc etc., that will be needed */ np=1; while (p1bits/np >= OBITS) np++; np--; /* find the high/low limits for these primes, so that the generated prime p will be exactly PBITS in length */ expb2(p1bits-1,t); nroot(t,np,low); /* np-th integer root */ incr(low,1,low); premult(t,2,t); decr(t,1,t); nroot(t,np,high); subtract(high,low,t); /* raise low limit up to half-way... */ subdiv(t,2,t); subtract(high,t,low); /* generate q */ forever { /* make sure leading two bits of q 11... */ expb2(QBITS,q); bigbits(QBITS-2,t); subtract(q,t,q); nxprime(q,q); if (logb2(q)>QBITS) continue; break; } printf("q= (%d bits)\n",logb2(q)); cotnum(q,stdout); /* generate prime pool from which permutations of np primes will be picked until a Lim-Lee prime is found */ for (i=0;i<POOL_SIZE;i++) { /* generate the primes pa, pb, pc etc.. */ pool[i]=mirvar(0); forever { bigrand(high,p1); if (mr_compare(p1,low)<0) continue; nxprime(p1,p1); if (mr_compare(p1,high)>0) continue; copy(p1,pool[i]); break; } } /* The '1' bits in the permutation indicate which primes are picked from the pool. If np=5, start at 11111, then 101111 etc */ permutation=1L; for (i=0;i<np;i++) permutation<<=1; permutation-=1; /* permuation = 2^np-1 */ /* generate p */ fail=FALSE; forever { convert(1,p1); for (i=j=0,m=1L;j<np;i++,m<<=1) { if (i>=POOL_SIZE) { /* ran out of primes... */ fail=TRUE; break; } if (m&permutation) { multiply(p1,pool[i],p1); j++; } } if (fail) break; printf("."); premult(q,2,p); multiply(p,p1,p); incr(p,1,p); permutation=increment(permutation); if (logb2(p)!=PBITS) continue; if (isprime(p)) break; } if (fail) { printf("\nFailed - very unlikely! - try increasing POOL_SIZE\n"); return 0; } printf("\np= (%d bits)\n",logb2(p)); cotnum(p,stdout); /* finally find g */ do { decr(p,1,t); bigrand(t,h); divide(t,q,t); powmod(h,t,p,g); } while(size(g)==1); printf("g= (%d bits)\n",logb2(g)); cotnum(g,stdout); fp=fopen("common.dss","wt"); fprintf(fp,"%d\n",PBITS); mip->IOBASE=16; cotnum(p,fp); cotnum(q,fp); cotnum(g,fp); fclose(fp); return 0; }