int bb_verify(unsigned char *sig, unsigned int hashlen, unsigned char *hash, bb_public_key_t pk) { element_t sigma, r; element_t m; element_t t0, t1, t2; int res; int len; pairing_ptr pairing = pk->param->pairing; element_init(m, pairing->Zr); element_from_hash(m, hash, hashlen); element_init(sigma, pairing->G1); len = element_from_bytes_x_only(sigma, sig); element_init(r, pairing->Zr); element_from_bytes(r, sig + len); element_init(t0, pairing->G2); element_init(t1, pairing->G2); element_init(t2, pairing->GT); element_pow_zn(t0, pk->g2, m); element_pow_zn(t1, pk->v, r); element_mul(t0, t0, t1); element_mul(t0, t0, pk->u); element_pairing(t2, sigma, t0); if (!element_cmp(t2, pk->z)) { res = 1; } else { element_mul(t2, t2, pk->z); res = element_is1(t2); } element_clear(t0); element_clear(t1); element_clear(t2); element_clear(m); element_clear(sigma); element_clear(r); return res; }
// USER JOIN PHASE 2 - user key generation (Join) int xsgs_user_join_phase2(XSGS_PUBLIC_KEY* gpk, XSGS_USER_DB_ENTRY* udbe, XSGS_ISSUER_KEY* ik, XSGS_PAILLIER_PUBKEY* ppk, XSGS_JOIN_PHASE1* jpd1, XSGS_JOIN_PHASE2* jpd2) { int ret; pairing_ptr pairing = gpk->pairing; field_ptr Fp = pairing->Zr; mpz_t r1, h; //, t; element_t R1, R2, g1, B, D, zp, gt, hp; mpz_init(h); mpz_from_hash(h, jpd1->U.hash, JOIN_HASH_BITS / 8); // 1. verify C e G1 and check U // R1 = g^s * c^h mod n^2 mpz_init(r1); mpz_powm2(r1, ppk->g, jpd1->U.s, jpd1->U.c, h, ppk->n_squared); // R2 = H^s * C^h element_init_G1(R2, pairing); element_pow_naf2_mpz(R2, gpk->H, jpd1->U.s, jpd1->C, h); mpz_clear(h); // h = H(g, n, c, C, H, R1, R2) DWORD data_len = mpz_length_in_bytes(ppk->g) + mpz_length_in_bytes(ppk->n_squared) + mpz_length_in_bytes(jpd1->U.c) + element_length_in_bytes(jpd1->C) + element_length_in_bytes(gpk->H) + mpz_length_in_bytes(r1) + element_length_in_bytes(R2); BYTE* data_buf = (BYTE*) malloc(data_len); data_buf += mpz_to_bytes(data_buf, ppk->g); data_buf += mpz_to_bytes(data_buf, ppk->n_squared); data_buf += mpz_to_bytes(data_buf, jpd1->U.c); data_buf += element_to_bytes(data_buf, jpd1->C); data_buf += element_to_bytes(data_buf, gpk->H); data_buf += mpz_to_bytes(data_buf, r1); data_buf += element_to_bytes(data_buf, R2); data_buf -= data_len; BYTE* hash = (BYTE*) malloc(JOIN_HASH_BITS / 8); xsgs_hash(data_buf, data_len * 8, hash, JOIN_HASH_BITS); free(data_buf); mpz_clear(r1); element_clear(R2); // compare hashes ret = memcmp(jpd1->U.hash, hash, JOIN_HASH_BITS / 8); free(hash); if (!ret) { element_t r; // initialization element_init(udbe->UCert.x, Fp); element_init_G1(udbe->UCert.A, pairing); element_init_G1(udbe->C, pairing); element_init_G1(jpd2->A, pairing); element_init_G1(g1, pairing); element_init_GT(B, pairing); element_init_GT(gt, pairing); element_init(zp, Fp); // save jpd1->C to ubde->C element_set(udbe->C, jpd1->C); // 2. x eR Zp and element_random(udbe->UCert.x); // A <- (G1 * C)^{1/(gamma + x)} element_add(zp, ik->gamma, udbe->UCert.x); element_invert(zp, zp); element_mul(jpd2->A, gpk->G1, jpd1->C); element_pow_naf(jpd2->A, jpd2->A, zp); element_set(udbe->UCert.A, jpd2->A); // 3. B <- e(G1 * C, G2) / e(A, W) = e(G1 * C, G2) * e(A^-1, W) element_mul(g1, gpk->G1, jpd1->C); element_pairing(B, g1, gpk->G2); element_invert(g1, jpd2->A); element_pairing(gt, g1, gpk->W); element_mul(B, B, gt); element_clear(g1); element_clear(zp); element_clear(gt); // 4. D <- e(A, G2) element_init_GT(D, pairing); element_pairing(D, jpd2->A, gpk->G2); // 5. V <- NIZKPoKDL(B, D) // T1 = B^gamma element_init_GT(jpd2->V.T1, pairing); element_pow_zn(jpd2->V.T1, B, ik->gamma); // T2 = D^gamma element_init_GT(jpd2->V.T2, pairing); element_pow_zn(jpd2->V.T2, D, ik->gamma); // r eR Zp element_init(r, Fp); element_random(r); // R1 = B^r element_init_GT(R1, pairing); element_pow_zn(R1, B, r); // R2 = D^r element_init_GT(R2, pairing); element_pow_zn(R2, D, r); // h = H(B, D, T1, T2, R1, R2) data_len = element_length_in_bytes(B) + element_length_in_bytes(D) + element_length_in_bytes(jpd2->V.T1) + element_length_in_bytes(jpd2->V.T2) + element_length_in_bytes(R1) + element_length_in_bytes(R2); data_buf = (BYTE*) malloc(data_len); data_buf += element_to_bytes(data_buf, B); data_buf += element_to_bytes(data_buf, D); data_buf += element_to_bytes(data_buf, jpd2->V.T1); data_buf += element_to_bytes(data_buf, jpd2->V.T2); data_buf += element_to_bytes(data_buf, R1); data_buf += element_to_bytes(data_buf, R2); data_buf -= data_len; jpd2->V.hash = (BYTE*) malloc(JOIN_HASH_BITS / 8); xsgs_hash(data_buf, data_len * 8, jpd2->V.hash, JOIN_HASH_BITS); element_init(hp, Fp); element_from_hash(hp, jpd1->U.hash, JOIN_HASH_BITS / 8); free(data_buf); element_clear(B); element_clear(D); element_clear(R1); element_clear(R2); // s = r - hash * gamma mod p element_init(jpd2->V.s, Fp); element_mul(jpd2->V.s, hp, ik->gamma); element_add(jpd2->V.s, r, jpd2->V.s); element_clear(r); element_clear(hp); } // return (A, V = (T1, T2, hash, s) ) return ret; }
// USER JOIN PHASE 3 - user key generation (Join) int xsgs_user_join_phase3(XSGS_PUBLIC_KEY* gpk, XSGS_USER_CERT* ucert, XSGS_JOIN_PHASE1* jpd1, XSGS_JOIN_PHASE2* jpd2, XSGS_JOIN_PHASE3* jpd3, char* usk_pem_filename) { int ret; pairing_ptr pairing = gpk->pairing; field_ptr Fp = pairing->Zr; element_t B, D, R1, R2, h, g1, gt; // B = e(G1 * C, G2) / e(A, W) = e(G1 * C, G2) * e(A^-1, W) element_init_GT(B, pairing); element_init_G1(g1, pairing); element_init_GT(gt, pairing); element_mul(g1, gpk->G1, jpd1->C); element_pairing(B, g1, gpk->G2); element_invert(g1, jpd2->A); element_pairing(gt, g1, gpk->W); element_mul(B, B, gt); // D = e(A, G2) element_init_GT(D, pairing); element_pairing(D, jpd2->A, gpk->G2); // verifies A e Group1, Checks V element_init(h, Fp); element_from_hash(h, jpd1->U.hash, JOIN_HASH_BITS / 8); element_neg(h, h); // R1 = B^s * T1^h element_init_GT(R1, pairing); element_pow_naf2(R1, B, jpd2->V.s, jpd2->V.T1, h); // R2 = D^s * T2^h element_init_GT(R2, pairing); element_pow_naf2(R2, D, jpd2->V.s, jpd2->V.T2, h); // clear tmp element_clear(g1); element_clear(gt); element_clear(h); // h = H(B, D, T1, T2, R1, R2) DWORD data_len = element_length_in_bytes(B) + element_length_in_bytes(D) + element_length_in_bytes(jpd2->V.T1) + element_length_in_bytes(jpd2->V.T2) + element_length_in_bytes(R1) + element_length_in_bytes(R2); BYTE* data_buf = (BYTE*) malloc(data_len); data_buf += element_to_bytes(data_buf, B); data_buf += element_to_bytes(data_buf, D); data_buf += element_to_bytes(data_buf, jpd2->V.T1); data_buf += element_to_bytes(data_buf, jpd2->V.T2); data_buf += element_to_bytes(data_buf, R1); data_buf += element_to_bytes(data_buf, R2); data_buf -= data_len; BYTE* hash = (BYTE*) malloc(JOIN_HASH_BITS / 8); xsgs_hash(data_buf, data_len * 8, hash, JOIN_HASH_BITS); free(data_buf); element_clear(B); element_clear(D); element_clear(R1); element_clear(R2); // compare hashes ret = memcmp(jpd2->V.hash, hash, JOIN_HASH_BITS / 8); free(hash); if (!ret) { element_init_G1(ucert->A, pairing); element_set(ucert->A, jpd2->A); // S = sign(A) DWORD msg_len = element_length_in_bytes(ucert->A); BYTE* msg = (BYTE*) malloc(msg_len); element_to_bytes(msg, ucert->A); ret = xsgs_rsa_sign(usk_pem_filename, msg, msg_len, &(jpd3->S.sig), &(jpd3->S.len)); free(msg); } // return ( S = (rsa signature length, rsa signature) ) return ret; }
int main(void) { pairing_t pairing; char param[50000]; size_t count = fread(param, 1, 50000, stdin); if (!count) pbc_die("input error"); pairing_init_set_buf(pairing, param, count); // int cont = 0; struct timeval tvBegin, tvEnd; element_t g, h; element_t public_key, secret_key; element_t sig; element_t temp1, temp2; element_init_G2(g, pairing); element_init_G2(public_key, pairing); element_init_G1(h, pairing); element_init_G1(sig, pairing); element_init_GT(temp1, pairing); element_init_GT(temp2, pairing); element_init_Zr(secret_key, pairing); // Generating key element_random(g); element_random(secret_key); element_pow_zn(public_key, g, secret_key); // Generating message element_from_hash(h, "ABCDEF", 6); element_pow_zn(sig, h, secret_key); // RANDOM TESTS /* // Fp element_t p1, p2; element_init(p1, element_x(h)->field); element_init(p2, p1->field); element_random(p1); element_random(p2); // multiplication element_t puntos[2000]; for(cont = 0; cont < 1000; cont++){ element_init(puntos[cont], element_x(h)->field); element_init(puntos[2*cont], element_x(h)->field); element_random(puntos[cont]); element_random(puntos[2*cont]); } gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++){ element_mul(puntos[cont], puntos[cont], puntos[2*cont]); } gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); //square gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++) element_square(puntos[cont], puntos[2*cont]); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // add gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++) element_add(puntos[cont], puntos[cont], puntos[2*cont]); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // invers gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++) element_invert(puntos[cont], puntos[2*cont]); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // Fpk element_t q1, q2; element_init_GT(q1, pairing); element_init_GT(q2, pairing); element_random(q1); element_random(q2); // multiplication for(cont = 0; cont < 1000; cont++){ element_init_GT(puntos[cont], pairing); element_init_GT(puntos[2*cont], pairing); element_random(puntos[cont]); element_random(puntos[2*cont]); } gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++) { element_mul(puntos[cont], puntos[cont], puntos[2*cont]); } gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); //square gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++) element_square(puntos[cont], puntos[cont]); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // add gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++){ element_add(element_x(puntos[cont]), element_x(puntos[cont]), element_x(puntos[2*cont])); element_add(element_y(puntos[cont]), element_y(puntos[cont]), element_y(puntos[2*cont])); } gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // invers gettimeofday(&tvBegin, NULL); for(cont = 0; cont < 1000; cont++) element_invert(puntos[cont], puntos[2*cont]); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // CURVE OPERATIONS element_t punto, punto2; element_init(punto, h->field); element_random(punto); element_init(punto2, h->field); element_random(punto2); // add gettimeofday(&tvBegin, NULL); element_mul(punto, punto, punto2); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // double gettimeofday(&tvBegin, NULL); element_double(punto, punto2); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1); // SIZE GROUP int m = mpz_sizeinbase(pairing->r, 2) - 2; printf("%i\n", m); int contador = 0; for(;;){ if(!m) break; if(mpz_tstbit(pairing->r,m)) contador++; m--; } printf("%i\n", contador); */ // One pairing gettimeofday(&tvBegin, NULL); eval_miller(temp1, sig, g, pairing); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1000); //print_contador(); // One pairing (with precomputed values) // Original method pairing_pp_t pp; // Precomp gettimeofday(&tvBegin, NULL); pairing_pp_init(pp, sig, pairing); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1000); // Eval gettimeofday(&tvBegin, NULL); pairing_pp_apply(temp1, g, pp); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1000); pairing_pp_clear(pp); void do_precomp(){ lpoly *list; // precomputation gettimeofday(&tvBegin, NULL); list = lpoly_init(); precompute(list, pairing->r, sig, g); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1000); // DMAX printf("%i\n", list->MAXD); // eval gettimeofday(&tvBegin, NULL); compute_miller(temp2, list, g, pairing); gettimeofday(&tvEnd, NULL); timeval_subtract(&tvEnd, &tvBegin, 1000); lpoly_free(list); }
static void fq_from_hash(element_ptr n, void *data, int len) { eptr r = n->data; int k = len / 2; element_from_hash(r->x, data, k); element_from_hash(r->y, (char *)data + k, len - k); }
static void gt_from_hash(element_ptr e, void *data, int len) { pairing_ptr pairing = e->field->pairing; element_from_hash(e->data, data, len); pairing->finalpow(e); }
bool Manager::JoinMember(string request, string & respond) { //elements element_t Pi1; element_t Pi2; element_t Sk; element_t R; element_init_G1(Pi1,pairing); element_init_GT(Pi2, pairing); element_init_Zr(Sk, pairing); element_init_G1(R,pairing); //read & check SoK string hash; string hash_check; RequestFromString(request,hash,Sk,Pi1); //check Pi1 is point of curve if(element_item_count(Pi1)!=2) { element_clear(Pi1); element_clear(Pi2); element_clear(Sk); element_clear(R); return 1;//failure } element_t tmp1, tmp2; element_t c_Hsok; element_init_G1(tmp1, pairing); element_init_G1(tmp2, pairing); element_init_Zr(c_Hsok, pairing); element_from_hash(c_Hsok,(void*)hash.c_str(),hash.length()); element_pow_zn(tmp1,g,Sk); element_pow_zn(tmp2,Pi1,c_Hsok); element_div(R,tmp1,tmp2); hash_check=Helper::Hash_g_R(g,R); if(hash.compare(hash_check)) { element_clear(Pi1); element_clear(Pi2); element_clear(Sk); element_clear(R); element_clear(tmp1); element_clear(tmp2); element_clear(c_Hsok); return 1;//failure } //generate r_issuer element_t issuer_r; element_init_Zr(issuer_r, pairing); element_random(issuer_r); //create a b c element_t ai; element_t bi; element_t ci; element_t temp_ci1; element_t temp_ci2; //init element_init_G1(ai, pairing); element_init_G1(bi, pairing); element_init_G1(ci, pairing); element_init_G1(temp_ci1, pairing); element_init_G1(temp_ci2, pairing); //compute ai bi ci element_pow_zn(ai,g,issuer_r);//ai element_pow_zn(bi,ai,y);//bi element_pow_zn(temp_ci1,ai,x); element_pow_zn(temp_ci2,Pi1,issuer_r); element_pow_zn(temp_ci2,temp_ci2,x); element_pow_zn(temp_ci2,temp_ci2,y); element_mul(ci,temp_ci1,temp_ci2);//ci //create RESPOND respond=MemberSecretToString(ai,bi,ci); //compute Pi2 element_pairing(Pi2,Pi1,g); //Write_to_reg_list AddToRegistrationList(Pi1, Pi2); //clear elements element_clear(issuer_r); element_clear(Pi1); element_clear(Pi2); element_clear(temp_ci1); element_clear(temp_ci2); element_clear(tmp1); element_clear(tmp2); element_clear(c_Hsok); element_clear(Sk); element_clear(R); element_clear(ai); element_clear(bi); element_clear(ci); return 0;//success }
int main(int argc, char **argv) { pairing_t pairing; pbc_demo_pairing_init(pairing, argc, argv); if (!pairing_is_symmetric(pairing)) pbc_die("pairing must be symmetric"); double time1, time2; element_t P, Ppub, x, S, H, t1, t2, t3, t4; element_init_Zr(x, pairing); element_init_Zr(H, pairing); element_init_Zr(t1, pairing); element_init_G1(S, pairing); element_init_G1(P, pairing); element_init_G1(Ppub, pairing); element_init_G1(t2, pairing); element_init_GT(t3, pairing); element_init_GT(t4, pairing); printf("ZSS short signature schema\n"); printf("KEYGEN\n"); time1 = pbc_get_time(); element_random(x); element_random(P); element_mul_zn(Ppub, P, x); element_printf("P = %B\n", P); element_printf("x = %B\n", x); element_printf("Ppub = %B\n", Ppub); printf("SIGN\n"); element_from_hash(H, "Message", 7); element_add(t1, H, x); element_invert(t1, t1); element_mul_zn(S, P, t1); printf("Signature of message \"Message\" is:\n"); element_printf("S = %B\n", S); printf("VERIFY\n"); element_from_hash(H, "Message", 7); element_mul_zn(t2, P, H); element_add(t2, t2, Ppub); element_pairing(t3, t2, S); element_pairing(t4, P, P); element_printf("e(H(m)P + Ppub, S) = %B\n", t3); element_printf("e(P, P) = %B\n", t4); if (!element_cmp(t3, t4)) printf("Signature is valid\n"); else printf("Signature is invalid\n"); time2 = pbc_get_time(); printf("All time = %fs\n", time2 - time1); element_clear(P); element_clear(Ppub); element_clear(x); element_clear(S); element_clear(H); element_clear(t1); element_clear(t2); element_clear(t3); element_clear(t4); pairing_clear(pairing); return 0; }
/** * In this scheme every signer can aggregate a signature on a different message. * * This __cannot__ verify multiple messages from the same AS. * * We have __one__ signer -> __one__ message but as the message could be the same * for every signer, we can aggregate on it. * * @param store here we insert all the messages and all the signers * (as we __must__ verify every message of every signer) * * @return 0 if verify = success. * */ int pbgp_ibe_verify(setup_params_t *setup, ibe_signature_t *sign, store_t *store) { assert(sign && setup && store); element_t sumID, sumCi, sumTot, Pubi0, Pubi1, Pm, t1, p1, p2, e1, e2, ci; pairing_pp_t pp1, pp2, pp3; element_init_G1(sumID, setup->pairing); element_init_G1(sumCi, setup->pairing); element_init_G1(sumTot, setup->pairing); element_init_G1(Pubi0, setup->pairing); element_init_G1(Pubi1, setup->pairing); element_init_G1(Pm, setup->pairing); element_init_G1(t1, setup->pairing); element_init_GT(p1, setup->pairing); element_init_GT(p2, setup->pairing); element_init_GT(e1, setup->pairing); element_init_GT(e2, setup->pairing); element_init_Zr(ci, setup->pairing); element_set0(sumID); element_set0(sumCi); // // For each ASNUM in the list // store_iterator_t *iterator = pbgp_store_iterator_open(store); store_key_t key = STORE_KEY_INIT; while (1) { uint32_t id = 0; size_t ksize = 0, dsize = 0; // This mess is to avoid __any__ malloc call >:/ int ret = pbgp_store_iterator_uget_next_size(iterator, &ksize, &dsize); if (ret != 0) { break ; } // compute key data size ksize -= STORE_KEY_METADATA_LENGTH; if (sizeof(id) != ksize) { continue ; } // key buffer unsigned char kbuf[ksize]; memset (kbuf, 0, ksize); key.data = kbuf; key.dsize = sizeof(kbuf); // data buffer unsigned char message[dsize]; memset (message, 0, dsize); // get asnum + message ret = pbgp_store_iterator_uget_next(iterator, &key, message, &dsize); if (ret != 0) { break ; } char id0[BUFSIZ], id1[BUFSIZ]; memcpy(&id, kbuf, sizeof id); _ibe_get_id_pair(id, id0, sizeof (id0), id1, sizeof (id1)); // // Computes public keys for this AS from its identity // unsigned char hash[EVP_MAX_MD_SIZE + 1]; // hash(id0) memset(hash, 0, sizeof (hash)); _element_from_hash(Pubi0, hash, pbgp_rsa_uhash((unsigned char *) id0, strlen(id0), hash)); // hash(id1) memset(hash, 0, sizeof (hash)); _element_from_hash(Pubi1, hash, pbgp_rsa_uhash((unsigned char *) id1, strlen(id1), hash)); // ci = hash(m) memset(hash, 0, sizeof (hash)); element_from_hash(ci, hash, pbgp_rsa_uhash(message, dsize, hash)); // Computes sum(Pi_0) sum(ci * Pi_1) element_mul_zn(t1, Pubi1, ci); element_add(sumID, sumID, Pubi0); element_add(sumCi, sumCi, t1); } pbgp_store_iterator_close(iterator); element_add(sumTot, sumID, sumCi); pairing_pp_init(pp1, sumTot, setup->pairing); pairing_pp_init(pp2, sign->v, setup->pairing); pairing_pp_init(pp3, sign->u, setup->pairing); // e(Q = ibePub, sumTot) pairing_pp_apply(p1, setup->ibePub, pp1); // e(Tn = v, Pw) pairing_pp_apply(p2, sign->w, pp2); // e(Q = ibePub, sumTot) * e(Tn = v, Pw) element_mul(e2, p1, p2); // e(Sn = u, P) pairing_pp_apply(e1, setup->g, pp3); int rv = element_cmp(e1, e2); pairing_pp_clear(pp1); pairing_pp_clear(pp2); pairing_pp_clear(pp3); element_clear(sumID); element_clear(sumCi); element_clear(sumTot); element_clear(t1); element_clear(ci); element_clear(Pubi0); element_clear(Pubi1); element_clear(Pm); element_clear(p1); element_clear(p2); element_clear(e1); element_clear(e2); return rv; }
/** * In this scheme every signer can aggregate a signature on a different message. * * @param sign the computated signature (param modified) * @param m the message to sign * @param mlen message length * * The __caller__ SHOULD add id:message to some storage as we need the aggregate signature * signers id=asnum to vrfy @see pbgp_ibe_vrfy() * * ie. pbgp_store_uput(store, STORE_KEY_SET_DATA(key, ASLIST, signer_id), (void *) m, mlen) * */ void pbgp_ibe_sign(setup_params_t *setup, ibe_keypair_t *key, const unsigned char *m, size_t mlen, ibe_signature_t *sign) { element_t ri, t1, t2, t3, t4, ci; // // Check if this is the first signature // "w must be an unique unseen value" // if (element_is0(sign->w)) { #if HAVE_LIBUUID || HAVE_LIBE2FS_UUID uuid_t uuid; uuid_generate(uuid); element_from_hash(sign->w, uuid, sizeof uuid); #else element_random(sign->w); #endif if (element_is0(sign->w)) { pbgp_fatal("pbgp_ibe_sign :: random"); } } element_init_G1(t1, setup->pairing); element_init_G1(t2, setup->pairing); element_init_G1(t3, setup->pairing); element_init_G1(t4, setup->pairing); element_init_Zr(ri, setup->pairing); element_init_Zr(ci, setup->pairing); // ci = binary_hash(message) unsigned char hash[EVP_MAX_MD_SIZE + 1]; memset(hash, 0, sizeof (hash)); unsigned int len = pbgp_rsa_uhash(m, mlen, hash); element_from_hash(ci, hash, len); // ri = random element element_random(ri); // ri * Pw element_mul_zn(t1, sign->w, ri); // Pi,0 = key->priv0 // Pi,1 = key->priv1 // ci * Pi,1 element_mul_zn(t2, key->priv1, ci); // ri * Pi,0 // element_mul(t5, ri, key->pub0); // ri * Pw + ci * sP(i,1) + sP(i,0) element_add(t3, t1, t2); // Si = ri * Pw + ci * Pi,1 + Pi,0 element_add(t3, t3, key->priv0); // Ti = ri * P element_mul_zn(t4, setup->g, ri); // Sum(sign) for each signature // w is the same for all signers // u = sum(Si) element_add(sign->u, sign->u, t3); // v = sum(Ti) element_add(sign->v, sign->v, t4); element_clear(t1); element_clear(t2); element_clear(t3); element_clear(t4); element_clear(ri); element_clear(ci); }
void bbs_sign(unsigned char *sig, int hashlen, void *hash, bbs_group_public_key_ptr gpk, bbs_group_private_key_ptr gsk) { bbs_sys_param_ptr param = gpk->param; pairing_ptr pairing = param->pairing; field_ptr Fp = pairing->Zr; element_t T1, T2, T3; element_t R1, R2, R3, R4, R5; element_t alpha, beta; element_t c; element_t ralpha, rbeta, rx, rdelta1, rdelta2; element_t z0, z1; element_t e10, et0; unsigned char *writeptr = sig; element_init_G1(T1, pairing); element_init_G1(T2, pairing); element_init_G1(T3, pairing); element_init_G1(R1, pairing); element_init_G1(R2, pairing); element_init_GT(R3, pairing); element_init_G1(R4, pairing); element_init_G1(R5, pairing); element_init(c, Fp); element_init(alpha, Fp); element_random(alpha); element_init(beta, Fp); element_random(beta); //temp variables element_init(z0, Fp); element_init(z1, Fp); element_init_GT(et0, pairing); element_init_G1(e10, pairing); element_init(ralpha, Fp); element_random(ralpha); element_init(rbeta, Fp); element_random(rbeta); element_init(rx, Fp); element_random(rx); element_init(rdelta1, Fp); element_random(rdelta1); element_init(rdelta2, Fp); element_random(rdelta2); element_pow_zn(T1, gpk->u, alpha); element_pow_zn(T2, gpk->v, beta); element_add(z0, alpha, beta); element_pow_zn(T3, gpk->h, z0); element_mul(T3, T3, gsk->A); element_pow_zn(R1, gpk->u, ralpha); element_pow_zn(R2, gpk->v, rbeta); /* * rather than computing e(T3,g2), note that T3 = A h^{alpha+beta}, * use precomputed e(A,g2) and e(h,g2), and use appropriate * exponentiations in GT. */ //pairing_apply(et0, T3, gpk->g2, pairing); /* precomputed */ element_pow_zn(et0, gpk->pr_h_g2, z0); /* NB. here z0 = alpha+beta */ element_mul(et0, et0, gsk->pr_A_g2); //element_pow_zn(R3, et0, rx); // pairing_apply(et0, gpk->h, gpk->w, pairing); /* precomputed */ element_add(z0, ralpha, rbeta); element_neg(z0, z0); //element_pow_zn(et0, gpk->pr_h_w, z0); //element_mul(R3, R3, et0); // pairing_apply(et0, gpk->h, gpk->g2, pairing); /* precomputed */ element_add(z1, rdelta1, rdelta2); element_neg(z1, z1); //element_pow_zn(et0, gpk->pr_h_g2, z1); //element_mul(R3, R3, et0); element_pow3_zn(R3, et0, rx, gpk->pr_h_w, z0, gpk->pr_h_g2, z1); //element_pow_zn(R4, T1, rx); element_neg(z0, rdelta1); //element_pow_zn(e10, gpk->u, z0); //element_mul(R4, R4, e10); element_pow2_zn(R4, T1, rx, gpk->u, z0); //element_pow_zn(R5, T2, rx); element_neg(z0, rdelta2); //element_pow_zn(e10, gpk->v, z0); //element_mul(R5, R5, e10); element_pow2_zn(R5, T2, rx, gpk->v, z0); element_t M; element_init_G1(M, pairing); element_from_hash(M, hash, hashlen); unsigned int hash_input_length = element_length_in_bytes(T1) + element_length_in_bytes(T2) + element_length_in_bytes(T3) + element_length_in_bytes(R1) + element_length_in_bytes(R2) + element_length_in_bytes(R3) + element_length_in_bytes(R4) + element_length_in_bytes(R5) + element_length_in_bytes(M); unsigned char *hash_input = malloc(hash_input_length); hash_input += element_to_bytes(hash_input, T1); hash_input += element_to_bytes(hash_input, T2); hash_input += element_to_bytes(hash_input, T3); hash_input += element_to_bytes(hash_input, R1); hash_input += element_to_bytes(hash_input, R2); hash_input += element_to_bytes(hash_input, R3); hash_input += element_to_bytes(hash_input, R4); hash_input += element_to_bytes(hash_input, R5); hash_input += element_to_bytes(hash_input, M); // Could avoid converting to bytes and from bytes hash_input -= hash_input_length; hash_ctx_t context; unsigned char digest[hash_length]; hash_init(context); hash_update(context, hash_input, hash_input_length); hash_final(digest, context); free(hash_input); element_from_hash(c, digest, sizeof(digest)); element_clear(M); //now the r's represent the values of the s's //no need to allocate yet more variables element_mul(z0, c, alpha); element_add(ralpha, ralpha, z0); element_mul(z0, c, beta); element_add(rbeta, rbeta, z0); element_mul(z1, c, gsk->x); element_add(rx, rx, z1); element_mul(z0, z1, alpha); element_add(rdelta1, rdelta1, z0); element_mul(z0, z1, beta); element_add(rdelta2, rdelta2, z0); writeptr += element_to_bytes(writeptr, T1); writeptr += element_to_bytes(writeptr, T2); writeptr += element_to_bytes(writeptr, T3); writeptr += element_to_bytes(writeptr, c); writeptr += element_to_bytes(writeptr, ralpha); writeptr += element_to_bytes(writeptr, rbeta); writeptr += element_to_bytes(writeptr, rx); writeptr += element_to_bytes(writeptr, rdelta1); writeptr += element_to_bytes(writeptr, rdelta2); #ifdef DEBUG element_printf("T1: %B\n", T1); element_printf("T2: %B\n", T2); element_printf("T3: %B\n", T3); element_printf("R1: %B\n", R1); element_printf("R2: %B\n", R2); element_printf("R3: %B\n", R3); element_printf("R4: %B\n", R4); element_printf("R5: %B\n", R5); element_printf("c: %B\n", c); #endif element_clear(T1); element_clear(T2); element_clear(T3); element_clear(R1); element_clear(R2); element_clear(R3); element_clear(R4); element_clear(R5); element_clear(alpha); element_clear(beta); element_clear(c); element_clear(ralpha); element_clear(rbeta); element_clear(rx); element_clear(rdelta1); element_clear(rdelta2); //clear temp variables element_clear(z0); element_clear(z1); element_clear(e10); element_clear(et0); }
int bbs_verify(unsigned char *sig, int hashlen, void *hash, bbs_group_public_key_t gpk) { bbs_sys_param_ptr param = gpk->param; pairing_ptr pairing = param->pairing; field_ptr Fp = pairing->Zr; element_t T1, T2, T3; element_t R1, R2, R3, R4, R5; element_t c, salpha, sbeta, sx, sdelta1, sdelta2; element_t e10, e20, e21, et0, z0, z1; unsigned char *readptr = sig; element_init_G1(T1, pairing); element_init_G1(T2, pairing); element_init_G1(T3, pairing); element_init_G1(R1, pairing); element_init_G1(R2, pairing); element_init_GT(R3, pairing); element_init_G1(R4, pairing); element_init_G1(R5, pairing); element_init(c, Fp); element_init(salpha, Fp); element_init(sbeta, Fp); element_init(sx, Fp); element_init(sdelta1, Fp); element_init(sdelta2, Fp); element_init_G1(e10, pairing); element_init_G2(e20, pairing); element_init_G2(e21, pairing); element_init_GT(et0, pairing); element_init(z0, Fp); element_init(z1, Fp); readptr += element_from_bytes(T1, readptr); readptr += element_from_bytes(T2, readptr); readptr += element_from_bytes(T3, readptr); readptr += element_from_bytes(c, readptr); readptr += element_from_bytes(salpha, readptr); readptr += element_from_bytes(sbeta, readptr); readptr += element_from_bytes(sx, readptr); readptr += element_from_bytes(sdelta1, readptr); readptr += element_from_bytes(sdelta2, readptr); element_neg(z0, c); //element_pow_zn(R1, gpk->u, salpha); //element_pow_zn(e10, T1, z0); //element_mul(R1, R1, e10); element_pow2_zn(R1, gpk->u, salpha, T1, z0); //element_pow_zn(R2, gpk->v, sbeta); //element_pow_zn(e10, T2, z0); //element_mul(R2, R2, e10); element_pow2_zn(R2, gpk->v, sbeta, T2, z0); element_neg(z0, sdelta1); //element_pow_zn(R4, gpk->u, z0); //element_pow_zn(e10, T1, sx); //element_mul(R4, R4, e10); element_pow2_zn(R4, gpk->u, z0, T1, sx); element_neg(z0, sdelta2); //element_pow_zn(R5, gpk->v, z0); //element_pow_zn(e10, T2, sx); //element_mul(R5, R5, e10); element_pow2_zn(R5, gpk->v, z0, T2, sx); /* * compute R3 more efficiently. use precomputed e(g1,g2)^{-1}, * e(h,g2), and e(h,w). this leaves e(T3,g2)^sx and e(T3,w)^c; * compute these with one pairing as e(T3, g2^sx w^c). */ //element_pow_zn(e20, gpk->g2, sx); //element_pow_zn(e21, gpk->w, c); //element_mul(e20, e20, e21); element_pow2_zn(e20, gpk->g2, sx, gpk->w, c); pairing_apply(R3, T3, e20, pairing); //element_pow_zn(et0, gpk->pr_g1_g2_inv, c); //element_mul(R3, R3, et0); element_add(z0, salpha, sbeta); element_neg(z0, z0); //element_pow_zn(et0, gpk->pr_h_w, z0); //element_mul(R3, R3, et0); element_add(z1, sdelta1, sdelta2); element_neg(z1, z1); //element_pow_zn(et0, gpk->pr_h_g2, z1); element_pow3_zn(et0, gpk->pr_g1_g2_inv, c, gpk->pr_h_w, z0, gpk->pr_h_g2, z1); element_mul(R3, R3, et0); #ifdef DEBUG element_printf("T1: %B\n", T1); element_printf("T2: %B\n", T2); element_printf("T3: %B\n", T3); element_printf("R1: %B\n", R1); element_printf("R2: %B\n", R2); element_printf("R3: %B\n", R3); element_printf("R4: %B\n", R4); element_printf("R5: %B\n", R5); #endif int result = 0; element_t M; element_init_G1(M, pairing); element_from_hash(M, hash, hashlen); unsigned int hash_input_length = element_length_in_bytes(T1) + element_length_in_bytes(T2) + element_length_in_bytes(T3) + element_length_in_bytes(R1) + element_length_in_bytes(R2) + element_length_in_bytes(R3) + element_length_in_bytes(R4) + element_length_in_bytes(R5) + element_length_in_bytes(M); unsigned char *hash_input = malloc(hash_input_length); hash_input += element_to_bytes(hash_input, T1); hash_input += element_to_bytes(hash_input, T2); hash_input += element_to_bytes(hash_input, T3); hash_input += element_to_bytes(hash_input, R1); hash_input += element_to_bytes(hash_input, R2); hash_input += element_to_bytes(hash_input, R3); hash_input += element_to_bytes(hash_input, R4); hash_input += element_to_bytes(hash_input, R5); hash_input += element_to_bytes(hash_input, M); // Could avoid converting to bytes and from bytes hash_input -= hash_input_length; hash_ctx_t context; unsigned char digest[hash_length]; hash_init(context); hash_update(context, hash_input, hash_input_length); hash_final(digest, context); free(hash_input); element_t c1; element_init(c1, Fp); element_from_hash(c1, digest, sizeof(digest)); if (!element_cmp(c, c1)) { result = 1; } element_clear(M); element_clear(c1); element_clear(T1); element_clear(T2); element_clear(T3); element_clear(R1); element_clear(R2); element_clear(R3); element_clear(R4); element_clear(R5); element_clear(c); element_clear(salpha); element_clear(sbeta); element_clear(sx); element_clear(sdelta1); element_clear(sdelta2); element_clear(e10); element_clear(e20); element_clear(e21); element_clear(et0); element_clear(z0); element_clear(z1); return result; }