herumi / mcl

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

tests fail with segfault on x86-64 and Ubuntu #45

Closed mortdeus closed 5 years ago

mortdeus commented 5 years ago

I am having an issue with xbyak that is causing some of the tests (most importantly bn_test.exe) to crash. I have investigated the issue and concluded that the problem has something to do with xbyak because the problem goes away whenever xbyak is not enabled.

However having xbyak disabled leads to further breakage when trying to compile bls with the xbyak disabled mcl library. (that error is related to an undefined reference to a fp::Op related function that is #ifdef'd out in the mcl code whenever MCL_USE_XBYAK=1 is set)

mortdeus commented 5 years ago

here is the last part of the makefile's stdout where it fails.

test bin/fp_test.exe bin/ec_test.exe bin/fp_util_test.exe bin/window_method_test.exe bin/elgamal_test.exe bin/fp_tower_test.exe bin/gmp_test.exe bin/bn_test.exe bin/bn384_test.exe bin/glv_test.exe bin/paillier_test.exe bin/she_test.exe bin/vint_test.exe bin/bn512_test.exe bin/ecdsa_test.exe bin/conversion_test.exe bin/bn_c256_test.exe bin/bn_c384_test.exe bin/bn_c384_256_test.exe bin/bn_c512_test.exe bin/she_c256_test.exe bin/she_c384_test.exe bin/aggregate_sig_test.exe bin/array_test.exe bin/bls12_test.exe bin/ecdsa_c_test.exe bin/mont_fp_test.exe bin/sq_test.exe bin/fp_generator_test.exe
AddressSanitizer:DEADLYSIGNAL

=================================================================
==14810==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7ffc42e3a660 sp 0x7ffc42e3a558 T0)
==14810==Hint: pc points to the zero page.
==14810==The signal is caused by a READ memory access.
==14810==Hint: address points to the zero page.

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==14810==ABORTING
Makefile:275: recipe for target 'test' failed
make: *** [test] Error 1
mortdeus commented 5 years ago

and here is the backtrace at the moment the test crashes.

(gdb) run
Starting program: /home/mortdeus/work/mcl/bin/bn_test.exe 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
JIT 1
ctest:module=size
ctest:module=naive
i=0 curve=BN254

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00000000004f6320 in mcl::fp::invOpForMontC (y=0x7b9720 <mcl::FpT<mcl::bn::local::FrTag, 256ul>::inv2_>, x=0x7fffffffc740, op=...)
    at src/fp.cpp:274
#2  0x00000000004652df in mcl::FpT<mcl::bn::local::FrTag, 256ul>::inv (y=..., x=...) at include/mcl/fp.hpp:407
#3  0x000000000045335e in mcl::FpT<mcl::bn::local::FrTag, 256ul>::init (pb=0x7fffffffd390, xi_a=0, p=..., mode=mcl::fp::FP_AUTO)
    at include/mcl/fp.hpp:133
#4  0x0000000000444507 in mcl::FpT<mcl::bn::local::FrTag, 256ul>::init (pb=0x7fffffffd390, p=..., mode=mcl::fp::FP_AUTO) at include/mcl/fp.hpp:150
#5  0x000000000042c583 in mcl::bn::local::Param::init (this=0x7b85a0 <mcl::bn::local::StaticVar<0ul>::param>, pb=0x7fffffffd390, cp=..., 
    mode=mcl::fp::FP_AUTO) at include/mcl/bn.hpp:1046
#6  0x0000000000436564 in mcl::bn::BN::init (pb=0x7fffffffd390, cp=..., mode=mcl::fp::FP_AUTO) at include/mcl/bn.hpp:2163
#7  0x0000000000436713 in mcl::bn::initPairing (cp=..., mode=mcl::fp::FP_AUTO) at include/mcl/bn.hpp:2193
#8  0x0000000000416d4d in cybozu_test_naive () at test/bn_test.cpp:355
#9  0x00000000004197d4 in cybozu::test::AutoRun::run (this=0x7b8500 <cybozu::test::AutoRun::getInstance()::instance>, argv=0x7fffffffe138)
    at include/cybozu/test.hpp:72
#10 0x0000000000417950 in main (argc=1, argv=0x7fffffffe138) at test/bn_test.cpp:398
mortdeus commented 5 years ago

according to gdb the issue has to do with op.fp_preInv being null

#ifdef MCL_USE_XBYAK
inline void invOpForMontC(Unit *y, const Unit *x, const Op& op)
{
    Unit r[maxUnitSize];
    int k = op.fp_preInv(r, x);
    /*
        S = UnitBitSize
        xr = 2^k
        R = 2^(N * S)
        get r2^(-k)R^2 = r 2^(N * S * 2 - k)
    */
    op.fp_mul(y, r, op.invTbl.data() + k * op.N, op.p);
}
mortdeus commented 5 years ago

can you elaborate more on this?

    if (op.primeMode != PM_NIST_P192 && op.N <= 4) { // support general op.N but not fast for op.N > 4
            align(16);
            op.fp_preInv = getCurr<int2u>();
            gen_preInv();
            prof_.set("preInv", getCurr());
        }
mortdeus commented 5 years ago

okay so the issue is that if the CPU doesn't support AVX (as mine doesn't) then the fp_preInv function pointer is never initialized.

herumi commented 5 years ago

Thank you for the detailed report. I fixed it. https://github.com/herumi/mcl/commit/6ef8f3db38f6a60cfe6c091b9f6d6a888b2325e1

mortdeus commented 5 years ago

@herumi is there a way that i can talk to you more directly. (e.g. discord or irc?)

mortdeus commented 5 years ago

im doing a lot of work related to your libraries right now (which according to your commit history it seems to be that were working on the same thing [i.e go integration]) and I have a few questions i was hoping you could clear up.

herumi commented 5 years ago

At first, could you mail to me (herumi@nifty.com)?