herumi / mcl

a portable and fast pairing-based cryptography library
BSD 3-Clause "New" or "Revised" License
458 stars 157 forks source link

static variables init order #64

Closed huyuguang closed 5 years ago

huyuguang commented 5 years ago

I init the mcl with code like:

static struct LibInit {
    LibInit()
    {
        mcl::bn256::initPairing(mcl::bn::CurveSNARK1); // init mcl library
    }
} s_libInit;

And I got an exception in xbyak.h RegExp::RegExp(...). The caller function is MixPack::init and the code is this->m = Xbyak::util::rsp + rspPos;

The static const Xbyak::util::rsp is not initialized yet. I print the rsp, looks like:

(gdb) print Xbyak::util::rsp
$5 = {<Xbyak::Reg32e> = {<Xbyak::Reg> = {<Xbyak::Operand> = {static EXT8BIT = 32 ' ', idx_ = 0, kind_ = 0, bit_ = 0, zero_ = 0, mask_ = 0,
        rounding_ = 0}, <No data fields>}, <No data fields>}, <No data fields>}

I understand that the c++ static variables init order is somehow like magic. So it seems that I should not init the mcl by a static variable's constructor. But I need to define some global variables looks like:

std::vector<size_t> mcl_bn128_G1::wnaf_window_table;
std::vector<size_t> mcl_bn128_G1::fixed_base_exp_window_table;
mcl_bn128_G1 mcl_bn128_G1::G1_zero;
mcl_bn128_G1 mcl_bn128_G1::G1_one;

So, what should I do? Any suggestion? Thanks.

huyuguang commented 5 years ago

I use a dirty trick to workaround this issue:

std::vector<size_t> &alt_bn128_G2::wnaf_window_table() {
  static std::vector<size_t> _wnaf_window_table_;
  return _wnaf_window_table_;
}
std::vector<size_t> &alt_bn128_G2::fixed_base_exp_window_table(){
  static std::vector<size_t> _fixed_base_exp_window_table_;
  return _fixed_base_exp_window_table_;
}
alt_bn128_G2 &alt_bn128_G2::G2_zero() {
  static alt_bn128_G2 _G2_zero_;
  return _G2_zero_;
}
alt_bn128_G2 &alt_bn128_G2::G2_one() {
  static alt_bn128_G2 _G2_one_;
  return _G2_one_;
}

So the key is: do not use global variables of the mcl type, use functions with a static variable.