对大型加密数据应用同态运算

问题描述

当前正在使用PALISADE library进行同态加密。

我想对大型加密输入应用简单的运算,例如加法和乘法。例如,输入 C:\Users\kaushikb\Anaconda3\lib\site-packages\setuptools\distutils_patch.py:25: UserWarning: Distutils was imported before Setuptools. This usage is discouraged and may exhibit undesirable behaviors or errors. Please use Setuptools' objects directly or at least import Setuptools first. warnings.warn( Traceback (most recent call last): File "C:\Users\kaushikb\Anaconda3\Scripts\jupyter-notebook-script.py",line 6,in from notebook.notebookapp import main File "C:\Users\kaushikb\Anaconda3\lib\site-packages\notebook\notebookapp.py",line 49,in from zmq.eventloop import ioloop File "C:\Users\kaushikb\Anaconda3\lib\site-packages\zmq\__init__.py",line 47,in from zmq import backend File "C:\Users\kaushikb\Anaconda3\lib\site-packages\zmq\backend\__init__.py",line 40,in reraise(*exc_info) File "C:\Users\kaushikb\Anaconda3\lib\site-packages\zmq\utils\sixcerpt.py",line 34,in reraise raise value File "C:\Users\kaushikb\Anaconda3\lib\site-packages\zmq\backend\__init__.py",line 27,in _ns = select_backend(first) File "C:\Users\kaushikb\Anaconda3\lib\site-packages\zmq\backend\select.py",line 28,in select_backend mod = __import__(name,fromlist=public_api) File "C:\Users\kaushikb\Anaconda3\lib\site-packages\zmq\backend\cython\__init__.py",in from . import (constants,error,message,context,ImportError: DLL load failed while importing error: The specified module could not be found. 和输入A[3200]的int值向量/数组都被加密。使用这两个输入B[4096]Enc(A),我想应用一个乘法:

Enc(B)

就我而言,上述要求的实施可以通过两种不同的方式解决:

  1. 将输入打包为单个密文(类似于SIMD),对于he操作,我可以使用EvalMult(Enc(A[0]),Enc(B[42])) *0 and 42 denoting the indexes of the corresponding inputs ** no SIMD needed 从加密输入中获取正确的值。

  2. 分别加密A和B中的每个值。

我不太确定所描述的解决方案中哪一种在效率方面是最好的。第一种方法的主要优点是,整个输入只需要一个加密过程,但这带来的缺点是,我总是必须使用EvalIndexAt()方法访问正确的元素,并且输入越大,输入速度越慢。 EvalAtIndex()的计算得到。 (至少在我的机器上)

第二种方法似乎更合适,因为不需要EvalAtIndexKeyGen(),但要花很多时间才能单独加密每个值。

有什么想法建议吗?

解决方法

谢谢你的提问。

方法#1(SIMD)的主要好处是,您可以使用单个同态加法或乘法(非常有效)对向量(4096个或更多的整数/实数)进行加法和乘法。旋转(在PALISADE中称为EvalAtIndex)是一项额外的操作,允许一个访问单个索引或进行有效的求和(如内部乘积),矩阵乘法等。此方法的密文扩展因子也小得多(通过4096x或更高)。通常,在实践中通常首选选项1(并且我无法想到要使用选项2的任何实际用例)。

为了最小化乘法的开销,也许您可​​以将矢量打包在连续的块中,以便您需要对一个块进行一次旋转。例如,

EvalMult(Enc(A[0:5]),Enc(B[42:47))

您可以使用的另一种技术是EvalFastRotation(仅适用于PALISADE v1.10.x中的CKKS和BGVrns)。如果您需要多次旋转相同的密文,则可以为密文预先计算一些内容,然后使用便宜的旋转方式(BV密钥切换最大的好处)-有关示例,请参见https://gitlab.com/palisade/palisade-development/-/blob/master/src/pke/examples/advanced-real-numbers.cpp

如果需要多次旋转(也仅计算所需旋转数的平方根),也有一些方法可以最大程度地减少要生成的键的数量,例如,使用下面介绍的婴儿步长步长技术https://eprint.iacr.org/2018/244(这些技术可以在基于PALISADE的应用程序中实现)。

如果已知用于执行乘法的模式,则也可以使用打包向量的特殊顺序(这样,您的旋转将使用一次旋转操作在向量上准备好几个块)。当#个纯文本插槽(批处理大小)等于ring dimension / 2时,CKKS和BGVrns中的循环都是周期性的(环绕)。如果矢量小于此值,则始终可以克隆/复制小矢量填充ring dimension / 2所需的次数。

总而言之,如果您从类似于SIMD的向量的角度考虑问题,则可以最大程度地提高效率。然后,您可以重新构造您的问题/模型,以充分利用HE提供的工具集。在某种程度上,这类似于使用矢量化指令(例如AVX)或面向矩阵的编程(例如在MATLAB中)进行编程。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...