Выполните добавление к продукту, используя библиотеку SEAL - PullRequest
0 голосов
/ 26 декабря 2018

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

Информация об окружении:

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

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

1 Ответ

0 голосов
/ 27 декабря 2018

Есть несколько способов заставить это работать.Например, предположим, что все шифротексты 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 должны быть различны).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...