void pbc_decrypt(struct crypto *pbc, int tl, int *nse, int ts, int use_caching, int use_product) { /* e(C_0, K_0) -> pairing(C, K[i]) * e(C_{i1}, K_{i1}) -> pairing(Ci[i], Ki[i]) * e(C_{i2}, K_{i2}) -> pairing(Ci[i], Ki[i]) */ element_t C, K[ts], Ci[tl], Ki[tl], R, A, B, M, T; int num_mul=0, num_pair=0; struct timeval st, en; int i, j; /* -------------------- setup --------------------- */ gettimeofday(&st, NULL); element_init_G1(C, pbc->pairing); element_random(C); for (i = 0; i < ts; i++) { element_init_G2(K[i], pbc->pairing); element_random(K[i]); } for (i = 0; i < tl; i++) { element_init_G1(Ci[i], pbc->pairing); element_random(Ci[i]); } for (i = 0; i < tl; i++) { element_init_G2(Ki[i], pbc->pairing); element_random(Ki[i]); } element_init_GT(R, pbc->pairing); element_init_GT(A, pbc->pairing); element_init_GT(B, pbc->pairing); element_init_GT(M, pbc->pairing); element_init_GT(T, pbc->pairing); gettimeofday(&en, NULL); printf("Setup: %lu us\n", time_diff(&st, &en)); printf("tl=%d ts=%d|", tl, ts); for (i = 0; i < ts; i++) printf("%d ", nse[i]); printf("\n"); /* ------------------ decryption ------------------ */ gettimeofday(&st, NULL); /* e(C0, K0) across all tokens */ if (use_caching) { pairing_pp_t pp; pairing_pp_init(pp, C, pbc->pairing); for (i = 0; i < ts; i++) pairing_pp_apply(R, K[i], pp); pairing_pp_clear(pp); } else for (i = 0; i < ts; i++) { pairing_apply(R, C, K[i], pbc->pairing); num_pair++; } /* prod{e(Ci1, Ki1)}prod{e(Ci2, Ki2)} across all tokens */ if (use_product) { for (i = 0; i < ts; i++) { if (!nse[i])continue; element_prod_pairing(A, Ci, Ki, nse[i]); element_prod_pairing(B, Ci, Ki, nse[i]); element_mul(M, A, B); } } else for (i = 0; i < ts; i++) { element_set1(A); for (j = 0; j < nse[i]; j++) { element_pairing(T, Ci[j], Ki[j]); element_mul(A, A, T); num_pair++; num_mul++; } element_set1(B); for (j = 0; j < nse[i]; j++) { element_pairing(T, Ci[j], Ki[j]); element_mul(B, B, T); num_pair++; num_mul++; } element_mul(M, A, B); num_mul++; } gettimeofday(&en, NULL); printf("Decryption: %lu us\n", time_diff(&st, &en)); if (use_caching || use_product) { num_pair = -1; num_mul = -1; } printf("Used %d pairings and %d multiplications\n", num_pair, num_mul); /* ------------------- cleanup -------------------- */ gettimeofday(&st, NULL); element_clear(T); element_clear(M); element_clear(B); element_clear(A); element_clear(R); element_clear(C); for (i = 0; i < ts; i++) element_clear(K[i]); for (i = 0; i < tl; i++) element_clear(Ci[i]); for (i = 0; i < tl; i++) element_clear(Ki[i]); gettimeofday(&en, NULL); printf("Cleanup: %lu us\n", time_diff(&st, &en)); }
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); }
/** * 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; }