-
Notifications
You must be signed in to change notification settings - Fork 744
Closed
Description
When serializing/deserializing Plaintexts, there was an inconsistent size estimation resulting from an improper type when computing ComprSizeEstimate.
Previously, when running the following code:
plaintext.h line ~572:
SEAL_NODISCARD inline std::streamoff save_size(
compr_mode_type compr_mode) const
{
std::size_t members_size = Serialization::ComprSizeEstimate(
util::add_safe(
sizeof(parms_id_),
sizeof(coeff_count_), // <--------------------- Offending member
sizeof(scale_),
util::safe_cast<std::size_t>(
data_.save_size(compr_mode_type::none))),
compr_mode);
std::cout << "Plaintext::save_size member_size (" << members_size << ")" <<std::endl;
auto size = util::safe_cast<std::streamoff>(util::add_safe(
sizeof(Serialization::SEALHeader),
members_size
));
std::cout << "Plaintext::save_size size (" << size << ")" <<std::endl;
return size;
// return util::safe_cast<std::streamoff>(util::add_safe(
// sizeof(Serialization::SEALHeader),
// members_size
// ));
}
Results in the incorrect member_size:
Plaintext::save_size member_size (32836)
Plaintext::save_size size (32852)
This, in turn, becomes an issue when deserializing a saved Plaintext stream where the stream.tellg() position calculation throws here:
serialization.cpp line ~657:
if (header.size != stream.tellg() - stream_start_pos)
Replacing it with the following:
SEAL_NODISCARD inline std::streamoff save_size(
compr_mode_type compr_mode) const
{
std::size_t members_size = Serialization::ComprSizeEstimate(
util::add_safe(
sizeof(parms_id_),
sizeof(uint64_t), // coeff_count_ <--------------------- Modified member
sizeof(scale_),
util::safe_cast<std::size_t>(
data_.save_size(compr_mode_type::none))),
compr_mode);
std::cout << "Plaintext::save_size member_size (" << members_size << ")" <<std::endl;
auto size = util::safe_cast<std::streamoff>(util::add_safe(
sizeof(Serialization::SEALHeader),
members_size
));
std::cout << "Plaintext::save_size size (" << size << ")" <<std::endl;
return size;
// return util::safe_cast<std::streamoff>(util::add_safe(
// sizeof(Serialization::SEALHeader),
// members_size
// ));
Results in the correct member_size:
Plaintext::save_size member_size (32840)
Plaintext::save_size size (32856)
This change in Plaintext.h resembles the uint64_t setting for coeff_mod_count_ in Ciphertext.cpp.
Parameters to reproduce (pseudo code):
EncParms: {
schemeType: BFV,
polyModulusDegree: 4096,
security: tc128,
plainModulus: Batching(polyModulusDegree: 4096, bitsize: 20)
coeffModulus: BFVDefault(polyModulusDegree: 4096,
security: tc128)
}
Context: {
expandModChain: true,
security: tc128
}
Create a Plaintext and encode 4096 (max size of polyModulusDegree) misc values to it (within range)
Save the plaintext to a stream. (where the header size is computed incorrectly)
Attempt to load from the same stream. (where it throws during runtime)
Metadata
Metadata
Assignees
Labels
No labels