/* * Class: edu_biu_scapi_primitives_dlog_miracl_MiraclDlogECF2m * Method: initF2mExponentiateWithPrecomputedValues * Signature: (JIIII[B[BJ[BII)J * * This function wraps the creation of an ebrick structure used to precompute exponentiations for a certain base for Dlog groups over Fp. It returns * a pointer to the ebrick structure which will be kept by the calling application (edu.biu.scapi...) in some data structure and will * be used for further calls to exponentiations with the same base. */ JNIEXPORT jlong JNICALL Java_edu_biu_scapi_primitives_dlog_miracl_MiraclDlogECF2m_initF2mExponentiateWithPrecomputedValues (JNIEnv * env, jobject, jlong mipp, jint mod, jint k1, jint k2, jint k3, jbyteArray a, jbyteArray b, jlong base, jint window, jint maxBits){ //translate parameters to miracl notation miracl* mip = (miracl*)mipp; big aB = byteArrayToMiraclBig(env, mip, a); big bB = byteArrayToMiraclBig(env, mip, b); //Get the coordinates (x,y) from the requested base point: big x, y; x = mirvar(mip, 0); y = mirvar(mip, 0); epoint2_get(mip, (epoint*)base, x, y); //Create a new structure to hold the precomputed values for given base and exponent ebrick2* exponentiations = new ebrick2(); //Perform precomputation ebrick2_init(mip, exponentiations, x, y, aB, bB, mod, k1, k2, k3, window, maxBits); //clean up mirkill(aB); mirkill(bB); //May be clan up also x and y mirkill(x); mirkill(y); //Return the pointer to the structure where the precomputed values are held return (jlong)exponentiations; }

/* 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; }

/* function getXValue : This function return the x coordinate of the given point * param m : pointer to mip * param point : pointer to the point * return : the x coordinate of the given point */ JNIEXPORT jbyteArray JNICALL Java_edu_biu_scapi_primitives_dlog_miracl_ECF2mPointMiracl_getXValueF2mPoint (JNIEnv *env, jobject obj, jlong m, jlong point){ /* convert the accepted parameters to MIRACL parameters*/ miracl* mip = (miracl*)m; big x, y; jbyteArray xBytes; x= mirvar(mip, 0); y= mirvar(mip, 0); //get x, y values of the point epoint2_get(mip, (epoint*)point, x, y); xBytes = miraclBigToJbyteArray(env, mip, x); mirkill(x); mirkill(y); //return the bytes of x return xBytes; }

/* function invertF2mPoint : This function return the inverse of ec point * param m : miracl pointer * param p1 : ellitic curve point * return : the inverse point */ JNIEXPORT jlong JNICALL Java_edu_biu_scapi_primitives_dlog_miracl_MiraclDlogECF2m_invertF2mPoint (JNIEnv *env, jobject obj, jlong m, jlong p1){ /* convert the accepted parameters to MIRACL parameters*/ miracl* mip = (miracl*)m; big x, y; epoint* p2; x= mirvar(mip, 0); y= mirvar(mip, 0); //init the result point and copy p1 values to it p2 = epoint_init(mip); epoint2_get(mip, (epoint*)p1, x, y); epoint2_set(mip, x,y,0, p2); mirkill(x); mirkill(y); //inverse the point epoint2_negate(mip, p2); return (jlong)p2; // return the inverse }

/* function isF2mMember : This function checks if the accepted point is a point of the current elliptic curve (over F2m) * param m : miracl pointer * param point : ellitic curve point to check * return : true if the point is on the curve, false otherwise */ JNIEXPORT jboolean JNICALL Java_edu_biu_scapi_primitives_dlog_miracl_MiraclDlogECF2m_isF2mMember (JNIEnv *env, jobject obj, jlong m, jlong point){ int member = 0; /* convert the accepted parameters to MIRACL parameters*/ miracl* mip = (miracl*)m; /* get the x,y, values of the point */ big x,y; epoint* p = epoint_init(mip); x = mirvar(mip, 0); y = mirvar(mip, 0); epoint2_get(mip, (epoint*)point, x, y); /* try to create another point with those values. if succeded - the point is in the curve */ if (epoint2_set(mip, x, y, 0, p)==1) member = 1; mirkill(x); mirkill(y); return member; }

/* function multiplyF2mPoints : This function multiplies two point of ec over F2m * param m : miracl pointer * param p1 : ellitic curve point * param p2 : ellitic curve point * return : the multiplication result */ JNIEXPORT jlong JNICALL Java_edu_biu_scapi_primitives_dlog_miracl_MiraclDlogECF2m_multiplyF2mPoints (JNIEnv *env, jobject obj, jlong m, jlong p1, jlong p2){ big x, y; epoint *p3; /* convert the accepted parameters to MIRACL parameters*/ miracl* mip = (miracl*)m; x= mirvar(mip, 0); y= mirvar(mip, 0); /* create the result point with the values of p2. This way, p2 values won't damage in the multiplication operation */ p3 = epoint_init(mip); epoint2_get(mip, (epoint*)p2, x, y); epoint2_set(mip, x,y,0, p3); mirkill(x); mirkill(y); /* The multiply operation is converted to addition because miracl treat EC as additive group */ ecurve2_add(mip, (epoint*)p1, p3); return (jlong)p3; //return the result }

int main() { int ia,ib,promptr; epoint *PA,*PB; big A,B,a,b,q,pa,pb,key,x,y; ebrick2 binst; miracl instance; /* create miracl workspace on the stack */ /* Specify base 16 here so that HEX can be read in directly without a base-change */ miracl *mip=mirsys(&instance,WORDS*HEXDIGS,16); /* size of bigs is fixed */ char mem_big[MR_BIG_RESERVE(10)]; /* we need 10 bigs... */ char mem_ecp[MR_ECP_RESERVE(2)]; /* ..and two elliptic curve points */ memset(mem_big, 0, MR_BIG_RESERVE(10)); /* clear the memory */ memset(mem_ecp, 0, MR_ECP_RESERVE(2)); A=mirvar_mem(mip, mem_big, 0); /* Initialise big numbers */ B=mirvar_mem(mip, mem_big, 1); pa=mirvar_mem(mip, mem_big, 2); pb=mirvar_mem(mip, mem_big, 3); key=mirvar_mem(mip, mem_big, 4); x=mirvar_mem(mip, mem_big, 5); y=mirvar_mem(mip, mem_big, 6); q=mirvar_mem(mip,mem_big,7); a=mirvar_mem(mip, mem_big, 8); b=mirvar_mem(mip, mem_big, 9); PA=epoint_init_mem(mip, mem_ecp, 0); /* initialise Elliptic Curve points */ PB=epoint_init_mem(mip, mem_ecp, 1); irand(mip, 3L); /* change parameter for different random numbers */ promptr=0; init_big_from_rom(B,WORDS,rom,WORDS*4,&promptr); /* Read in curve parameter B from ROM */ /* don't need q or G(x,y) (we have precomputed table from it) */ init_big_from_rom(q,WORDS,rom,WORDS*4,&promptr); init_big_from_rom(x,WORDS,rom,WORDS*4,&promptr); init_big_from_rom(y,WORDS,rom,WORDS*4,&promptr); convert(mip,1,A); /* set A=1 */ /* Create precomputation instance from precomputed table in ROM */ ebrick2_init(&binst,prom,A,B,CURVE_M,CURVE_A,CURVE_B,CURVE_C,WINDOW,CURVE_M); /* offline calculations */ bigbits(mip,CURVE_M,a); /* A's random number */ ia=mul2_brick(mip,&binst,a,pa,pa); /* a*G =(pa,ya), ia is sign of ya */ bigbits(mip,CURVE_M,b); /* B's random number */ ib=mul2_brick(mip,&binst,b,pb,pb); /* b*G =(pb,yb), ib is sign of yb */ /* online calculations */ ecurve2_init(mip,CURVE_M,CURVE_A,CURVE_B,CURVE_C,A,B,FALSE,MR_PROJECTIVE); epoint2_set(mip,pb,pb,ib,PB); /* decompress PB */ ecurve2_mult(mip,a,PB,PB); epoint2_get(mip,PB,key,key); /* since internal base is HEX, can use otnum instead of cotnum - avoiding a base change */ printf("Alice's Key= "); otnum(mip,key,stdout); epoint2_set(mip,pa,pa,ia,PB); /* decompress PA */ ecurve2_mult(mip,b,PB,PB); epoint2_get(mip,PB,key,key); printf("Bob's Key= "); otnum(mip,key,stdout); /* clear the memory */ memset(mem_big, 0, MR_BIG_RESERVE(10)); memset(mem_ecp, 0, MR_ECP_RESERVE(2)); return 0; }

int main() { FILE *fp; int m,a,b,c; big e,a2,a6,x,y,r; epoint *g; ebrick2 binst; int i,d,ndig,nb,best,time,store,base; miracl *mip=mirsys(50,0); e=mirvar(0); a2=mirvar(0); a6=mirvar(0); x=mirvar(0); y=mirvar(0); r=mirvar(0); fp=fopen("common2.ecs","r"); fscanf(fp,"%d\n",&m); mip->IOBASE=16; cinnum(a2,fp); cinnum(a6,fp); cinnum(r,fp); cinnum(x,fp); cinnum(y,fp); mip->IOBASE=10; fscanf(fp,"%d\n",&a); fscanf(fp,"%d\n",&b); fscanf(fp,"%d\n",&c); printf("modulus is %d bits in length\n",m); printf("Enter size of exponent in bits = "); scanf("%d",&nb); getchar(); ebrick2_init(&binst,x,y,a2,a6,m,a,b,c,nb); printf("%d big numbers have been precomputed and stored\n",binst.store); bigdig(nb,2,e); /* random exponent */ printf("naive method\n"); ecurve2_init(m,a,b,c,a2,a6,FALSE,MR_PROJECTIVE); g=epoint2_init(); epoint2_set(x,y,0,g); ecurve2_mult(e,g,g); epoint2_get(g,x,y); cotnum(x,stdout); cotnum(y,stdout); zero(x); zero(y); printf("Brickel et al method\n"); mul2_brick(&binst,e,x,y); ebrick2_end(&binst); cotnum(x,stdout); cotnum(y,stdout); return 0; }

int EC2::get(Big& x) const {return epoint2_get(p,x.getbig(),x.getbig());}

int main() { FILE *fp; int m,a,b,c,cf; miracl *mip; char ifname[13],ofname[13]; big a2,a6,q,x,y,d,r,s,k,hash; epoint *g; long seed; /* get public data */ fp=fopen("common2.ecs","r"); if (fp==NULL) { printf("file common2.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&m); mip=mirsys(3+m/MIRACL,0); a2=mirvar(0); a6=mirvar(0); q=mirvar(0); x=mirvar(0); y=mirvar(0); d=mirvar(0); r=mirvar(0); s=mirvar(0); k=mirvar(0); hash=mirvar(0); mip->IOBASE=16; cinnum(a2,fp); /* curve parameters */ cinnum(a6,fp); /* curve parameters */ cinnum(q,fp); /* order of (x,y) */ cinnum(x,fp); /* (x,y) point on curve of order q */ cinnum(y,fp); mip->IOBASE=10; fscanf(fp,"%d\n",&a); fscanf(fp,"%d\n",&b); fscanf(fp,"%d\n",&c); fclose(fp); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(seed); ecurve2_init(m,a,b,c,a2,a6,FALSE,MR_PROJECTIVE); /* initialise curve */ g=epoint2_init(); epoint2_set(x,y,0,g); /* set point of order q */ /* calculate r - this can be done offline, and hence amortized to almost nothing */ bigrand(q,k); ecurve2_mult(k,g,g); /* see ebrick2.c for method to speed this up */ epoint2_get(g,r,r); divide(r,q,q); /* get private key of signer */ fp=fopen("private.ecs","r"); if (fp==NULL) { printf("file private.ecs does not exist\n"); return 0; } cinnum(d,fp); fclose(fp); /* calculate message digest */ printf("file to be signed = "); gets(ifname); strcpy(ofname,ifname); strip(ofname); strcat(ofname,".ecs"); if ((fp=fopen(ifname,"rb"))==NULL) { printf("Unable to open file %s\n",ifname); return 0; } hashing(fp,hash); fclose(fp); /* calculate s */ xgcd(k,q,k,k,k); mad(d,r,hash,q,q,s); mad(s,k,k,q,q,s); fp=fopen(ofname,"w"); cotnum(r,fp); cotnum(s,fp); fclose(fp); return 0; }