Beispiel #1
0
size_t
pbgp_ibe_serialized_signature_size(ibe_signature_t *signature)
{
  return (size_t) element_length_in_bytes(signature->u) +
         element_length_in_bytes(signature->w) +
         element_length_in_bytes(signature->v);
}
Beispiel #2
0
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);
	/////////////////////////	
}
Beispiel #3
0
/**
 * @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;
}
Beispiel #4
0
// 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;
}
/*
 * Returns the length of the given element in bytes.
 * We assume that elements from G1 and G2 can be compressed, while elements from GT can't.
 */
int BilinearMappingHandler::getElementLengthInBytes(element_t elem, bool isElementOfGT)
{
	if (isElementOfGT)
		return element_length_in_bytes(elem);   //members of GT can't be compressed
	else
		return element_length_in_bytes_compressed(elem);  //members of G1/G2 can be compressed
}//end of getElementLengthInByte()
Beispiel #6
0
int
newepoch_gen(char *out,epoch_item_t *ep,setup_params_t *setup)
{
      char *accstr = NULL;
      int elem_size = 0;
      
      //update the accumulator 
      acc_update(ep->acc,ep->epls.act,ep->epls.rvk,setup);
      ep->epoch++;
      //sign epoch revoked list
      sign_list_rsa(ep->s_rvk,setup,ep->epls.rvk);
      //sign epoch added list      
      sign_list_rsa(ep->s_new,setup,ep->epls.act);

      elem_size = element_length_in_bytes(ep->acc->elem);
      accstr = (char *) malloc(elem_size);
      if(!accstr) {
            pbgp_error("newepoch :: %s\n",strerror(errno));
            return -1;
      }

      element_snprintf(accstr,elem_size,"%B",ep->acc->elem);
      //sign accumulator value
      sign_rsa(ep->s_acc,setup,(uint8_t *)accstr);

      //dump envelope
      newepoch_save(out,ep,setup);
      
      free(accstr); 
      return 0;  
}
Beispiel #7
0
//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 );	
}
Beispiel #8
0
/**
 *  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));
  }
}
Beispiel #9
0
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);
}
Beispiel #10
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);
}
Beispiel #11
0
//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 ;
}
int main(int argc, char ** argv) {
  pbc_param_t ec_params;
  pairing_t pairing;
  unsigned int rbits = 40, qbits = 128;
  element_t *g1, *g2, *gt;
  
  for (int s = 10; s <= 1000; s += 10) {
  while (qbits <= 4096) {
    fprintf(stderr, "%d", qbits);
    pbc_param_init_a_gen(ec_params, rbits, qbits);

    pairing_init_pbc_param(pairing, ec_params);


    element_init_G1(g1, pairing);
    element_init_G2(g2, pairing);
    element_init_GT(gt, pairing);

    struct timeval tv1, tv2;
    int bc = element_length_in_bytes(g1);

    for (int i = 0; i < 100; i++) {
      if (0 == i % 10)
	fprintf(stderr, ".");

      element_random(g1);
      element_random(g2);

      gettimeofday(&tv1, NULL);
      pairing_apply(gt, g1, g2, pairing);
      gettimeofday(&tv2, NULL);

      double time = tv2.tv_sec - tv1.tv_sec;
      time *= (1000 * 1000);
      time += tv2.tv_usec - tv1.tv_usec;

      fprintf(stdout, "%d %d %d %d %d\n", bc, rbits, qbits, i, ((int) time));
    }

    for (int j = 0; j < s; j++) {
      element_clear(g1[j]);
      element_clear(g2[j]);
      element_clear(gt[j]);
    }

    rbits *= 2;
    qbits *= 2;

    fprintf(stderr, "\n");
  }
  free(g1);
  free(g2);
  free(g3);
  }
}
Beispiel #13
0
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;
}
Beispiel #14
0
static int fq_length_in_bytes(element_ptr e) {
  eptr p = e->data;
  return element_length_in_bytes(p->x) + element_length_in_bytes(p->y);
}
Beispiel #15
0
static int mulg_length_in_bytes(element_ptr e) {
  return element_length_in_bytes(e->data);
}
Beispiel #16
0
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;
		}
	}
Beispiel #17
0
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);
}
Beispiel #18
0
// 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;
}
Beispiel #19
0
// 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;
}
Beispiel #20
0
int
join_save(action_data_t *join)
{
      FILE *fpout = NULL;
      int rv = 0, i = 0;
      uint32_t elem_size = 0 ;
      uint8_t *buf = NULL;
      char fname[MAX_ENVEL_NAME];
	  unsigned char *sbuf = NULL;


      if(!join) {
    	  errno = EINVAL;
    	  pbgp_error("join_save :: join is null");
    	  return -1;
      }

      sprintf(fname,"id-%d.env",join->ibk->id->asnum);
           
      fpout = fopen(fname,"wb");
      if(!fpout) {
            pbgp_error("join_datasave :: %s\n",strerror(errno));
            return -1;
      }
     
      rv = ibe_keypair_savefp(fpout,join->ibk);
      if(rv < 0 ) {
            pbgp_error("join_datasave :: %s\n",strerror(errno));
            return -1;
      }
 
      elem_size = element_length_in_bytes(join->witness);
      fwrite(&elem_size,sizeof(uint32_t),1,fpout);

      buf = (uint8_t *) malloc(elem_size);
      if(!buf) {
            pbgp_error("join_datasave :: %s\n",strerror(errno));
            return -1;
      } 
      element_to_bytes(buf,join->witness);
      fwrite(buf,elem_size,1,fpout);
      
      fwrite(&join->pfixlist->size,sizeof(uint32_t),1,fpout);
      //write prefix list + signatures
      for(i = 0; i < join->pfixlist->size; i++) {
            fwrite(&join->pfixlist->ina[i],sizeof(struct in_addr),1,fpout);
            fwrite(&join->pfixlist->netmask[i],sizeof(uint8_t),1,fpout);

            elem_size = ibe_signature_serialize(&sbuf,join->pfixlist->pf_sign[i]);

            if(elem_size < 0 ) {
            	rv = -1;
            	break;
            }

            fwrite(&elem_size,sizeof(uint32_t),1,fpout);
            fwrite(sbuf,elem_size,1,fpout);

            free(sbuf);
            sbuf = NULL;
      }

      fwrite(&join->pfixlist->tsca,sizeof(time_t),1,fpout);

      if(sbuf) free(sbuf);
      if(buf)  free(buf);
      fclose(fpout);

      return rv;
}
Beispiel #21
0
int element_length_in_bytes_x_only(element_ptr e) {
	point_ptr P = (point_ptr)e->data;
  return element_length_in_bytes(P->x);
}
Beispiel #22
0
// 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;
}
Beispiel #23
0
int element_length_in_bytes_compressed(element_ptr e) {
	point_ptr P = (point_ptr)e->data;
  return element_length_in_bytes(P->x) + 1;
}
Beispiel #24
0
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;
}
Beispiel #25
0
// 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;
}
Beispiel #26
0
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;
}
Beispiel #27
0
// 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);
}
Beispiel #28
0
static int curve_length_in_bytes(element_ptr x) {
	point_ptr p = (point_ptr)x->data;
  return element_length_in_bytes(p->x) + element_length_in_bytes(p->y);
}