I'm working in Visual Studio 2012. In Debug mode the program works fine, however, when changed to release mode the program fails on the call to element_to_mpz() which is called by the PBC function element_pow_zn()
I'm using MS VC++ Convertion of PBC from their download page.
The call stack seems to indicate there is an error on a call to _realloc(). I believe I found the line responsible. In the PBC source, line 133 of montfp.c (the _mpz_realloc() call)
static void fp_to_mpz(mpz_ptr z, element_ptr e) {
eptr ep = e->data;
if (!ep->flag) mpz_set_ui(z, 0);
else {
// x is stored as xR.
// We must divide out R to convert to standard representation.
fptr p = e->field->data;
mp_limb_t tmp[2 * p->limbs];
memcpy(tmp, ep->d, p->limbs * sizeof(mp_limb_t));
memset(&tmp[p->limbs], 0, p->limbs * sizeof(mp_limb_t));
/**************************************************************************
* The line I believe to be failing - However I can't step into PBC.dll as
* I do not have the symbols.
**************************************************************************/
_mpz_realloc(z, p->limbs);//This is a call into the GMP library
mont_reduce(z->_mp_d, tmp, p);
// Remove leading zero limbs.
for (z->_mp_size = p->limbs; !z->_mp_d[z->_mp_size - 1]; z->_mp_size--);
}
}
The code I am using to actually call element_to_mpz() is:
bswabe_cph_t*
bswabe_enc( bswabe_pub_t* pub, element_t m, char* policy )
{
bswabe_cph_t* cph;
element_t s;
cph = (bswabe_cph_t*)malloc(sizeof(bswabe_cph_t));
element_init_Zr(s, pub->p);
element_init_GT(m, pub->p);
element_init_GT(cph->cs, pub->p);
element_init_G1(cph->c, pub->p);
cph->p = parse_policy_postfix(policy);
element_random(m);
element_random(s);
/****************************************************
* The call to element_to_mpz() is in element_pow_zn()
*****************************************************/
element_pow_zn(cph->cs, pub->g_hat_alpha, s);
element_mul(cph->cs, cph->cs, m);
element_pow_zn(cph->c, pub->h, s);
fill_policy(cph->p, pub, s);
return cph;
}
The above code is from CPABE - Which is a library for policy based encryption. The arguments pub, m, and policy are all properly initialized from the calling environment.
I'm not sure if this is a bug in the CPABE code, the PBC, code or a bug in GMP. (since that's where _mpz_realloc() is defined)
Any help would be greatly appreciated.
To fix this issue I replaced the GMP requirement with MPIR. It can be built with VS2012 and used as a drop-in replacement for GMP. After switching to this library the issue went away.
I'm guessing the cause of my issue was a bug in GMP-4.1. Since I also couldn't get GMP-5.1 compiled and working with VC++ I could never verify that the bug is actually gone from GMP.