Выполните добавление к продукту, используя библиотеку SEAL

Я пытаюсь выполнить операцию в форме: (A * B) + C. Умножение работает нормально, так как все числа имеют одинаковую шкалу в этой точке, но произведение A * B имеет другую шкалу, чем C. Имеет смысл, что умножение изменит масштаб, но мне было интересно, есть ли способ выполнить такую ​​операцию, используя библиотеку SEAL.

Информация об окружающей среде:

  1. Язык: C++
  2. Схема шифрования: CKKS
  3. Маленькие закодированные двойные числа (например, 0,4531)
  4. Шкала, используемая для кодирования: pow(2.0, 60) как в примере

Заранее спасибо и дайте мне знать, если потребуется дополнительная информация.

1 ответ

Решение

Есть несколько способов заставить это работать. Например, предположим, что все шифротексты A, B, C имеют одинаковый масштаб Z. Тогда A * B будет иметь масштаб Z^2. На этом этапе вам следует также перераспределить A * B, если у вас нет веских причин не делать этого.

Например, для вычисления A * B + C вы можете:

  • перекодировать C (если у вас есть открытый текст) со шкалой Z ^ 2 и использовать его вместо этого;
  • использование multiply_plain умножить C на скалярный открытый текст 1,0 со шкалой Z, чтобы увеличить масштаб до Z ^ 2, но сохранить значение таким же (существует перегрузка для CKKSEncoder::encode за это);
  • сначала измените масштаб A * B, чтобы он имел масштаб Z^2/q_k, где q_k - последнее простое число в coeff_modulus, Теперь вы можете перекодировать C, чтобы иметь масштаб точно Z^2/q_k (если у вас есть открытый текст), или умножить C на скалярный текст 1.0, как объяснено выше, чтобы изменить масштаб точно на Z^2/q_k;
  • если Z близко к q_k, так что Z^2/q_k ~ Z, то после изменения масштаба вы можете просто использовать 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 должно быть отчетливым).
Другие вопросы по тегам