如今,标准(非同态)加密的安全性已经被很好的理解。通常有两种形式:加密方案只能抵御被动攻击者(可以查看加密数据但不能操纵它),或者也可以抵御主动攻击者可以操纵加密的数据,然后观察如何解密。
较弱(被动)概念的加密术语是“CPA-security”,而较强的概念称为“CCA-security”。(这些首字母缩写分别代表“选择明文攻击”和“选择密文攻击”。)
众所周知,要保护静态或传输中的数据,必须使用CCA安全加密。如果将加密功能作为较大系统中的一个组件,而该系统中的其他组件则提供了针对活动攻击者的保护,则CPA安全性就足够了。
对于同态加密(HE)方案,众所周知,它们本质上不能CCA安全。其非CCA安全性的后果之一是,系统必须确保永远不要将解密应用于无效的密。
实际上,对于目前的全同态加密方案,允许攻击者提交要解密的无效密文通常会导致密钥泄露。因此,全同态加密方案通常会采用CPA安全性,并依靠周围的系统来提供可能需要的额外保护。
Li和Micciancio最近观察到,对于近似全同态加密方案,CPA安全性的通用概念可能甚至不足以应对被动攻击者。
关键区别在于,由于该方案本身会增加一些错误,如果攻击者知道解密结果应该是什么,攻击者也可以从解密结果中学到一些东西。具体来说,它能够学习错误,这可能会泄漏有关密钥的信息。
Li和Micciancio描述了对CKKS近似全同态加密方案的简单攻击,该攻击在看到少量解密结果(有时只有一次解密)后可以破解密钥。
如何减轻Li-Micciancio袭击
针对此观察,HElib现在包括减轻这种风险的对策。特别是,对CKKS的HElib解密函数进行了修改,以添加一些与密钥无关的噪声,从而掩盖了与密钥有关的噪声,并使Li-Micciancio攻击更难以奏效。
但是,这种额外的噪声降低了解密结果的准确性。默认情况下,选择与密钥无关的噪声的大小在HElib为解密密文而保留的噪声范围之内,但是该范围可能过于保守,因此添加的噪声有时可能会导致准确性显着降低。因此,HElib为应用程序提供了指定解密所需精度的方法,然后将在此精度约束下添加最大数量的噪声。
使用CKKS的应用程序需要找到一条能平衡安全性,准确性和性能的方法。下面,我们在考虑这些方面的同时,描述了一个用于开发基于CCKS的应用程序的框架。粗略地,我们建议应用程序尝试对错误进行严格估算,然后使用该估算值代替HElib计算的噪声范围。
1.首先确定应用程序需要应用于数据的(类别)流程;
2.从处理结果中确定所需的精度;
3.在测试数据上的HElib中运行这些过程,以确定要使用的参数,大致如下:
i.找到一些参数设置,其中context.securityLevel()返回足够高的安全性,并且库不报告解密错误;
ii.当使用步骤2中的精度参数调用时,通过实验找到解密结果的噪声大小的一个相当紧密的边界。这可以通过多次运行HElib处理来实现,并将解密的结果与对明文数据进行相同处理时得到的结果进行比较;
iii.比较从上面3.2步得到的噪声边界和HElib在解密之前计算的估计误差,后者可以通过ctxt.errorBound()访问。如果实验噪声明显小于ctx.errorbound()返回的噪声,那么在解密之前使用ctx.bumpnoisebound()来强制HElib使用更严格的误差估计。
iv.重复步骤3.1-3.3,增加参数,直到解密不再发出有关所添加噪声太小的警告。
现在,我们将详细介绍每个步骤。
步骤1-2过程和所需的精度
与全同态加密的任何应用程序一样,起点是确保足够的功能。因此,开发人员必须确定要计算的运算和所需的输出精度。一些应用程序只需要计算一个功能,而其他应用程序则需要处理更广泛的功能,但是至少开发人员应该确定所支持电路的最大深度和所需的最大精度。
在HElib中,应用程序可以指定用于加密明文数据的输入精度,并且电路中的每个级别都将精度降低一位(或最多1.5位),即,每个级别的误差大约翻倍。例如,使用辅助类PtxtArray可以调用ptxt.encrypt(ctxt,ptxtMagnitude,precision),这将导致给定输入明文的加密,并且错误以2精度为边界。在计算了一个三层深度的电路(例如)之后,误差将增加到超过23个精度。在计算深度d电路之后,需要p位输出精度的应用程序应以p+d到p+3d/2之间的输入精度进行加密。
步骤3查找匹配参数
在确定了所需的深度d和输出精度p之后,应用程序开发人员需要找到一些在确保安全性的前提下产生该输出精度的参数。这通常涉及迭代的反复试验过程,如下所示:
1.从对参数的一些粗略估计开始:深度d电路所需的模数的总位长通常约为,使用该模数获得128位安全性所需的环尺寸约为(取整为2的幂,因为目前的CKKS支持在HElib只测试了2的幂次环)
用m表示大于的2的下一个幂,然后可以使用ContextBuilder类在HElib中设置这些初始参数,设置
Context context=ContextBuilder<CKKS>().m(m).bits(16*(d+1)).precision(p+d).c(3).build();
注意,上面指定的位数仅为而不是,并且存在一个神秘的附加参数c=3,它满足。是对深度d电路所需的估计,而HElib中的总模数位数按大致获得。(请参阅HElib文档中有关密文与特殊素数的讨论,第5.1节。)
通过将c参数从其默认值c=3增加,可以使相同功能的总位大小略小,但是密钥大小和运行时间会增加与c几乎成线性关系。
设置完这些参数后,运行HElib处理并检查库是否出现可能的解密错误,并使用这些实验增加或减少位和m参数。您还应该使用接口context.securityLevel()来检查参数m,bits,precision和c的组合是否产生可接受的安全级别。
2.检查这些参数确实产生所需的输出精度。即运行HElib处理的几个实验,使用可选的控制精度的参数(例如,使用ptxtArray类的接口ptxt.rawDecrypt(ctxt,secretKey))解密结果,并将结果与明文处理结果进行比较。(这时,您应忽略HEib的任何有关增加的噪声过小的警告。)重新检查上述步骤1中的参数,直到安全性和输出精度均可接受为止。
3.接下来,检查在解密之前HElib通过ctxt.errorBound()报告的错误界限,与上一步中观察到的实际错误(大概不超过)有关。如果HElib估算值明显大于实际噪声,则在解密之前使用ctxt.bumpNoiseBound()强制HElib使用“正确估算值”。
4.此时,您需要切换到使用ptxt.decrypt(ctxt,secretKey,p)并检查HElib在解密时不再发出警告消息,说明添加的噪声太小。如果仍然看到该警告,则需要重新访问参数设置,增加bits参数(以及保持安全性和精度所需的其他参数),直到不再显示此警告为止。
最后指出,此过程仅适用于威胁模型包括仅获得少数解密结果的对手的情况。如果对手可获得的有关解密查询的信息总量大得多,则应用程序需要从上方增加bits参数。特别是,为了抵御可以访问D密文解密结果的攻击,应该将bits参数粗略地增加D倍,并且将输入精度参数类似地增加到D(p+d)。
在HElib中,如果密文是使用库的加密和计算例程生成的,则密文是有效的,并且不会包含太多噪声。特别是,使用解密不应发出有关“太多噪声解密”的警告。
ptxtMagnitude和precision参数是可选的,默认值取决于上下文和要加密的实际明文。重要的是,精度(如果指定)表示的是绝对数字,而不是明文大小的一小部分。例如,调用precision=3将产生1/8大小的错误,无论调用ptxtMagnitude=16,还是ptxtMagnitude=1。最后请注意,精度参数也可以是负值,表示误差幅度大于1。
