/* calculate a pubKey out of a given priKey */ int SM2_standard_sign_keygeneration(unsigned char PriKey[], unsigned char Px[], unsigned char Py[]) { int i = 0; big d, PAx, PAy; epoint *PA; SM2_standard_init(); PA = epoint_init(); d = mirvar(0); PAx = mirvar(0); PAy = mirvar(0); bytes_to_big(SM2_NUMWORD, PriKey, d); ecurve_mult(d, G, PA); epoint_get(PA, PAx, PAy); big_to_bytes(SM2_NUMWORD, PAx, Px, TRUE); big_to_bytes(SM2_NUMWORD, PAy, Py, TRUE); i = Test_PubKey(PA); if (i) return i; else return 0; }
/* * Class: edu_biu_scapi_primitives_dlog_miracl_MiraclDlogECFp * Method: initFpExponentiateWithPrecomputedValues * Signature: (J[B[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_MiraclDlogECFp_initFpExponentiateWithPrecomputedValues (JNIEnv *env, jobject, jlong m, jbyteArray p, jbyteArray a, jbyteArray b, jlong base, jbyteArray exponent, jint window, jint maxBits){ //translate parameters to miracl notation miracl* mip = (miracl*)m; big exponentB = byteArrayToMiraclBig(env, mip, exponent); big pB = byteArrayToMiraclBig(env, mip, p); big aB = byteArrayToMiraclBig(env, mip, a); big bB = byteArrayToMiraclBig(env, mip, b); //Create a new structure to hold the precomputed values for given base and exponent ebrick* exponentiations = new ebrick(); //Get the coordinates (x,y) from the requested base point: big x, y; x = mirvar(mip, 0); y = mirvar(mip, 0); epoint_get(mip, (epoint*)base, x, y); //Perform precomputation ebrick_init(mip, exponentiations, x, y, aB, bB, pB, window, maxBits); //clean up mirkill(exponentB); mirkill(pB); mirkill(aB); mirkill(bB); //Return the pointer to the structure where the precomputed values are held return (jlong)exponentiations; }
/* function validateFpGenerator : This function checks if the accepted point is the generator of EC over Fp, 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_MiraclDlogECFp_validateFpGenerator (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); epoint_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; }
int main() { FILE *fp; big e,n,a,b,x,y,r; epoint *g; ebrick binst; int i,d,ndig,nb,best,time,store,base,bits; miracl *mip=mirsys(50,0); n=mirvar(0); e=mirvar(0); a=mirvar(0); b=mirvar(0); x=mirvar(0); y=mirvar(0); r=mirvar(0); fp=fopen("common.ecs","r"); fscanf(fp,"%d\n",&bits); mip->IOBASE=16; cinnum(n,fp); cinnum(a,fp); cinnum(b,fp); cinnum(r,fp); cinnum(x,fp); cinnum(y,fp); mip->IOBASE=10; printf("modulus is %d bits in length\n",logb2(n)); printf("Enter size of exponent in bits = "); scanf("%d",&nb); getchar(); ebrick_init(&binst,x,y,a,b,n,nb); printf("%d big numbers have been precomputed and stored\n",binst.store); bigdig(nb,2,e); /* random exponent */ printf("naive method\n"); ecurve_init(a,b,n,MR_PROJECTIVE); g=epoint_init(); epoint_set(x,y,0,g); ecurve_mult(e,g,g); epoint_get(g,x,y); cotnum(x,stdout); cotnum(y,stdout); printf("Brickel et al method\n"); mul_brick(&binst,e,x,y); ebrick_end(&binst); cotnum(x,stdout); cotnum(y,stdout); return 0; }
/* function isFpMember : This function checks if the accepted point is a point of the current elliptic curve (over Fp) * 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_MiraclDlogECFp_isFpMember (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); epoint_get(mip, (epoint*)point, x, y); /* try to create another point with those values. if succeded - the point is in the curve */ if (epoint_set(mip, x, y, 0, p)==1) member = 1; mirkill(x); mirkill(y); return member; }
/* function invertFpPoint : 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_MiraclDlogECFp_invertFpPoint (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 the values to it p2 = epoint_init(mip); epoint_get(mip, (epoint*)p1, x, y); epoint_set(mip, x,y,0, p2); mirkill(x); mirkill(y); //inverse the point epoint_negate(mip, p2); return (jlong)p2; // return the inverse }
/* function multiplyFpPoints : This function multiplies two point of ec over Fp * 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_MiraclDlogECFp_multiplyFpPoints (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); epoint_get(mip, (epoint*)p2, x, y); epoint_set(mip, x,y,0, p3); mirkill(x); mirkill(y); /* The multiply operation is converted to addition because miracl treat EC as additive group */ ecurve_add(mip, (epoint*)p1, p3); return (jlong)p3; //return the result }
JNIEXPORT jobjectArray JNICALL Java_com_sunshuzhou_experiment_1miracl_Verify_computeForServer(JNIEnv *env, jobject instance, jstring ux_, jstring uy_, jstring u1x_, jstring u1y_, jstring wx_, jstring wy_, jstring com1x_, jstring com1y_, jstring N1_, jstring sid_, jstring alpha_, jstring beta_, jstring zeta_) { const char *ux = (*env)->GetStringUTFChars(env, ux_, 0); const char *uy = (*env)->GetStringUTFChars(env, uy_, 0); const char *u1x = (*env)->GetStringUTFChars(env, u1x_, 0); const char *u1y = (*env)->GetStringUTFChars(env, u1y_, 0); const char *wx = (*env)->GetStringUTFChars(env, wx_, 0); const char *wy = (*env)->GetStringUTFChars(env, wy_, 0); const char *com1x = (*env)->GetStringUTFChars(env, com1x_, 0); const char *com1y = (*env)->GetStringUTFChars(env, com1y_, 0); const char *N1 = (*env)->GetStringUTFChars(env, N1_, 0); const char *sid = (*env)->GetStringUTFChars(env, sid_, 0); const char *alpha = (*env)->GetStringUTFChars(env, alpha_, 0); const char *beta = (*env)->GetStringUTFChars(env, beta_, 0); const char *zeta = (*env)->GetStringUTFChars(env, zeta_, 0); big x, y, d, k1, N2, sum, big1; epoint *u, *u1, *w, *com1, *w1, *epoint1, *com, *K; int message_len, i; unsigned char key[300], tag[SHA1_HASH_SIZE], hexdigest[SHA1_HASH_SIZE * 2 + 1], message[1000], tempChars[300]; jclass jclass1 = (*env)->FindClass(env, "java/lang/String"); jobjectArray result; envirment_init(); x = mirvar(0); y = mirvar(0); d = mirvar(0); k1 = mirvar(0); N2 = mirvar(0); sum = mirvar(0); big1 = mirvar(0); u = epoint_init(); u1 = epoint_init(); w = epoint_init(); com1 = epoint_init(); w1 = epoint_init(); epoint1 = epoint_init(); com = epoint_init(); K = epoint_init(); cinstr(x, ux); cinstr(y, uy); epoint_set(x, y, 0, u); cinstr(x, u1x); cinstr(y, u1y); epoint_set(x, y, 0, u1); cinstr(x, wx); cinstr(y, wy); epoint_set(x, y, 0, w); cinstr(x, com1x); cinstr(y, com1y); epoint_set(x, y, 0, com1); irand((long)time(0)); bigrand(ECC_N, d); bigrand(ECC_N, k1); bigbits(80, N2); // sum = alpha + beta + zeta cinstr(big1, alpha); cinstr(sum, beta); add(big1, sum, sum); cinstr(big1, zeta); add(big1, sum, sum); // w1 = k1 * H ecurve_mult(k1, ECC_H, w1); // com = (alpha + beta + zeta) * u + d * H ecurve_mult(sum, u, com); ecurve_mult(d, ECC_H, epoint1); ecurve_add(epoint1, com); // K = d * w + k1 * (com1 - sum * u1) ecurve_mult(d, w, K); ecurve_mult(sum, u1, epoint1); ecurve_sub(epoint1, com1); ecurve_mult(k1, com1, com1); ecurve_add(com1, K); // K.y as key epoint_get(K, x, y); cotstr(y, key); // message: u.y || u1.y || w.y || com1.y || N1 || sid epoint_get(u, x, y); cotstr(y, message); message_len = strlen(message); epoint_get(u1, x, y); cotstr(y, &message[message_len]); message_len = strlen(message); epoint_get(w, x, y); cotstr(y, &message[message_len]); message_len = strlen(message); epoint_get(com1, x, y); cotstr(x, &message[message_len]); message_len = strlen(message); strcpy(&message[message_len], N1); message_len = strlen(message); strcpy(&message[message_len], sid); message_len = strlen(message); hmac_sha1(key, strlen(key), message, message_len, tag, SHA1_HASH_SIZE); for (i = 0; i < SHA1_HASH_SIZE; ++i) { sprintf(&hexdigest[i * 2], "%02x", tag[i]); } hexdigest[40] = '\0'; (*env)->ReleaseStringUTFChars(env, ux_, ux); (*env)->ReleaseStringUTFChars(env, uy_, uy); (*env)->ReleaseStringUTFChars(env, u1x_, u1x); (*env)->ReleaseStringUTFChars(env, u1y_, u1y); (*env)->ReleaseStringUTFChars(env, wx_, wx); (*env)->ReleaseStringUTFChars(env, wy_, wy); (*env)->ReleaseStringUTFChars(env, com1x_, com1x); (*env)->ReleaseStringUTFChars(env, com1y_, com1y); (*env)->ReleaseStringUTFChars(env, N1_, N1); (*env)->ReleaseStringUTFChars(env, sid_, sid); (*env)->ReleaseStringUTFChars(env, alpha_, alpha); (*env)->ReleaseStringUTFChars(env, beta_, beta); (*env)->ReleaseStringUTFChars(env, zeta_, zeta); result = (*env)->NewObjectArray(env, 8, jclass1, (*env)->NewStringUTF(env, "")); epoint_get(w1, x, y); cotstr(x, tempChars); (*env)->SetObjectArrayElement(env, result, 0, (*env)->NewStringUTF(env, tempChars)); cotstr(y, tempChars); (*env)->SetObjectArrayElement(env, result, 1, (*env)->NewStringUTF(env, tempChars)); epoint_get(com, x, y); cotstr(x, tempChars); (*env)->SetObjectArrayElement(env, result, 2, (*env)->NewStringUTF(env, tempChars)); cotstr(y, tempChars); (*env)->SetObjectArrayElement(env, result, 3, (*env)->NewStringUTF(env, tempChars)); cotstr(N2, tempChars); (*env)->SetObjectArrayElement(env, result, 4, (*env)->NewStringUTF(env, tempChars)); (*env)->SetObjectArrayElement(env, result, 5, (*env)->NewStringUTF(env, message)); (*env)->SetObjectArrayElement(env, result, 6, (*env)->NewStringUTF(env, hexdigest)); (*env)->SetObjectArrayElement(env, result, 7, (*env)->NewStringUTF(env, key)); mirkill(x); mirkill(y); mirkill(d); mirkill(k1); mirkill(N2); mirkill(sum); mirkill(big1); return result; }
/* 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; }
/* SM2 signature algorithm */ int SM2_standard_sign(unsigned char *message, int len, unsigned char ZA[], unsigned char rand[], unsigned char d[], 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 dA, r, s, e, k, KGx, KGy; big rem, rk, z1, z2; epoint *KG; i = SM2_standard_init(); if (i) return i; //initiate dA = mirvar(0); e = mirvar(0); k = mirvar(0); KGx = mirvar(0); KGy = mirvar(0); r = mirvar(0); s = mirvar(0); rem = mirvar(0); rk = mirvar(0); z1 = mirvar(0); z2 = mirvar(0); bytes_to_big(SM2_NUMWORD, d, dA); //cinstr(dA, d); KG = epoint_init(); //step1, set M = ZA || M M = (char *)malloc(sizeof(char)*(M_len + 1)); memcpy(M, ZA, SM3_len / 8); memcpy(M + SM3_len / 8, message, len); //step2, generate e = H(M) SM3_256(M, M_len, hash); bytes_to_big(SM3_len / 8, hash, e); //step3:generate k bytes_to_big(SM3_len / 8, rand, k); //step4:calculate kG ecurve_mult(k, G, KG); //step5:calculate r epoint_get(KG, KGx, KGy); add(e, KGx, r); divide(r, para_n, rem); //judge r = 0 or n + k = n? add(r, k, rk); if (Test_Zero(r) | Test_n(rk)) return ERR_GENERATE_R; //step6:generate s incr(dA, 1, z1); xgcd(z1, para_n, z1, z1, z1); multiply(r, dA, z2); divide(z2, para_n, rem); subtract(k, z2, z2); add(z2, para_n, z2); multiply(z1, z2, s); divide(s, para_n, rem); //judge s = 0? if (Test_Zero(s)) return ERR_GENERATE_S ; big_to_bytes(SM2_NUMWORD, r, R, TRUE); big_to_bytes(SM2_NUMWORD, s, S, TRUE); free(M); return 0; }
int main() { int ia,ib; time_t seed; epoint *g,*ea,*eb; big a,b,p,q,n,p1,q1,phi,pa,pb,key,e,d,dp,dq,t,m,c,x,y,k,inv; big primes[2],pm[2]; big_chinese ch; miracl *mip; #ifndef MR_NOFULLWIDTH mip=mirsys(500,0); #else mip=mirsys(500,MAXBASE); #endif a=mirvar(0); b=mirvar(0); p=mirvar(0); q=mirvar(0); n=mirvar(0); p1=mirvar(0); q1=mirvar(0); phi=mirvar(0); pa=mirvar(0); pb=mirvar(0); key=mirvar(0); e=mirvar(0); d=mirvar(0); dp=mirvar(0); dq=mirvar(0); t=mirvar(0); m=mirvar(0); c=mirvar(0); pm[0]=mirvar(0); pm[1]=mirvar(0); x=mirvar(0); y=mirvar(0); k=mirvar(0); inv=mirvar(0); time(&seed); irand((unsigned long)seed); /* change parameter for different values */ printf("First Diffie-Hellman Key exchange .... \n"); cinstr(p,primetext); /* offline calculations could be done quicker using Comb method - See brick.c. Note use of "truncated exponent" of 160 bits - could be output of hash function SHA (see mrshs.c) */ printf("\nAlice's offline calculation\n"); bigbits(160,a); /* 3 generates the sub-group of prime order (p-1)/2 */ powltr(3,a,p,pa); printf("Bob's offline calculation\n"); bigbits(160,b); powltr(3,b,p,pb); printf("Alice calculates Key=\n"); powmod(pb,a,p,key); cotnum(key,stdout); printf("Bob calculates Key=\n"); powmod(pa,b,p,key); cotnum(key,stdout); printf("Alice and Bob's keys should be the same!\n"); /* Now Elliptic Curve version of the above. Curve is y^2=x^3+Ax+B mod p, where A=-3, B and p as above "Primitive root" is the point (x,y) above, which is of large prime order q. In this case actually q=FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831 */ printf("\nLets try that again using elliptic curves .... \n"); convert(-3,a); mip->IOBASE=16; cinstr(b,ecb); cinstr(p,ecp); ecurve_init(a,b,p,MR_BEST); /* Use PROJECTIVE if possible, else AFFINE coordinates */ g=epoint_init(); cinstr(x,ecx); cinstr(y,ecy); mip->IOBASE=10; epoint_set(x,y,0,g); ea=epoint_init(); eb=epoint_init(); epoint_copy(g,ea); epoint_copy(g,eb); printf("Alice's offline calculation\n"); bigbits(160,a); ecurve_mult(a,ea,ea); ia=epoint_get(ea,pa,pa); /* <ia,pa> is compressed form of public key */ printf("Bob's offline calculation\n"); bigbits(160,b); ecurve_mult(b,eb,eb); ib=epoint_get(eb,pb,pb); /* <ib,pb> is compressed form of public key */ printf("Alice calculates Key=\n"); epoint_set(pb,pb,ib,eb); /* decompress eb */ ecurve_mult(a,eb,eb); epoint_get(eb,key,key); cotnum(key,stdout); printf("Bob calculates Key=\n"); epoint_set(pa,pa,ia,ea); /* decompress ea */ ecurve_mult(b,ea,ea); epoint_get(ea,key,key); cotnum(key,stdout); printf("Alice and Bob's keys should be the same! (but much smaller)\n"); epoint_free(g); epoint_free(ea); epoint_free(eb); /* El Gamal's Method */ printf("\nTesting El Gamal's public key method\n"); cinstr(p,primetext); bigbits(160,x); /* x<p */ powltr(3,x,p,y); /* y=3^x mod p*/ decr(p,1,p1); mip->IOBASE=128; cinstr(m,text); mip->IOBASE=10; do { bigbits(160,k); } while (egcd(k,p1,t)!=1); powltr(3,k,p,a); /* a=3^k mod p */ powmod(y,k,p,b); mad(b,m,m,p,p,b); /* b=m*y^k mod p */ printf("Ciphertext= \n"); cotnum(a,stdout); cotnum(b,stdout); zero(m); /* proof of pudding... */ subtract(p1,x,t); powmod(a,t,p,m); mad(m,b,b,p,p,m); /* m=b/a^x mod p */ printf("Plaintext= \n"); mip->IOBASE=128; cotnum(m,stdout); mip->IOBASE=10; /* RSA. Generate primes p & q. Use e=65537, and find d=1/e mod (p-1)(q-1) */ printf("\nNow generating 512-bit random primes p and q\n"); do { bigbits(512,p); if (subdivisible(p,2)) incr(p,1,p); while (!isprime(p)) incr(p,2,p); bigbits(512,q); if (subdivisible(q,2)) incr(q,1,q); while (!isprime(q)) incr(q,2,q); multiply(p,q,n); /* n=p.q */ lgconv(65537L,e); decr(p,1,p1); decr(q,1,q1); multiply(p1,q1,phi); /* phi =(p-1)*(q-1) */ } while (xgcd(e,phi,d,d,t)!=1); cotnum(p,stdout); cotnum(q,stdout); printf("n = p.q = \n"); cotnum(n,stdout); /* set up for chinese remainder thereom */ /* primes[0]=p; primes[1]=q; crt_init(&ch,2,primes); */ /* use simple CRT as only two primes */ xgcd(p,q,inv,inv,inv); /* 1/p mod q */ copy(d,dp); copy(d,dq); divide(dp,p1,p1); /* dp=d mod p-1 */ divide(dq,q1,q1); /* dq=d mod q-1 */ mip->IOBASE=128; cinstr(m,text); mip->IOBASE=10; printf("Encrypting test string\n"); powmod(m,e,n,c); printf("Ciphertext= \n"); cotnum(c,stdout); zero(m); printf("Decrypting test string\n"); powmod(c,dp,p,pm[0]); /* get result mod p */ powmod(c,dq,q,pm[1]); /* get result mod q */ subtract(pm[1],pm[0],pm[1]); /* poor man's CRT */ mad(inv,pm[1],inv,q,q,m); multiply(m,p,m); add(m,pm[0],m); /* crt(&ch,pm,m); combine them using CRT */ printf("Plaintext= \n"); mip->IOBASE=128; cotnum(m,stdout); /* crt_end(&ch); */ return 0; }
int main() { FILE *fp; big e,n,a,b,x,y,r; epoint *g; ebrick binst; int nb,bits,window,len,bptr,m,i,j; miracl *mip=mirsys(50,0); n=mirvar(0); e=mirvar(0); a=mirvar(0); b=mirvar(0); x=mirvar(0); y=mirvar(0); r=mirvar(0); #ifndef MR_EDWARDS fp=fopen("common.ecs","rt"); #else fp=fopen("edwards.ecs","rt"); #endif fscanf(fp,"%d\n",&bits); mip->IOBASE=16; cinnum(n,fp); cinnum(a,fp); cinnum(b,fp); cinnum(r,fp); cinnum(x,fp); cinnum(y,fp); mip->IOBASE=10; printf("modulus is %d bits in length\n",logb2(n)); printf("Enter max. size of exponent in bits = "); scanf("%d",&nb); getchar(); printf("Enter window size in bits (1-10)= "); scanf("%d",&window); getchar(); ebrick_init(&binst,x,y,a,b,n,window,nb); /* Print out the precomputed table (for use in ecdhp.c ?) In which case make sure that MR_SPECIAL is defined and active in the build of this program, so MR_COMBA must also be defined as the number of words in the modulus * len=MR_ROUNDUP(bits,MIRACL); bptr=0; for (i=0;i<2*(1<<window);i++) { for (j=0;j<len;j++) { printf("0x%x,",binst.table[bptr++]); } printf("\n"); } */ printf("%d elliptic curve points have been precomputed and stored\n",(1<< window)); bigbits(nb,e); /* random exponent */ printf("naive method\n"); ecurve_init(a,b,n,MR_PROJECTIVE); g=epoint_init(); epoint_set(x,y,0,g); ecurve_mult(e,g,g); epoint_get(g,x,y); cotnum(x,stdout); cotnum(y,stdout); printf("Comb method\n"); mul_brick(&binst,e,x,y); ebrick_end(&binst); cotnum(x,stdout); cotnum(y,stdout); return 0; }
int ECn::get(Big& x) const {return epoint_get(p,x.getbig(),x.getbig());}
int main() { FILE *fp; char ifname[50],ofname[50]; big a,b,p,q,x,y,d,r,s,k,hash; epoint *g; long seed; int bits; miracl instance; miracl *mip=&instance; char mem[MR_BIG_RESERVE(11)]; /* reserve space on the stack for 11 bigs */ char mem1[MR_ECP_RESERVE(1)]; /* and one elliptic curve points */ memset(mem,0,MR_BIG_RESERVE(11)); memset(mem1,0,MR_ECP_RESERVE(1)); /* get public data */ #ifndef MR_EDWARDS fp=fopen("common.ecs","rt"); if (fp==NULL) { printf("file common.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&bits); #else fp=fopen("edwards.ecs","rt"); if (fp==NULL) { printf("file edwards.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&bits); #endif mirsys(mip,bits/4,16); /* Use Hex internally */ a=mirvar_mem(mip,mem,0); b=mirvar_mem(mip,mem,1); p=mirvar_mem(mip,mem,2); q=mirvar_mem(mip,mem,3); x=mirvar_mem(mip,mem,4); y=mirvar_mem(mip,mem,5); d=mirvar_mem(mip,mem,6); r=mirvar_mem(mip,mem,7); s=mirvar_mem(mip,mem,8); k=mirvar_mem(mip,mem,9); hash=mirvar_mem(mip,mem,10); innum(mip,p,fp); /* modulus */ innum(mip,a,fp); /* curve parameters */ innum(mip,b,fp); innum(mip,q,fp); /* order of (x,y) */ innum(mip,x,fp); /* (x,y) point on curve of order q */ innum(mip,y,fp); fclose(fp); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(mip,seed); ecurve_init(mip,a,b,p,MR_PROJECTIVE); /* initialise curve */ g=epoint_init_mem(mip,mem1,0); epoint_set(mip,x,y,0,g); /* initialise point of order q */ /* calculate r - this can be done offline, and hence amortized to almost nothing */ bigrand(mip,q,k); ecurve_mult(mip,k,g,g); /* see ebrick.c for method to speed this up */ epoint_get(mip,g,r,r); divide(mip,r,q,q); /* get private key of signer */ fp=fopen("private.ecs","rt"); if (fp==NULL) { printf("file private.ecs does not exist\n"); return 0; } innum(mip,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(mip,fp,hash); fclose(fp); /* calculate s */ xgcd(mip,k,q,k,k,k); mad(mip,d,r,hash,q,q,s); mad(mip,s,k,k,q,q,s); fp=fopen(ofname,"wt"); otnum(mip,r,fp); otnum(mip,s,fp); fclose(fp); memset(mem,0,MR_BIG_RESERVE(11)); memset(mem1,0,MR_ECP_RESERVE(1)); return 0; }
int SM9_standard_key_encap(unsigned char hid[], unsigned char *IDB, unsigned char rand[], unsigned char Ppub[], unsigned char C[], unsigned char K[], int Klen) { big h, x, y, r; epoint *Ppube, *QB, *Cipher; unsigned char *Z = NULL; int Zlen, buf, i, num = 0; zzn12 g, w; //initiate h = mirvar(0); r = mirvar(0); x = mirvar(0); y = mirvar(0); QB = epoint_init(); Ppube = epoint_init(); Cipher = epoint_init(); zzn12_init(&g); zzn12_init(&w); bytes_to_big(BNLEN, Ppub, x); bytes_to_big(BNLEN, Ppub + BNLEN, y); epoint_set(x, y, 0, Ppube); //----------Step1:calculate QB=[H1(IDB||hid,N)]P1+Ppube---------- Zlen = strlen(IDB) + 1; Z = (char *)malloc(sizeof(char)*(Zlen + 1)); if(Z == NULL) return SM9_ASK_MEMORY_ERR; memcpy(Z, IDB, strlen(IDB)); memcpy(Z + strlen(IDB), hid, 1); buf = SM9_standard_h1(Z, Zlen, N, h); free(Z); if(buf) return buf; printf("\n************************ H1(IDB||hid,N) ************************\n"); cotnum(h, stdout); ecurve_mult(h, P1, QB); ecurve_add(Ppube, QB); printf("\n*******************QB:=[H1(IDB||hid,N)]P1+Ppube*****************\n"); epoint_get(QB, x, y); cotnum(x, stdout); cotnum(y, stdout); //-------------------- Step2:randnom ------------------- bytes_to_big(BNLEN, rand, r); printf("\n***********************randnum r: ******************************\n"); cotnum(r, stdout); //----------------Step3:C=[r]QB------------------------ ecurve_mult(r, QB, Cipher); epoint_get(Cipher, x, y); printf("\n*********************** C=[r]QB: ******************************\n"); cotnum(x, stdout); cotnum(y, stdout); big_to_bytes(BNLEN, x, C, 1); big_to_bytes(BNLEN, y, C + BNLEN, 1); //----------------Step4:g=e(Ppube,P2)------------------------ if(!ecap(P2, Ppube, para_t, X, &g)) return SM9_MY_ECAP_12A_ERR; //test if a ZZn12 element is of order q if(!member(g, para_t, X)) return SM9_MEMBER_ERR; printf("\n***********************g=e(Ppube,P2):****************************\n"); zzn12_ElementPrint(g); //----------------Step5:w=g^r------------------------ w = zzn12_pow(g, r); printf("\n************************* w=g^r:*********************************\n"); zzn12_ElementPrint(w); //----------------Step6:K=KDF(C||w||IDB,klen)------------------------ Zlen = strlen(IDB) + BNLEN * 14; Z = (char *)malloc(sizeof(char)*(Zlen + 1)); if(Z == NULL) return SM9_ASK_MEMORY_ERR; LinkCharZzn12(C, BNLEN * 2, w, Z, BNLEN * 14); memcpy(Z + BNLEN * 14, IDB, strlen(IDB)); SM3_kdf(Z, Zlen, Klen, K); free(Z); //----------------test if K equals 0------------------------ printf("\n******************* K=KDF(C||w||IDB,klen):***********************\n"); for(i = 0; i < Klen; i++) { if(K[i] == 0) num += 1; printf("%02x", K[i]); } if(num == Klen) return SM9_ERR_K1_ZERO; return 0; }
int main() { FILE *fp; int ep,bits; epoint *g,*w; big a,b,p,q,x,y,d; long seed; miracl instance; miracl *mip=&instance; char mem[MR_BIG_RESERVE(7)]; /* reserve space on the stack for 7 bigs */ char mem1[MR_ECP_RESERVE(2)]; /* and two elliptic curve points */ memset(mem,0,MR_BIG_RESERVE(7)); memset(mem1,0,MR_ECP_RESERVE(2)); #ifndef MR_EDWARDS fp=fopen("common.ecs","rt"); if (fp==NULL) { printf("file common.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&bits); #else fp=fopen("edwards.ecs","rt"); if (fp==NULL) { printf("file edwards.ecs does not exist\n"); return 0; } fscanf(fp,"%d\n",&bits); #endif mirsys(mip,bits/4,16); /* Use Hex internally */ a=mirvar_mem(mip,mem,0); b=mirvar_mem(mip,mem,1); p=mirvar_mem(mip,mem,2); q=mirvar_mem(mip,mem,3); x=mirvar_mem(mip,mem,4); y=mirvar_mem(mip,mem,5); d=mirvar_mem(mip,mem,6); innum(mip,p,fp); innum(mip,a,fp); innum(mip,b,fp); innum(mip,q,fp); innum(mip,x,fp); innum(mip,y,fp); fclose(fp); /* randomise */ printf("Enter 9 digit random number seed = "); scanf("%ld",&seed); getchar(); irand(mip,seed); ecurve_init(mip,a,b,p,MR_PROJECTIVE); /* initialise curve */ g=epoint_init_mem(mip,mem1,0); w=epoint_init_mem(mip,mem1,1); if (!epoint_set(mip,x,y,0,g)) /* initialise point of order q */ { printf("Problem - point (x,y) is not on the curve\n"); exit(0); } ecurve_mult(mip,q,g,w); if (!point_at_infinity(w)) { printf("Problem - point (x,y) is not of order q\n"); exit(0); } /* generate public/private keys */ bigrand(mip,q,d); ecurve_mult(mip,d,g,g); ep=epoint_get(mip,g,x,x); /* compress point */ printf("public key = %d ",ep); otnum(mip,x,stdout); fp=fopen("public.ecs","wt"); fprintf(fp,"%d ",ep); otnum(mip,x,fp); fclose(fp); fp=fopen("private.ecs","wt"); otnum(mip,d,fp); fclose(fp); /* clear all memory used */ memset(mem,0,MR_BIG_RESERVE(7)); memset(mem1,0,MR_ECP_RESERVE(2)); return 0; }
int main() { int promptr; epoint *PB; big A,B,p,a,b,pa,pb,key; ebrick 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(8)]; /* we need 8 bigs... */ char mem_ecp[MR_ECP_RESERVE(1)]; /* ..and 1 elliptic curve points */ memset(mem_big, 0, MR_BIG_RESERVE(8)); /* clear the memory */ memset(mem_ecp, 0, MR_ECP_RESERVE(1)); 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); a=mirvar_mem(mip, mem_big, 5); b=mirvar_mem(mip, mem_big, 6); p=mirvar_mem(mip, mem_big, 7); PB=epoint_init_mem(mip, mem_ecp, 0); /* initialise Elliptic Curve points */ irand(mip, 3L); /* change parameter for different random numbers */ promptr=0; init_big_from_rom(p,WORDS,rom,WORDS*5,&promptr); /* Read in prime modulus p from ROM */ init_big_from_rom(B,WORDS,rom,WORDS*5,&promptr); /* Read in curve parameter B from ROM */ /* don't need q or G(x,y) (we have precomputed table from it) */ convert(mip,-3,A); /* set A=-3 */ /* Create precomputation instance from precomputed table in ROM */ ebrick_init(&binst,prom,A,B,p,WINDOW,CURVE_BITS); /* offline calculations */ bigbits(mip,CURVE_BITS,a); /* A's random number */ mul_brick(mip,&binst,a,pa,pa); /* a*G =(pa,ya) */ bigbits(mip,CURVE_BITS,b); /* B's random number */ mul_brick(mip,&binst,b,pb,pb); /* b*G =(pb,yb) */ /* swap X values of point */ /* online calculations */ ecurve_init(mip,A,B,p,MR_PROJECTIVE); epoint_set(mip,pb,pb,0,PB); /* decompress PB */ ecurve_mult(mip,a,PB,PB); epoint_get(mip,PB,key,key); /* since internal base is HEX, can use otnum instead of cotnum - avoiding a base change */ #ifndef MR_NO_STANDARD_IO printf("Alice's Key= "); otnum(mip,key,stdout); #endif epoint_set(mip,pa,pa,0,PB); /* decompress PA */ ecurve_mult(mip,b,PB,PB); epoint_get(mip,PB,key,key); #ifndef MR_NO_STANDARD_IO printf("Bob's Key= "); otnum(mip,key,stdout); #endif /* clear the memory */ memset(mem_big, 0, MR_BIG_RESERVE(8)); memset(mem_ecp, 0, MR_ECP_RESERVE(1)); return 0; }