【摘要】 SEAL全同态加密库可映射到Python 该接口已在GitHub开源
宁波格密链网络科技有限公司一直致力于全同态加密的应用研究。最近陈智罡博士的团队开发了一个将SEAL全同态加密库映射到Python上的接口,解决了机器学习库与全同态加密库对接的问题,极大的方便了机器学习领域人员使用全同态加密算法,为其它领域需要用到全同态加密库的人们提供便利的工具。该库已经在GitHub上开源(github.com/Huelse/pyseal)。全世界各地的工程技术人员都可以使用该库。
微软的SEAL全同态加密库包含BFV和CKKS两种全同态加密方案,陈智罡博士团队要做的就是将这个库的所有可用接口都映射到Python上来,并使之在Python上正确运行。显然这是一个全新的项目。
经过分析讨论,技术路线确定为使用微软最新的SEAL库(3.3版本)做为基础,与Pybind11官方头文件库作为中间件绑定,使用Setuptools或CMake编译生成动态链接库。这样就可供Python上调用SEAL库接口。技术框架如下:
这不是一个简单问题。初期,他们遇到了复杂的环境和标准问题,经过反复确认,团队选择使用是C++17标准和Python3.6.8的稳定版作为开发环境。然而接下来团队碰到了三个棘手问题。
第一个问题,在最新版的SEAL库中,其使用的是一个名为MemoryPoolHandle的类和MemoryManager基类作为计算过程中的指针与内存池管理。因为Python的内存管理是自动化的,所以这个在Python里是无法直接实现。于是团队在wrapper绑定文件中,将其作为一个参数类导入,最终达成了相同的功能。
第二个问题,SEAL库的Cipertext明文类中有一个关键参数scale,在测试环节中是要做到可自定义修改的,但问题在于这是一个私有变量。在C++中,定义好共有方法后,可通过应用的方式对其赋值,但在Python中因为其语言特性,同样不可能实现对私有变量的直接修改。所以经过研究,团队的解决方法是在Cipertext类中增加一个共有方法set_scale(),该函数方法是整个项目唯一对SEAL库做出修改的地方,也仅应用于测试环节的使用,对全同态加密整体是无影响的。
第三个问题,出自于Python的内存管理,这是一个技术难点与重点。提前说明一下,Python中假如我们在代码文件里定义一个变量a=0,我们再写一个带参数的函数foo(a),然后函数里会对a变量进行一系列运算使之改变。当我们将a带入到这个函数并使之运行后我们发现,在该函数里,a这个变量的确被运算过了,但是在这个函数体之外的那个a,它的值并不会变。通过id()方法观察内存,最终确认是这样的。
而在C++里通过指针的方式实现对传入参数的修改,SEAL库多处的encode和decode函数都是这样使用的。要在尽可能不改变SEAL库源码的情况下将其转移到Python上来,且Python不能操控指针,仅这个问题困扰了团队很久。最终团队给出的方案是自定义一个变量类。
虽然在Python中单一的变量作为参数不会发生改变,但如果是一个类作为参数传入,那它的改变是全局性的。比如uIntVector类在c++中的原型是std::vector,DoubleVector类其原型是std::vector。团队对类的包装完成了这两者最基本的数据交互,这样CKKS方案就能完美运行。至此陈智罡博士团队的Pyseal项目的主要工作也已完成。
最后,陈智罡博士的团队使用Pyseal将SEAL官方给出的6个样例在Python上全部实现,且运行效率也并未减少。接口已经在Github上开源。
宁波格密链网络科技有限公司一直致力于全同态加密的研究与开发,希望能给全世界更多的技术工程人员带来便利,更加方便地使用全同态加密库。(致远博士)