openfheorg / openfhe-development

This is the development repository for the OpenFHE library. The current (stable) version is v1.2.3 (released on October 30, 2024).
BSD 2-Clause "Simplified" License
758 stars 190 forks source link

Simultaneous SetKeySwitchTechnique(BV) and SetEncryptionTechnique(EXTENDED) Causing Crashes in BGV/CKKS #366

Closed ailanxier closed 1 year ago

ailanxier commented 1 year ago

Although the EXTENDED mode is designed for BFV encryption, incorrect use of SetEncryptionTechnique(EXTENDED) in CKKS and BGV schemes can lead to segmentation fault. In simple-integers-bgvrns example and simple-real-numbers example, combining SetKeySwitchTechnique(BV) and SetEncryptionTechnique(EXTENDED) will result in errors as follows. It may be necessary to catch exceptions when using SetEncryptionTechnique(EXTENDED) in these two schemes.

// simple-integers-bgvrns.cpp:
    parameters.SetMultiplicativeDepth(2);
    parameters.SetPlaintextModulus(65537);
    parameters.SetKeySwitchTechnique(BV);            // new line
    parameters.SetEncryptionTechnique(EXTENDED);     // new line
    parameters.SetDigitSize(30);

    CryptoContext<DCRTPoly> cryptoContext = GenCryptoContext(parameters);    
    KeyPair<DCRTPoly> keyPair;

    // Generate a public/private key pair
    keyPair = cryptoContext->KeyGen();    // crash here: simple-integers-bgvrns.cpp:63

// Not use ASAN
[1]    185146 segmentation fault (core dumped)  ./bin/simple-integers-bgvrns

// ASAN report
AddressSanitizer:DEADLYSIGNAL
=================================================================
==186318==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000000a0 (pc 0x55f9f5974656 bp 0x55f9f5d3b6a0 sp 0x7ffc40f208c0 T0)
==186318==The signal is caused by a READ memory access.
==186318==Hint: address points to the zero page.
    #0 0x55f9f5974656 in std::vector<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > >, std::allocator<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > > > >::size() const /usr/include/c++/11/bits/stl_vector.h:919
    #1 0x55f9f5974656 in lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > >::DCRTPolyImpl(lbcrypto::TernaryUniformGeneratorImpl<intnat::NativeVectorT<intnat::NativeIntegerT<unsigned long> > > const&, std::shared_ptr<lbcrypto::ILDCRTParams<bigintdyn::ubint<unsigned int> > >, Format, unsigned int) /root/openfhe-development/src/core/lib/lattice/hal/default/dcrtpoly.cpp:309
    #2 0x55f9f555aba0 in lbcrypto::PKEBase<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen(std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, bool) /root/openfhe-development/src/pke/lib/schemebase/base-pke.cpp:65
    #3 0x55f9f545141c in lbcrypto::SchemeBase<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen(std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, bool) /root/openfhe-development/src/pke/lib/schemebase/base-scheme.cpp:42
    #4 0x55f9f5198dd1 in lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen() /root/openfhe-development/src/pke/include/cryptocontext.h:1022
    #5 0x55f9f50bcbf8 in main /root/openfhe-development/src/pke/examples/simple-integers-bgvrns.cpp:63
    #6 0x7f6cb8c0ad8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    #7 0x7f6cb8c0ae3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    #8 0x55f9f50fadd4 in _start (/root/openfhe-development/build_static/bin/simple-integers-bgvrns+0xf2dd4)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/include/c++/11/bits/stl_vector.h:919 in std::vector<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > >, std::allocator<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > > > >::size() const
==186318==ABORTING
// simple-real-numbers.cpp:
    CCParams<CryptoContextCKKSRNS> parameters;
    parameters.SetMultiplicativeDepth(multDepth);  
    parameters.SetScalingModSize(scaleModSize);    
    parameters.SetBatchSize(batchSize);           
    parameters.SetKeySwitchTechnique(BV);            // new line
    parameters.SetEncryptionTechnique(EXTENDED);     // new line
    CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);  

    auto keys = cc->KeyGen(); // crash here: simple-real-numbers.cpp:142

// Not use ASAN
[1]    184183 segmentation fault (core dumped)  ./bin/simple-real-numbers

// ASAN report
==186621==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000000a0 (pc 0x55f0ff58cf56 bp 0x55f0ff969880 sp 0x7ffcb3622060 T0)
==186621==The signal is caused by a READ memory access.
==186621==Hint: address points to the zero page.
    #0 0x55f0ff58cf56 in std::vector<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > >, std::allocator<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > > > >::size() const /usr/include/c++/11/bits/stl_vector.h:919
    #1 0x55f0ff58cf56 in lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > >::DCRTPolyImpl(lbcrypto::TernaryUniformGeneratorImpl<intnat::NativeVectorT<intnat::NativeIntegerT<unsigned long> > > const&, std::shared_ptr<lbcrypto::ILDCRTParams<bigintdyn::ubint<unsigned int> > >, Format, unsigned int) /root/openfhe-development/src/core/lib/lattice/hal/default/dcrtpoly.cpp:309
    #2 0x55f0ff178ae0 in lbcrypto::PKEBase<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen(std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, bool) /root/openfhe-development/src/pke/lib/schemebase/base-pke.cpp:65
    #3 0x55f0fef111fc in lbcrypto::SchemeBase<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen(std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, bool) /root/openfhe-development/src/pke/lib/schemebase/base-scheme.cpp:42
    #4 0x55f0fecaa0a1 in lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen() /root/openfhe-development/src/pke/include/cryptocontext.h:1022
    #5 0x55f0febc385f in main /root/openfhe-development/src/pke/examples/simple-real-numbers.cpp:142
    #6 0x7fbf6b806d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    #7 0x7fbf6b806e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    #8 0x55f0fec01594 in _start (/root/openfhe-development/build_static/bin/simple-real-numbers+0x113594)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/include/c++/11/bits/stl_vector.h:919 in std::vector<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > >, std::allocator<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > > > >::size() const
==186621==ABORTING

Also, I found that using SetPREMode(NOT_SET) and SetEncryptionTechnique(EXTENDED) simultaneously can also lead to the same error.

// simple-integers-bgvrns.cpp:
    CCParams<CryptoContextBGVRNS> parameters;
    parameters.SetMultiplicativeDepth(2);
    parameters.SetPlaintextModulus(65537);
    parameters.SetPREMode(NOT_SET);                  // new line
    parameters.SetEncryptionTechnique(EXTENDED);     // new line

    CryptoContext<DCRTPoly> cryptoContext = GenCryptoContext(parameters);   

    KeyPair<DCRTPoly> keyPair;

    // Generate a public/private key pair
    keyPair = cryptoContext->KeyGen();     // simple-integers-bgvrns.cpp:60

// Not use ASAN
[1]    389468 segmentation fault  ./bin/simple-integers-bgvrns

// ASAN report
AddressSanitizer:DEADLYSIGNAL
=================================================================
==389054==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000000a0 (pc 0x55920cf2dc29 bp 0x7ffcd6a7fb50 sp 0x7ffcd6a7f920 T0)
==389054==The signal is caused by a READ memory access.
==389054==Hint: address points to the zero page.
    #0 0x55920cf2dc29 in std::vector<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > >, std::allocator<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > > > >::size() const /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h
    #1 0x55920cf2dc29 in lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > >::DCRTPolyImpl(lbcrypto::TernaryUniformGeneratorImpl<intnat::NativeVectorT<intnat::NativeIntegerT<unsigned long> > > const&, std::shared_ptr<lbcrypto::ILDCRTParams<bigintdyn::ubint<unsigned int> > >, Format, unsigned int) /root/openfhe-development/src/core/lib/lattice/hal/default/dcrtpoly.cpp:309
    #2 0x55920cce0b99 in lbcrypto::PKEBase<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen(std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, bool) /root/openfhe-development/src/pke/lib/schemebase/base-pke.cpp:65
    #3 0x55920cc15ed1 in lbcrypto::SchemeBase<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen(std::shared_ptr<lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > > >, bool) /root/openfhe-development/src/pke/lib/schemebase/base-scheme.cpp:42
    #4 0x55920c93b723 in lbcrypto::CryptoContextImpl<lbcrypto::DCRTPolyImpl<bigintdyn::mubintvec<bigintdyn::ubint<unsigned int> > > >::KeyGen() /root/openfhe-development/src/pke/include/cryptocontext.h:1022
    #5 0x55920c9254c5 in main /root/openfhe-development/src/pke/examples/simple-integers-bgvrns.cpp:60
    #6 0x7f4aadd1cd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    #7 0x7f4aadd1ce3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    #8 0x55920c924ee4 in _start (/root/openfhe-development/build_static/bin/simple-integers-bgvrns+0x6bee4)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h in std::vector<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > >, std::allocator<std::shared_ptr<lbcrypto::ILParamsImpl<intnat::NativeIntegerT<unsigned long> > > > >::size() const
==389054==ABORTING
dsuponitskiy commented 1 year ago

A fix is currently available in the dev branch of OpenFHE. We will move it to main with the next OpenFHE release.