Я пытаюсь выполнить операцию, которая имеет вид: (A * B) + C. Умножение работает нормально, так как все числа имеют одинаковую шкалу в этой точке, но произведение A * B имеет другую шкалу, чем C. Имеет смысл, что умножение изменит масштаб, но мне было интересно, есть ли способ выполнить такую операцию, используя библиотеку SEAL.
Информация об окружающей среде:
Заранее спасибо и дайте мне знать, если потребуется дополнительная информация.
Есть несколько способов заставить это работать. Например, предположим, что все шифротексты A, B, C имеют одинаковый масштаб Z. Тогда A * B будет иметь масштаб Z ^ 2. На этом этапе вам следует также переориентировать A * B, если у вас нет веских причин не делать этого.
Например, чтобы вычислить A * B + C, вы можете:
multiply_plain
умножить C на скалярный текст 1,0 с масштабом Z, чтобы увеличить масштаб до Z ^ 2, но сохранить значение таким же (существует перегрузка для CKKSEncoder::encode
за это);coeff_modulus
, Теперь вы можете перекодировать C, чтобы иметь масштаб точно Z ^ 2 / q_k (если у вас есть открытый текст), или умножить C на скалярный текст 1.0, как объяснено выше, чтобы изменить масштаб точно на Z ^ 2 / q_k; double &Ciphertext::scale()
чтобы установить шкалу A * B точно C.scale()
за счет небольшой мультипликативной ошибки ~ Z / q_k. Например, вместо шкалы 2 ^ 60 для A, B, C вы можете использовать static_cast<double>(parms.coeff_modulus().back())
, Тогда Z ^ 2 / q_k = Z (точно), и сложение работает сразу без переключения шкалы. Конечно, это уже не так хорошо работает после второго умножения + масштабирования, так как число от второго до последнего больше не может быть равно Z (все простые числа в coeff_modulus
должно быть отчетливым).Других решений пока нет …