Я использую HElib CKKS для проведения экспериментов и задаюсь вопросом, можно ли контролировать ошибку, связанную с каждой базовой операцией, такой как умножение, кодирование и вращение.
У меня этот вопрос, потому что я обнаружил, что увеличение ошибок, связанных с HElib, происходит быстрее, чем реализация HEAAN.
Вот пример проверки привязки ошибки после каждой квадратной операции из HElib:
// с *= с;
c.capacity=328,497 c.errorBound=1,28242e-06
c.capacity=289,748 c.errorBound=2,69423e-06
c.capacity=252.063 c.errorBound=5.71405e-06
c.capacity=213,502 c.errorBound=1,1591e-05
c.capacity=176,579 c.errorBound=2,37053e-05
c.capacity=139,634 c.errorBound=4,79147e-05
расстояние=1.84256e-05
Мы видим, что ошибка Bound увеличивается примерно в 2 раза (т. е. мы теряем один бит точности).
Для применения матричного умножения (включая вращение, кодирование и умножение, здесь подробности не уточняются) реализация в HEAAN работает хорошо, но граница ошибки превышает 200
и глубины не хватает, когда переписываю приложение с помощью HElib.
В целом, одно и то же приложение (т. е. имеет такое же количество умножений и слотов) в HElib требует больше битов, чем в HEAAN, и, наконец, приводит к уровню безопасности менее 80 бит.
Вопрос
В CKKS от HElib, если нам нужно точно контролировать (и как) связанную ошибку при умножении (или вращении)?
Параметры
Вот пример параметров, которые я использовал:
param(/*m=*/16 * 1024, /*bits=*/235, /*precision=*/20, /*c=*/2);
Ошибка, связанная после одной операции возведения в квадрат (умножения):
ct_Ck[0].capacity=256,968 ct_Ck[0].isCorrect=1 ct_Ck[0].errorBound=8,6898e-08
ct_Ck[0].capacity=207,74 ct_Ck[0].isCorrect=1 ct_Ck[0].errorBound=8.6348e-06
Данные открытого текста выглядят так:
-0.23801321 0.30014116 -0.0636206 0.21583742
ОБНОВИТЬ
Я нашел функцию в HElib для уменьшения границы ошибки, но я не знаю причин того, как она работает.
// результат перед вызовом bumpNoiseBound()
ct_F.capacity=38,4047 ct_F.isCorrect=1 ct_F.errorBound=201,848
ct_F.bumpNoiseBound (0,5);
ct_F.capacity=38,4047 ct_F.isCorrect=1 ct_F.errorBound=100,884
ct_F.bumpNoiseBound (0,00001);
ct_F.capacity=38,4047 ct_F.isCorrect=1 ct_F.errorBound=0,00202069
Расшифрованный результат:
[1.04830407 -3.209778495 -2.074653964 -1.684939538 -1.000400425 -4.124713608 -0.3628963567 -3.134082967 -3.801171699 -1.00385792 -1.472975371 -1.121783172 -5.484577652 -1.89848471 -1.517289034 -0.228743587 -1.226775781 3.901777677 1.575880583 -2.008799017 -1.980024549 3.465674733 -1.105679235 -3.594262482 0.1332798533 -7.012550198 0.5623979679 -4.254105028 -0.9447986134 -0.3755929384 -0.906013134 0.5607877395 -2.309902189 -4.112943726 -4.208302789 -2.742109602 -3.230622867 0.6365211006 -1.909193898 -1.761926501 0.07531637181 0.5945984313 -2.727958762 -2.45710736 -2.225926303 0.2915942006 -0.5207882104 -1.719778064 -3.581110672 0.9300763124 1.395581211 0.7434900004 -3.202471826 1.109593845 -5.68517439 0.2502367768 0.6176019573 -1.632018488 -0.3558288489 -1.87408586 3.322116753 -3.055094277 -1.437400739 -3.61812068]
Результат в открытом виде:
[1.048074533 -3.209868922 -2.075044009 -1.683690789 -0.9997621728 -4.124967495 -0.3629476429 -3.1339527 -3.801350955 -1.003947321 -1.473256614 -1.121510668 -5.484447105 -1.89821005 -1.517648893 -0.2295971341 -1.227429856 3.90224666 1.576020144 -2.008567349 -1.98010648 3.464794098 -1.105909147 -3.595045121 0.1335162434 -7.012703056 0.5623665673 -4.2541547 -0.9454690736 -0.3750930498 -0.9075913974 0.5602374826 -2.30977449 -4.11252574 -4.208385862 -2.742450262 -3.230891732 0.6371578519 -1.909217106 -1.76218525 0.07590385029 0.5945647743 -2.727895366 -2.457126412 -2.225143547 0.2917448084 -0.5201044894 -1.719980727 -3.580159571 0.9294232572 1.396138592 0.7433848735 -3.202827843 1.108926304 -5.68442001 0.2495510754 0.6176213132 -1.630955343 -0.35625627 -1.874107776 3.321633929 -3.054599105 -1.438421851 -3.618478743]
Результат после использования BumpNoiseBound ()
почти равен результату открытого текста. Значит, эта функция помогает нам вернуть правильную точность?