static int fq_to_bytes(unsigned char *data, element_t e) { eptr p = e->data; int len; len = element_to_bytes(data, p->x); len += element_to_bytes(data + len, p->y); return len; }
static int curve_to_bytes(unsigned char *data, element_t e) { point_ptr P = (point_ptr)e->data; int len; len = element_to_bytes(data, P->x); len += element_to_bytes(data + len, P->y); return len; }
void Hmki(element_t* out, public_key pk, element_t* key) { // pk and key check element_init_Zr(*out, pairing); int len = (pk.level + 1) * sizeof(unsigned int) / sizeof(char); element_t x; element_init_G1(x,pairing); element_from_hash(x, pk.ID_tuple, len); len = element_length_in_bytes(x); unsigned char* str = (unsigned char* ) malloc(len); element_to_bytes(str, x); int len1 = element_length_in_bytes(*key); unsigned char* key_str = (unsigned char*) malloc(len1); element_to_bytes(key_str, *key); unsigned char* sum = (unsigned char*) malloc(len1 + len); memcpy(sum, str, len); memcpy(sum + len, key_str, len1); element_clear(x); free(str); free(key_str); unsigned char o[MD5_DIGEST_LENGTH + 1]; MD5(sum, len + len1, o); o[MD5_DIGEST_LENGTH] = '\0'; element_from_hash(*out, o, MD5_DIGEST_LENGTH); ///////////////////////// }
/** * @param buf must be allocated by caller * pbgp_ibe_serialized_signature_size() bytes long */ unsigned char * pbgp_ibe_signature_serialize(ibe_signature_t *signature, unsigned char *buf) { // Ugly as we recalculate size but still faster than malloc int u_len = element_length_in_bytes(signature->u), v_len = element_length_in_bytes(signature->v); element_to_bytes(buf, signature->u); element_to_bytes(buf + u_len, signature->v); element_to_bytes(buf + u_len + v_len, signature->w); return buf; }
int CipherText::toByteString(ByteString& bytes){ int begin = bytes.getLength(); unsigned char* buf = (unsigned char*)malloc(sizeof(unsigned char) * ELEMENT_LENGTH); element_to_bytes(buf, this->c1); bytes.append(buf, ELEMENT_LENGTH); element_to_bytes(buf, this->c0); bytes.append(buf, ELEMENT_LENGTH); free(buf); this->policy->toByteString(bytes); int end = bytes.getLength(); return end - begin; }
int BCEEncrypt(byte *sys_params_path, byte *CT_C0_out, byte *CT_C1_out, byte *symmetric_key_out) { global_broadcast_params_t gbs; broadcast_system_t sys; ct_t shared_CT; element_t symmetric_key; int retlen; if (sys_params_path == NULL) return 1; if (CT_C0_out == NULL) return 2; if (CT_C1_out == NULL) return 3; if (symmetric_key_out == NULL) return 4; LoadParams((char *) sys_params_path, &gbs, &sys); shared_CT = (ct_t) pbc_malloc(sizeof(struct ciphertext_s)); BroadcastKEM_using_product(gbs, sys, shared_CT, symmetric_key); retlen = element_to_bytes(CT_C0_out, shared_CT->C0); if (retlen != CT_C0_LENGTH) return 5; retlen = element_to_bytes(CT_C1_out, shared_CT->C1); if (retlen != CT_C1_LENGTH) return 6; retlen = element_to_bytes(symmetric_key_out, symmetric_key); if (retlen != SYMMETRIC_KEY_LENGTH) return 7; element_random(symmetric_key); element_clear(symmetric_key); FreeCT(shared_CT); pbc_free(shared_CT); FreeBCS(sys); pbc_free(sys); FreeGBP(gbs); pbc_free(gbs); return 0; }
void bb_sign(unsigned char *sig, unsigned int hashlen, unsigned char *hash, bb_public_key_t pk, bb_private_key_t sk) { int len; element_t sigma; element_t r, z, m; bb_sys_param_ptr param = pk->param; pairing_ptr pairing = param->pairing; element_init(r, pairing->Zr); element_init(z, pairing->Zr); element_init(m, pairing->Zr); element_random(r); element_from_hash(m, hash, hashlen); element_mul(z, sk->y, r); element_add(z, z, sk->x); element_add(z, z, m); element_invert(z, z); element_init(sigma, pairing->G1); element_pow_zn(sigma, pk->g1, z); len = element_to_bytes_x_only(sig, sigma); element_to_bytes(&sig[len], r); element_clear(sigma); element_clear(r); element_clear(z); element_clear(m); }
/** * Memoized version of element_from_hash * for performance reason */ static inline void _element_from_hash(element_t e, void *data, int len) { // @fixme: store is "left open" when executable close static store_t *store = NULL; if (!store) { store = pbgp_store_open(NULL); } store_key_t key = { 0, 0, len, (unsigned char *) data }; size_t size = 0; int ret = 0; if (0 == pbgp_store_uget_size(store, &key, &size)) { unsigned char buf[size]; memset (buf, 0, size); pbgp_store_uget(store, &key, buf, &size); ret = element_from_bytes(e, buf); } if (0 == ret) { element_from_hash(e, data, len); unsigned char edata[element_length_in_bytes(e)]; element_to_bytes(edata, e); pbgp_store_put(store, &key, edata, sizeof(edata)); } }
status_t element_to_key(element_t e, uint8_t *data, int data_len, uint8_t label) { LEAVE_IF(e->isInitialized != TRUE, "uninitialized argument."); // adds an extra null byte by default - will use this last byte for the label int d_len = element_length(e), digest_len = SHA_LEN; uint8_t d[d_len + 1]; memset(d, 0, d_len); // write e to a tmp buf if(d_len > 0 && digest_len <= data_len) { element_to_bytes(d, d_len, e); d[d_len-1] = label; #ifdef DEBUG printf("%s: bytes form....\n", __FUNCTION__); print_as_hex(d, d_len); #endif // hash buf using md_map_sh256 and store data_len bytes in data uint8_t digest[digest_len + 1]; memset(digest, 0, digest_len); SHA_FUNC(digest, d, d_len); memcpy(data, digest, digest_len); #ifdef DEBUG printf("%s: digest: ", __FUNCTION__); print_as_hex(data, digest_len); #endif return ELEMENT_OK; } return ELEMENT_INVALID_ARG; }
/* * Convert an element to a byte array. * Elements from G1 or G2 will also be compressed! */ void BilinearMappingHandler::elementToByteArray(unsigned char* saveHere, element_t elem, bool isElementOfGT) { if (isElementOfGT) element_to_bytes(saveHere,elem); else element_to_bytes_compressed(saveHere, elem); }//end of elementToByteArray()
//H_mki function from the article //unique hash function from bit string to Z_r //like HAMC H_A(mk_i | MD5(X | mk_i)) where H_A is H_3, mk_i = key void H_4(element_t* out, element_t key, char* string ) { int buff_size; //key to string; int element_length = element_length_in_bytes(key); if (strlen(string) < MD5_DIGEST_LENGTH ) { buff_size = MD5_DIGEST_LENGTH + element_length; } else { buff_size = strlen(string) + element_length; } unsigned char element_in_bytes[element_length + 1]; element_to_bytes(element_in_bytes, key); element_in_bytes[element_length] = '\0'; //concatanation X | mk_i := buff char buff[buff_size]; strcpy(buff, string); strcpy(buff + strlen(string), element_in_bytes); buff[strlen(string) + element_length] = '\0'; // compute MD5 of buff; unsigned char hash[MD5_DIGEST_LENGTH + 1]; MD5(buff, strlen(string) + element_length, hash); hash[MD5_DIGEST_LENGTH] = '\0'; //mk_i | hash to buff strcpy(buff, element_in_bytes); strcpy(buff + element_length, hash); buff[element_length + MD5_DIGEST_LENGTH] = '\0'; //compute H_A := H3 to get elemenet from Z_r H_3(*out, buff, element_length + MD5_DIGEST_LENGTH ); }
// USER JOIN PHASE 4 - user key generation (Join) int xsgs_user_join_phase4(XSGS_PUBLIC_KEY* gpk, XSGS_USER_DB_ENTRY* udbe, XSGS_JOIN_PHASE3* jpd3, XSGS_JOIN_PHASE4* jpd4, char* upk_pem_filename) { int ret; pairing_ptr pairing = gpk->pairing; field_ptr Fp = pairing->Zr; DWORD msg_len = element_length_in_bytes(udbe->UCert.A); BYTE* msg = (BYTE*) malloc(msg_len); element_to_bytes(msg, udbe->UCert.A); /* TODO Verify_PK_CA(cert_user) */ ret = xsgs_rsa_verify(upk_pem_filename, msg, msg_len, jpd3->S.sig, jpd3->S.len); free(msg); udbe->S.len = jpd3->S.len; udbe->S.sig = (BYTE*) malloc(udbe->S.len); memcpy(udbe->S.sig, jpd3->S.sig, udbe->S.len); element_init(jpd4->x, Fp); element_set(jpd4->x, udbe->UCert.x); return ret; }
// start_index从1开始 int BCEChangeDecryptionProduct(byte *global_params_path, int start_index, int length, int *adds, int n_adds, int *rems, int n_rems, byte *decr_prod, byte *decr_prod_out) { global_broadcast_params_t gbs; struct single_priv_key_s *priv_key; int i, writelen = 0; if (global_params_path == NULL) return 1; if (start_index % NUM_USER_DIVISOR != 1) return 2; if (adds == NULL && rems == NULL) return 4; if (decr_prod == NULL) return 8; if (decr_prod_out == NULL) return 9; LoadGlobalParams((char *) global_params_path, &gbs); if (n_adds > gbs->num_users) return 5; if (n_rems > gbs->num_users) return 7; priv_key = (priv_key_t) malloc(length * sizeof(struct single_priv_key_s)); for (i = 0; i < length; i++) { // restore index priv_key[i].index = start_index + i; // restore fake g_i_gamma element_init(priv_key[i].g_i_gamma, gbs->pairing->G1); // restore fake g_i element_init(priv_key[i].g_i, gbs->pairing->G1); // restore fake h_i element_init(priv_key[i].h_i, gbs->pairing->G2); // restore real decr_prod element_init(priv_key[i].decr_prod, gbs->pairing->G1); decr_prod += element_from_bytes(priv_key[i].decr_prod, decr_prod); } for (i = 0; i < length; i++) { Change_decr_prod_indicies(gbs, priv_key[i].index, adds, n_adds, rems, n_rems, &priv_key[i]); writelen += element_to_bytes(decr_prod_out + writelen, priv_key[i].decr_prod); } for (i = 0; i < length; i++) FreePK(&priv_key[i]); free(priv_key); FreeGBP(gbs); pbc_free(gbs); return 0; }
void element_to_file(element_t element, char* outputFile){ const int int_bytes_of_element = element_length_in_bytes(element); unsigned char * element_byte_form = (unsigned char *)malloc( int_bytes_of_element * sizeof(unsigned char)); element_to_bytes(element_byte_form, element); element_from_bytes(element, element_byte_form); FILE* fp_element = fopen(outputFile, "w"); fwrite(element_byte_form, 1, int_bytes_of_element, fp_element); fclose( fp_element ); free(element_byte_form); }
static inline void out(element_t elem, FILE *myfile) { int sz = element_length_in_bytes(elem); fwrite(&sz, 4, 1, myfile); unsigned char* data = pbc_malloc(sz); if(!data) printf("DATA IS NULL\n"); element_to_bytes(data, elem); fwrite(data, sz, 1, myfile); pbc_free(data); }
//generae a 128bit hash from element // RETURN 33 bytes long char[] // MALLOC : RET !!!!!!! unsigned char* H_2(element_t element) { //convert elemnt to sztring int element_length = element_length_in_bytes(element); unsigned char buff[element_length]; element_to_bytes(buff, element); //hash the string unsigned char* hash = (unsigned char*) malloc(MD5_DIGEST_LENGTH * sizeof( unsigned char)) ; MD5(buff, element_length, hash); return hash ; }
// Requires e to be a point on an elliptic curve. int element_to_bytes_compressed(unsigned char *data, element_ptr e) { point_ptr P = (point_ptr)e->data; int len; len = element_to_bytes(data, P->x); if (element_sign(P->y) > 0) { data[len] = 1; } else { data[len] = 0; } len++; return len; }
int BCESetup(byte *curve_file_name, int num_user, byte *sys_params_path, byte * global_params_path, byte *sys_priv_key_out) { global_broadcast_params_t gbs; broadcast_system_t sys; //char recip[num_user / NUM_USER_DIVISOR]; char *recip; element_t sys_priv_key; if (curve_file_name == NULL) return 1; if (num_user % NUM_USER_DIVISOR != 0) return 2; if (sys_params_path == NULL) return 3; if (global_params_path == NULL) return 4; if (sys_priv_key_out == NULL) return 5; Setup_global_broadcast_params(&gbs, num_user, (char *) curve_file_name); Gen_broadcast_system(gbs, &sys); recip = (char *) malloc(num_user / NUM_USER_DIVISOR); memset(recip, BIT_VECTOR_UNIT_VALUE, num_user / NUM_USER_DIVISOR); Gen_encr_prod_from_bitvec(gbs, sys, recip); StoreParams((char *) sys_params_path, gbs, sys); StoreGlobalParams((char *) global_params_path, gbs); element_init_Zr(sys_priv_key, gbs->pairing); element_set(sys_priv_key, sys->priv_key); element_to_bytes(sys_priv_key_out, sys_priv_key); memset(recip, BIT_VECTOR_CLEAR_UNIT_VALUE, num_user / NUM_USER_DIVISOR); free(recip); element_random(sys_priv_key); element_clear(sys_priv_key); FreeBCS(sys); pbc_free(sys); FreeGBP(gbs); pbc_free(gbs); return 0; }
static void test_gf3m_param(void) { params *pa = (params *) f97->data; element_to_bytes(data, pa->p); unsigned i; unsigned char w; for (i = 0; i < pa->len * 2 * sizeof(unsigned long); i++) { switch (i) { case 1: w = 1; break; // 2 case 2: w = 16; break; // x^12 case 24: w = 2; break; // x^97 default: w = 0; } EXPECT(data[i] == w); } }
int newepoch_save(char *out,epoch_item_t *ep,setup_params_t * setup) { FILE *fp = NULL; uint32_t elem_size = 0; int rv = 0; unsigned char *buf = NULL; fp=fopen(out,"wb"); if(!fp) { pbgp_error("newepoch_save :: %s\n",strerror(errno)); return -1; } elem_size = element_length_in_bytes(ep->acc->elem); buf = (unsigned char *) malloc(elem_size); if(!buf) { pbgp_error("newepoch_save :: cannot allocate buf\n"); rv = -1; goto out; } element_to_bytes(buf,ep->acc->elem); fwrite(&elem_size,sizeof(uint32_t),1,fp); fwrite(buf,elem_size,1,fp); mpz_out_raw(fp,ep->s_acc); ids_save_fp(fp,ep->epls.act); mpz_out_raw(fp,ep->s_new); ids_save_fp(fp,ep->epls.rvk); mpz_out_raw(fp,ep->s_rvk); out: if(buf) free(buf); fclose(fp); return rv; }
FENC_ERROR export_components_to_buffer(uint8* buffer, size_t max_len, size_t *result_len, char* fmt, ...) { FENC_ERROR result = FENC_ERROR_NONE; va_list comp_list; uint8* buf_ptr = buffer; char* fmt_ptr; element_t *elt; fenc_attribute_policy *policy; fenc_attribute_list *attribute_list; size_t i_index=0, tmp_len=0; *result_len = 0; /* Iterate through the variable-length argument list. */ va_start(comp_list, fmt); for(fmt_ptr = fmt; *fmt_ptr != '\0'; fmt_ptr++) { if(*fmt_ptr != '%') { continue; } /* Point buf_ptr to the correct offset, unless the buffer is NULL. */ if (buffer != NULL) { buf_ptr = (uint8*)(buffer + *result_len); } switch(*++fmt_ptr) { case 'E': /* Uncompressed element. */ elt = va_arg(comp_list, element_t*); *result_len += element_length_in_bytes(*elt); if (buffer != NULL && *result_len <= max_len) { element_to_bytes(buf_ptr, *elt); } break; case 'C': /* Compressed element. */ elt = va_arg(comp_list, element_t*); tmp_len = element_length_in_bytes_compressed(*elt); *result_len += tmp_len; if (buffer != NULL && *result_len < max_len) { element_to_bytes_compressed(buf_ptr, *elt); } // printf("len of C = '%zu'\n", *result_len); // printf_buffer_as_hex(buf_ptr, tmp_len); break; case 'P': policy = va_arg(comp_list, fenc_attribute_policy*); result = fenc_attribute_policy_to_string(policy->root, (char *)buf_ptr, (max_len - *result_len)); i_index = strchr((char *) buf_ptr, 0) - (char *) buf_ptr; *result_len += i_index + 1; // printf("policy_root: '%s', strlen: '%d', index: '%d'\n", (char *) buf_ptr, strlen((char *) buf_ptr), i_index); break; case 'A': attribute_list = va_arg(comp_list, fenc_attribute_list*); fenc_attribute_list_to_buffer(attribute_list, buf_ptr, (max_len - *result_len), &i_index); *result_len += i_index + 1; // printf("attribute_list: '%s'\n\tlength: '%zu'\n", (char *)buf_ptr, strlen((char *)buf_ptr)); break; case 's': *result_len += strlen(va_arg(comp_list, char *)) + 1; if (buffer != NULL && *result_len <= max_len) { strcpy((char *)buf_ptr, va_arg(comp_list, char *)); } break; case 'd': *result_len += sizeof(int32); if (buffer != NULL && *result_len < max_len) { EXPORT_INT32(buf_ptr, va_arg(comp_list, int32)); } break; default: /* Unrecognized symbol. */ result = FENC_ERROR_INVALID_INPUT; break; } if (buffer != NULL && *result_len > max_len) { return FENC_ERROR_BUFFER_TOO_SMALL; } }
// 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() { unsigned int _steps = 0, hsize = 0; unsigned char hash[EVP_MAX_MD_SIZE + 1]; store_t *store_setup = pbgp_store_open(NULL); if (!store_setup) return pbgp_fatal("store_setup"); else pbgp_debug("setup open"); store_t *store_epoch = pbgp_store_open(NULL); if (!store_epoch) return pbgp_fatal("store_epoch"); else pbgp_debug("epoch open"); store_t *store_added = pbgp_store_open(NULL); if (!store_added) return pbgp_fatal("store_added"); else pbgp_debug("added open"); store_t *store_revoked = pbgp_store_open(NULL); if (!store_revoked) return pbgp_fatal("store_revoked"); else pbgp_debug("rvk open"); store_t *store_glb_added = pbgp_store_open(NULL); if (!store_glb_added) return pbgp_fatal("store_glb_added"); else pbgp_debug("glb ad open"); store_t *store_glb_revoked = pbgp_store_open(NULL); if (!store_glb_revoked) return pbgp_fatal("store_glb_revoked"); else pbgp_debug("glc rvk open"); /////////////////////////////// JOIN SOME ASNUM (ID) const uint32_t as[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; const char *pfxlist[] = { "123.122.121.1/24,123.122.122.1,123.122.122.1/16", "123.122.121.2/24,123.122.122.2,123.122.122.2/16", "123.122.121.3/24,123.122.122.3,123.122.122.3/16", "123.122.121.4/24,123.122.122.4,123.122.122.4/16", "123.122.121.5/24,123.122.122.5,123.122.122.5/16", "123.122.121.6/24,123.122.122.6,123.122.122.6/16", "123.122.121.7/24,123.122.122.7,123.122.122.7/16", "123.122.121.8/24,123.122.122.8,123.122.122.8/16", "123.122.121.9/24,123.122.122.9,123.122.122.9/16", }; uint32_t i, n = sizeof (as) / sizeof (as[0]); setup_params_t *setup = pbgp_setup_init(n + 1); pbgp_setup_fill(setup); // Save ibe __and__ rsa pubkeys for client (AS) pbgp_setup_save_pubkey(setup, store_setup); // IBE keypair for CA=0 for signing prefix list ibe_keypair_t *ibe_keypair = NULL; pbgp_ibe_keypair_init(setup, &ibe_keypair); pbgp_ibe_keypair_gen(setup, 0, ibe_keypair); for (i = 0; i < n; i++) { char *store_name = pbgp_generate_envelope_storage_name(as[i]); pbgp_debug("openening %s", store_name); // store_cidr_in is __always__ in memory database store_t *store_cidr_in = pbgp_store_open(NULL), *store_cidr_out = pbgp_store_open(store_name); // Parse prefixes and store into cidr_in pbgp_store_parsed_cidr(as[i], pfxlist[i], store_cidr_in); // - creates witness for this asnum (on empty list of added id) // - updates epoch asnum storages (store_added / store_revoked) // - calls join_save and write the envelope to storage (disk) pbgp_action_join(setup, ibe_keypair, as[i], store_cidr_in, store_cidr_out, store_added, store_revoked, store_glb_added, store_glb_revoked ); pbgp_debug("joined %s", store_name); pbgp_store_close(store_cidr_out); pbgp_store_close(store_cidr_in); xfree(store_name); } ////////////// UPDATE EPOCH ACCUMULATOR + GLOBAL ASNUM LIST + EPOCH SIGNATURES // // Saves epoch (calls pbgp_epoch_save) to store // This will update global storages (store_glb_added, store_glb_revoked) // pbgp_epoch_claim_new(setup, store_epoch, store_added, store_revoked, store_glb_added, store_glb_revoked ); /////// SERVER SIDE WORK ENDS HERE /////////////////////////////////////////// // Simulate client: reload setup pubkey (sent to the AS) setup_params_t *client_setup = pbgp_setup_init(n + 1); pbgp_setup_load_pubkey(client_setup, store_setup); pbgp_setup_pairing(client_setup); // For testing purpose we re-load epoch data from storage // in a real use case this will be executed by different parts epoch_t *epoch; pbgp_epoch_init(&epoch, client_setup); // this overwrites values in store_added / store_revoked (with themselves) pbgp_epoch_load(store_epoch, epoch, store_added, store_revoked); /////////////////////////////// START ACTIVE // Witness contained into envelope are outdated because there are new joined entities // in the for loop above (only the latest AS joined should be updated) store_iterator_t *iterator = NULL; store_key_t key = STORE_KEY_INIT; uint32_t asnum = 0; // For each asnum in globally active id for (iterator = pbgp_store_iterator_open(store_glb_added); pbgp_store_iterator_uget_next(iterator, STORE_KEY_SET_DATA(key, ASLIST, asnum), NULL, NULL) == 0; ) { char *store_name = pbgp_generate_envelope_storage_name(asnum); store_t *store_cidr_out = pbgp_store_open(store_name); uint32_t client_asnum; element_t client_witness; unsigned char *client_envelope_signature; size_t client_envelope_signature_size = 0; pbgp_debug("join load id:%d", asnum); // load asnum, witness, signature from envelope for this asnum pbgp_join_load(client_setup, store_cidr_out, &client_asnum, &client_witness, &client_envelope_signature, &client_envelope_signature_size); assert(client_asnum == asnum); // compute serialized = (asnum + witness) to check rsa signature on them unsigned char serialized[sizeof asnum + element_length_in_bytes(client_witness)]; memcpy(serialized, &client_asnum, sizeof client_asnum); element_to_bytes(serialized + sizeof client_asnum, client_witness); // verify envelope signature on serialized(asnum, witness) int ret = pbgp_rsa_verify(client_setup->rsa_evp, serialized, sizeof serialized, client_envelope_signature, client_envelope_signature_size); assert(ret == 1); // update envelope witness with new added / revoked id lists pbgp_witness_update(client_setup, store_added, store_revoked, asnum, client_witness); pbgp_store_put_element(store_cidr_out, STORE_KEY_SET_TYPE(key, JOIN, JOIN_WITNESS), client_witness); // ret = 0 if __not__ revoked (id into accumulator) ret = pbgp_is_revoked(setup, asnum, epoch->accumulator, client_witness); assert(ret == 0); // Loop on every prefix from join data and verify prefix signature store_iterator_t *_iterator = pbgp_store_iterator_open(store_cidr_out); while (1) { store_key_t key = STORE_KEY_INIT; size_t ksize = 0, dsize = 0; // Get [ cidr:asnum -> serialized(prefix + netmask + timestamp) ] int ret = pbgp_store_iterator_uget_next_size(_iterator, &ksize, &dsize); if (ret != 0) { break ; } ksize -= STORE_KEY_METADATA_LENGTH; unsigned char kbuf[ksize]; memset (kbuf, 0, ksize); key.data = kbuf; key.dsize = sizeof (kbuf); unsigned char data[dsize]; memset(data, 0, dsize); ret = pbgp_store_iterator_uget_next(_iterator, &key, data, &dsize); if (ret != 0) { break ; } pbgp_debug("reading join data ns=%d type=%d", key.ns, key.type); if (CIDR == key.ns && MESSAGE == key.type) { store_t *message_store = pbgp_store_open(NULL); // // At this point we have // - data = __signed__ serialized(prefix + netmask + timestamp) // - kbuf = cidr with cidr.index = asnum // cidr_t cidr; assert(sizeof (cidr) == key.dsize); memcpy(&cidr, key.data, key.dsize); if (cidr.index == asnum) { // Put [ asnum -> serialized(prefix + netmask + timestamp) ] into message storage store_key_t mkey = STORE_KEY_INIT; // ******* Messages are signed by ID(RIR=CA) id not by ID(AS) ******************* const uint32_t signer_id = 0; // Store [data = message] to pass it to ibe_vrfy pbgp_store_put(message_store, STORE_KEY_SET_DATA(mkey, IBE, signer_id), data, sizeof (data)); // Get signature for this prefix from join data / envelope size_t ssize = 0; cidr.index = SIGNATURE_INDEX; pbgp_store_uget_size(store_cidr_out, STORE_KEY_SET_DATA(mkey, CIDR, cidr), &ssize); assert(ssize > 0); // Signature is serialized, get the data buffer first unsigned char sbuf[ssize]; // store_cidr_out contains join data = envelope pbgp_store_uget(store_cidr_out, &mkey, sbuf, &ssize); // Let's unserialize ibe signature for this prefix ibe_signature_t *ibe_signature; pbgp_ibe_signature_init(client_setup, &ibe_signature); pbgp_ibe_signature_unserialize(sbuf, ibe_signature); // Finally verify ibe signature for this cidr + timestamp unsigned int verified = pbgp_ibe_verify(client_setup, ibe_signature, message_store); assert(verified == 0); pbgp_ibe_signature_clear(ibe_signature); } pbgp_store_close(message_store); } } pbgp_store_iterator_close(_iterator); // end prefix loop // Cleanup client (AS) data loaded from join envelope // __important__: clear elements __before__ freeing setup (pairing) element_clear(client_witness); pbgp_store_close(store_cidr_out); xfree(client_envelope_signature); xfree(store_name); } pbgp_store_iterator_close(iterator); /////////////////////////////// REVOCATION CHECK // // // Empty epoch added list for (i = 0; i < n; i ++) { pbgp_store_delete(store_added, STORE_KEY_SET_DATA(key, ASLIST, as[i])); } // Revoke some "odd" AS ;-) for (i = 0; i < n; i += 2) { pbgp_action_revoke(as[i], store_added, store_revoked, store_glb_added); } // Update accumulator and global list // this will save epoch data to storage (again) and update store_glb_revoked pbgp_epoch_claim_new(setup, store_epoch, store_added, store_revoked, store_glb_added, store_glb_revoked ); // Reload epoch data pbgp_epoch_clear(epoch); // setup should be client_setup in a real use case pbgp_epoch_init(&epoch, setup); // this overwrites values in store_added / store_revoked (with themselves) pbgp_epoch_load(store_epoch, epoch, store_added, store_revoked); // For each asnum check revocation for (i = 0; i < n; i++) { asnum = as[i]; char *store_name = pbgp_generate_envelope_storage_name(asnum); store_t *store_cidr_out = pbgp_store_open(store_name); uint32_t client_asnum; element_t client_witness; unsigned char *client_envelope_signature; size_t client_envelope_signature_size = 0; // load asnum, witness, signature from envelope for this asnum pbgp_join_load(client_setup, store_cidr_out, &client_asnum, &client_witness, &client_envelope_signature, &client_envelope_signature_size); assert(client_asnum == asnum); // verify epoch signatures on hashed added list memset (hash, 0, sizeof hash); hsize = pbgp_rsa_uhash_list_keys(store_added, hash); int verified = pbgp_rsa_verify(client_setup->rsa_evp, hash, hsize, epoch->signature_added, epoch->signature_added_len); assert(verified == 1); // verify epoch signatures on hashed revoked list memset (hash, 0, sizeof hash); hsize = pbgp_rsa_uhash_list_keys(store_revoked, hash); verified = pbgp_rsa_verify(client_setup->rsa_evp, hash, hsize, epoch->signature_revoked, epoch->signature_revoked_len); assert(verified == 1); // update witness pbgp_witness_update(client_setup, store_added, store_revoked, client_asnum, client_witness); pbgp_store_put_element(store_cidr_out, STORE_KEY_SET_TYPE(key, JOIN, JOIN_WITNESS), client_witness); // verify epoch signatures on accumulator unsigned char accbuf[element_length_in_bytes(epoch->accumulator)]; memset (accbuf, 0, sizeof (accbuf)); hsize = element_to_bytes(accbuf, epoch->accumulator); verified = pbgp_rsa_verify(client_setup->rsa_evp, accbuf, element_length_in_bytes(epoch->accumulator), epoch->signature_accumulator, epoch->signature_accumulator_len); assert(verified == 1); int revoked = pbgp_is_revoked(client_setup, client_asnum, epoch->accumulator, client_witness); if (asnum % 2) { assert(revoked); } else { assert(!revoked); } // Cleanup client (AS) data loaded from join envelope element_clear(client_witness); pbgp_store_close(store_cidr_out); xfree(client_envelope_signature); xfree(store_name); } /////////////////////////////// GLOBAL CLEANUP pbgp_ibe_keypair_clear(ibe_keypair); pbgp_epoch_clear(epoch); pbgp_setup_clear(&client_setup); pbgp_setup_clear(&setup); for (i = 0; i < n; i++) { char *store_name = pbgp_generate_envelope_storage_name(as[i]); unlink(store_name); } pbgp_store_close(store_epoch); pbgp_store_close(store_added); pbgp_store_close(store_revoked); pbgp_store_close(store_glb_added); pbgp_store_close(store_glb_revoked); return EXIT_SUCCESS; }
// 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; }
// XSGS USER JOIN - complete offline user join algorithm int xsgs_user_join_offline(XSGS_PUBLIC_KEY* gpk, XSGS_ISSUER_KEY* ik, XSGS_USER_CERT** ucert, XSGS_USER_KEY** uk, XSGS_USER_DB_ENTRY** udbe, char* usk_pem_filename) { element_t z, g11, g12; int ret = 0; *ucert = (XSGS_USER_CERT*) malloc(sizeof(XSGS_USER_CERT)); *uk = (XSGS_USER_KEY*) malloc(sizeof(XSGS_USER_KEY)); *udbe = (XSGS_USER_DB_ENTRY*) malloc(sizeof(XSGS_USER_DB_ENTRY)); element_init(z, gpk->pairing->Zr); element_init(g11, gpk->pairing->G1); element_init(g12, gpk->pairing->G1); // 1. choose x, y e Zp at random element_init((*ucert)->x, gpk->pairing->Zr); element_init((*udbe)->UCert.x, gpk->pairing->Zr); element_init((*uk)->y, gpk->pairing->Zr); element_random((*ucert)->x); element_set((*udbe)->UCert.x, (*ucert)->x); element_random((*uk)->y); // 2. C <- H^y element_init((*udbe)->C, gpk->pairing->G1); element_pow_naf((*udbe)->C, gpk->H, (*uk)->y); // 3. A <- (G1 * C)^{1/(gamma + x)} element_init((*ucert)->A, gpk->pairing->G1); element_init((*udbe)->UCert.A, gpk->pairing->G1); element_add(z, ik->gamma, (*ucert)->x); element_invert(z, z); element_mul((*ucert)->A, gpk->G1, (*udbe)->C); element_pow_naf((*ucert)->A, (*ucert)->A, z); element_set((*udbe)->UCert.A, (*ucert)->A); // 4. 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, &((*udbe)->S.sig), &((*udbe)->S.len)); free(msg); if (!ret) { // 5. check A^(x + gamma) = G1 * H^y element_add(z, ik->gamma, (*ucert)->x); element_pow_naf(g11, (*ucert)->A, z); element_pow_naf(g12, gpk->H, (*uk)->y); element_mul(g12, g12, gpk->G1); ret = element_cmp(g11, g12); } element_clear(z); element_clear(g11); element_clear(g12); return ret; }
static void test_gf3m_to_bytes(void) { element_random(a); element_to_bytes(data, a); element_from_bytes(b, data); EXPECT(0 == element_cmp(a, b)); }
// USER JOIN PHASE 1 - user key generation (Join) void xsgs_user_join_phase1(XSGS_PUBLIC_KEY* gpk, XSGS_USER_KEY* uk, XSGS_PAILLIER_PUBKEY* ppk, XSGS_JOIN_PHASE1* jpd1) { pairing_ptr pairing = gpk->pairing; field_ptr Fp = pairing->Zr; gmp_randstate_t rnd_state; mpz_t y, r, R1, h; element_t R2; // 1.choose y e Zp at random and element_init(uk->y, Fp); element_random(uk->y); // compute C <- H^y element_init_G1(jpd1->C, pairing); element_pow_naf(jpd1->C, gpk->H, uk->y); // 2. U = (c=ext-commit(y), NIZKPEqDL(c, C, H)) // c = ext-commit(y) = g^y mod n^2 mpz_init(y); mpz_init(jpd1->U.c); element_to_mpz(y, uk->y); mpz_powm(jpd1->U.c, ppk->g, y, ppk->n_squared); // zero-knowledge proof of c, C and H init_rand(rnd_state, PAILLIER_MODULO_BITS / 8 + 1); mpz_init(r); mpz_urandomb(r, rnd_state, PAILLIER_MODULO_BITS); gmp_randclear(rnd_state); // R1 = g^r mod n^2 mpz_init(R1); mpz_powm(R1, ppk->g, r, ppk->n_squared); // R2 = H^r element_init_G1(R2, pairing); element_pow_naf_mpz(R2, gpk->H, r); // 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(ppk->n) + 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, ppk->n); 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; jpd1->U.hash = (BYTE*) malloc(JOIN_HASH_BITS / 8); xsgs_hash(data_buf, data_len * 8, jpd1->U.hash, JOIN_HASH_BITS); free(data_buf); mpz_clear(R1); element_clear(R2); // s = r - h * y mpz_init(h); mpz_init(jpd1->U.s); mpz_from_hash(h, jpd1->U.hash, JOIN_HASH_BITS / 8); mpz_mul(jpd1->U.s, h, y); mpz_sub(jpd1->U.s, r, jpd1->U.s); mpz_clear(r); mpz_clear(y); mpz_clear(h); // return ( paillier = (pub, prv), C, U = (c, h, s) ) return; }
static int mulg_to_bytes(unsigned char *data, element_ptr e) { return element_to_bytes(data, e->data); }
// x in Z_r, g, h in some group of order r // finds x such that g^x = h void element_dlog_pollard_rho(element_t x, element_t g, element_t h) { // see Blake, Seroussi and Smart // only one snark for this implementation int i, s = 20; field_ptr Zr = x->field, G = g->field; element_t asum; element_t bsum; element_t a[s]; element_t b[s]; element_t m[s]; element_t g0, snark; darray_t hole; int interval = 5; mpz_t counter; int found = 0; mpz_init(counter); element_init(g0, G); element_init(snark, G); element_init(asum, Zr); element_init(bsum, Zr); darray_init(hole); //set up multipliers for (i = 0; i < s; i++) { element_init(a[i], Zr); element_init(b[i], Zr); element_init(m[i], G); element_random(a[i]); element_random(b[i]); element_pow_zn(g0, g, a[i]); element_pow_zn(m[i], h, b[i]); element_mul(m[i], m[i], g0); } element_random(asum); element_random(bsum); element_pow_zn(g0, g, asum); element_pow_zn(snark, h, bsum); element_mul(snark, snark, g0); record(asum, bsum, snark, hole, counter); for (;;) { int len = element_length_in_bytes(snark); unsigned char *buf = pbc_malloc(len); unsigned char hash = 0; element_to_bytes(buf, snark); for (i = 0; i < len; i++) { hash += buf[i]; } i = hash % s; pbc_free(buf); element_mul(snark, snark, m[i]); element_add(asum, asum, a[i]); element_add(bsum, bsum, b[i]); for (i = 0; i < hole->count; i++) { snapshot_ptr ss = hole->item[i]; if (!element_cmp(snark, ss->snark)) { element_sub(bsum, bsum, ss->b); element_sub(asum, ss->a, asum); //answer is x such that x * bsum = asum //complications arise if gcd(bsum, r) > 1 //which can happen if r is not prime if (!mpz_probab_prime_p(Zr->order, 10)) { mpz_t za, zb, zd, zm; mpz_init(za); mpz_init(zb); mpz_init(zd); mpz_init(zm); element_to_mpz(za, asum); element_to_mpz(zb, bsum); mpz_gcd(zd, zb, Zr->order); mpz_divexact(zm, Zr->order, zd); mpz_divexact(zb, zb, zd); //if zd does not divide za there is no solution mpz_divexact(za, za, zd); mpz_invert(zb, zb, zm); mpz_mul(zb, za, zb); mpz_mod(zb, zb, zm); do { element_pow_mpz(g0, g, zb); if (!element_cmp(g0, h)) { element_set_mpz(x, zb); break; } mpz_add(zb, zb, zm); mpz_sub_ui(zd, zd, 1); } while (mpz_sgn(zd)); mpz_clear(zm); mpz_clear(za); mpz_clear(zb); mpz_clear(zd); } else { element_div(x, asum, bsum); } found = 1; break; } } if (found) break; mpz_add_ui(counter, counter, 1); if (mpz_tstbit(counter, interval)) { record(asum, bsum, snark, hole, counter); interval++; } } for (i = 0; i < s; i++) { element_clear(a[i]); element_clear(b[i]); element_clear(m[i]); } element_clear(g0); element_clear(snark); for (i = 0; i < hole->count; i++) { snapshot_ptr ss = hole->item[i]; element_clear(ss->a); element_clear(ss->b); element_clear(ss->snark); pbc_free(ss); } darray_clear(hole); element_clear(asum); element_clear(bsum); mpz_clear(counter); }
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); }