/* * computes the loop of the algorithm. * for k=0 to h-1 * e=0 * for i=kw to kw+w-1 * if the bitIndex bit in ci is set: * calculate e += 2^(i-kw) * result = result *preComp[k][e] */ epoint* computeLoop(miracl* mip, big* exponentiations, int w, int h, epoint*** preComp, epoint* result, int bitIndex, int n, int field){ int e = 0, k, i, twoPow; big temp = mirvar(mip, 0); for (k=0; k<h; k++){ for (i=k*w; i<(k * w + w); i++){ if (i < n){ copy(exponentiations[i], temp); //check if the bit in bitIndex is set. //shift the big number bitIndex times sftbit(mip, temp, bitIndex*-1, temp); //check if the shifted big is divisible by two. if not - the first bit is set. if (subdivisible(mip, temp, 2) == 0){ twoPow = pow((double)2, i-k*w); e += twoPow; } } } //multiply operation depends on the field if (field == 1) ecurve_add(mip, preComp[k][e], result); else ecurve2_add(mip, preComp[k][e], result); e = 0; } mirkill(temp); return result; }
/* 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; }
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; }
void g(_MIPD_ epoint *A,epoint *B,zzn3 *Qx,zzn3 *Qy,zzn6 *w) { int type; big slope; zzn3 nn,dd; copy(A->X,mr_mip->w10); type=ecurve_add(_MIPP_ B,A); if (!type) { zzn6_from_int(_MIPP_ 1,w); return; } slope=mr_mip->w8; /* slope in w8 */ nn.a=mr_mip->w13; nn.b=mr_mip->w14; nn.c=mr_mip->w15; dd.a=mr_mip->w5; dd.b=mr_mip->w11; dd.c=mr_mip->w9; zzn3_copy(Qx,&nn); zzn3_copy(Qy,&dd); zzn3_negate(_MIPP_ &dd,&dd); #ifndef MR_AFFINE_ONLY if (A->marker!=MR_EPOINT_GENERAL) copy(mr_mip->one,mr_mip->w12); else copy(A->Z,mr_mip->w12); #else copy(mr_mip->one,mr_mip->w12); #endif if (type==MR_ADD) { zzn3_ssub(_MIPP_ &nn,B->X,&nn); zzn3_smul(_MIPP_ &nn,slope,&nn); nres_modmult(_MIPP_ mr_mip->w12,B->Y,mr_mip->w2); zzn3_sadd(_MIPP_ &nn,mr_mip->w2,&nn); zzn3_smul(_MIPP_ &dd,mr_mip->w12,&dd); zzn3_copy(&nn,&(w->x)); zzn3_copy(&dd,&(w->y)); return; } if (type==MR_DOUBLE) { /* note that ecurve_add has left useful things for us in w6 and w7! */ nres_modmult(_MIPP_ slope,mr_mip->w6,mr_mip->w2); zzn3_smul(_MIPP_ &nn,mr_mip->w2,&nn); nres_modmult(_MIPP_ slope,mr_mip->w10,slope); zzn3_ssub(_MIPP_ &nn,slope,&nn); zzn3_sadd(_MIPP_ &nn,mr_mip->w7,&nn); nres_modmult(_MIPP_ mr_mip->w12,mr_mip->w6,mr_mip->w12); zzn3_smul(_MIPP_ &dd,mr_mip->w12,&dd); zzn3_copy(&nn,&(w->x)); zzn3_copy(&dd,&(w->y)); return; } }