2024-01-20 14:14:46 +08:00
|
|
|
|
## 概述
|
2024-01-20 14:44:25 +08:00
|
|
|
|
NKDBSec是一个基于[Rosetta](https://github.com/LatticeX-Foundation/Rosetta)改造而成的安全多方计算框架。NKDBSec主要由[南开大学数据与智能系统安全教育部重点实验室](https://cyber.nankai.edu.cn/)和[北京安华金和有限公司](https://www.dbsec.cn/)进行开发和维护。原版本Rosetta框架是一个基于tensorflow开发的安全多方计算框架,主要用于隐私保护机器学习。但是由于其底层使用的tensor结构,大量的张量计算不太适用于大数据下的数据联合分析和其他隐私计算算法的开发。
|
2024-01-20 14:14:46 +08:00
|
|
|
|
|
2024-01-20 14:44:25 +08:00
|
|
|
|
基于这个现状,NKDBSec将原版Rosetta框架进行了底层改造,使之可以更加适用于数据联合分析与数据库操作等场景。改造后的框架基础算子性能得到了非常大的提升。NKDBSec将其基本算子进行了一个对比测试,测试结果详见下表:
|
2024-01-20 14:14:46 +08:00
|
|
|
|
|
|
|
|
|
测试硬件配置:Intel(R) Xeon(R) CPU E5-2660 v3 @ 2.60GHz 20核 40线 1000M带宽
|
|
|
|
|
|
|
|
|
|
测试数量级:10^7
|
|
|
|
|
|
2024-01-20 14:44:25 +08:00
|
|
|
|
| **测试算法** | **Rosetta** | **NKDBSec** |
|
2024-01-20 14:14:46 +08:00
|
|
|
|
| :-------: | :-------: | :-------: |
|
|
|
|
|
| 加法操作 | 4min59s | 3.8s |
|
|
|
|
|
| 减法操作 | 5min0s | 3.9s |
|
|
|
|
|
| 乘法操作 | 5min1s | 9.2s |
|
|
|
|
|
| 除法操作 | 5min2s | 9.1s |
|
|
|
|
|
| 比较运算 | 6min57s | 2min2s |
|
|
|
|
|
| 与 | 5min4s | 11.2s |
|
|
|
|
|
| 或 | 5min6s | 10.7s |
|
|
|
|
|
| 异或 | 5min2s | 12.2s |
|
|
|
|
|
|
|
|
|
|
## 安装与部署
|
|
|
|
|
|
|
|
|
|
操作系统:Ubuntu18.04+
|
|
|
|
|
python版本:python3.6+
|
|
|
|
|
依赖包:numpy
|
|
|
|
|
确认满足以上环境需求和安装包之后,然后进入项目的根目录,执行如下指令即可完成部署:
|
|
|
|
|
```bash
|
|
|
|
|
python3 setup.py install
|
|
|
|
|
```
|
2024-01-20 14:44:25 +08:00
|
|
|
|
用户在使用框架进行开发的时候,只需要在文件中添加以下两行代码即可使用NKDBSec框架:
|
2024-01-20 14:14:46 +08:00
|
|
|
|
```python
|
|
|
|
|
import numpy as np
|
|
|
|
|
import dbsecmpc
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 使用样例
|
|
|
|
|
|
2024-01-20 14:44:25 +08:00
|
|
|
|
对于NKDBSec框架,我们支持两种使用方式,一种是单机多线程模拟,另一种是多机交互。我们分别给出两个使用样例:
|
2024-01-20 14:14:46 +08:00
|
|
|
|
#### 1、单机多线程模拟
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
import numpy as np
|
|
|
|
|
import dbsecmpc
|
|
|
|
|
import time
|
|
|
|
|
import json
|
|
|
|
|
curt = time.time()
|
|
|
|
|
from multiprocessing import Process
|
|
|
|
|
|
|
|
|
|
# conf部分做好多线程模拟的端口配置,这部分的端口设置可以由用户自己定义,需要注意的是配置时最好避开常用的端口,否则会造成线程冲突和程序卡死。
|
|
|
|
|
conf = {
|
|
|
|
|
"NODE_INFO": [
|
|
|
|
|
{
|
|
|
|
|
"HOST": "127.0.0.1",
|
|
|
|
|
"PORT": 25500,
|
|
|
|
|
"NODE_ID": "P0"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"HOST": "127.0.0.1",
|
|
|
|
|
"PORT": 25700,
|
|
|
|
|
"NODE_ID": "P1"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"HOST": "127.0.0.1",
|
|
|
|
|
"PORT": 25900,
|
|
|
|
|
"NODE_ID": "P2"
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"DATA_NODES": [
|
|
|
|
|
"P0",
|
|
|
|
|
"P1",
|
|
|
|
|
"P2"
|
|
|
|
|
],
|
|
|
|
|
"COMPUTATION_NODES": {
|
|
|
|
|
"P0": 0,
|
|
|
|
|
"P1": 1,
|
|
|
|
|
"P2": 2
|
|
|
|
|
},
|
|
|
|
|
"RESULT_NODES": [
|
|
|
|
|
"P0",
|
|
|
|
|
"P1",
|
|
|
|
|
"P2"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def test(id):
|
|
|
|
|
# conf部分用于初始化通信端口操作,无需修改
|
|
|
|
|
confbuf = json.dumps(conf)
|
|
|
|
|
dbsecmpc.init(id, confbuf)
|
|
|
|
|
|
|
|
|
|
np.random.seed(199)
|
|
|
|
|
colnum, rownum = 2, 10
|
|
|
|
|
|
|
|
|
|
# P0方进行输入
|
|
|
|
|
xplaintable = np.random.rand(colnum * rownum)*(100)
|
|
|
|
|
xplaintable.shape = (colnum, rownum)
|
|
|
|
|
print("P0 input: ", xplaintable)
|
|
|
|
|
rtx = dbsecmpc.privateinput(["P0"], xplaintable)
|
|
|
|
|
|
|
|
|
|
# P1方进行输入
|
|
|
|
|
np.random.seed(307)
|
|
|
|
|
yplaintable = np.random.rand(colnum * rownum)*(100)
|
|
|
|
|
yplaintable.shape = (colnum, rownum)
|
|
|
|
|
print("P1 input: ", yplaintable)
|
|
|
|
|
rty = dbsecmpc.privateinput(["P1"], yplaintable)
|
|
|
|
|
|
|
|
|
|
# 调用OP_ADD和OP_MUL运算符,执行隐私计算操作
|
|
|
|
|
res = dbsecmpc.opvector(dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_ADD), rty, dbsecmpc.OP_MUL)
|
|
|
|
|
print("P{} secret share: ".format(id), res)
|
|
|
|
|
|
|
|
|
|
# 调用reveal函数,将秘密共享计算结果由P2方进行恢复后打印验证
|
|
|
|
|
res = dbsecmpc.reveal(["P2"], res)
|
|
|
|
|
print("P{} output: ".format(id), res)
|
|
|
|
|
|
|
|
|
|
pc1 = Process(target = test, args=(0,))
|
|
|
|
|
pc2 = Process(target = test, args=(1,))
|
|
|
|
|
pc3 = Process(target = test, args=(2,))
|
|
|
|
|
|
|
|
|
|
st = time.time()
|
|
|
|
|
pc1.start()
|
|
|
|
|
pc2.start()
|
|
|
|
|
pc3.start()
|
|
|
|
|
|
|
|
|
|
pc1.join()
|
|
|
|
|
pc2.join()
|
|
|
|
|
pc3.join()
|
|
|
|
|
print(time.time() - st)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 2、多机交互操作
|
|
|
|
|
```python
|
|
|
|
|
import time
|
|
|
|
|
curt = time.time()
|
|
|
|
|
import json
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
import dbsecmpc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# conf写法参考Rosetta的CONFIG.json文件
|
|
|
|
|
conf = {
|
|
|
|
|
"NODE_INFO": [
|
|
|
|
|
{
|
|
|
|
|
"HOST": "10.10.160.2",
|
|
|
|
|
"PORT": 44122,
|
|
|
|
|
"NODE_ID": "P0"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"HOST": "10.10.160.3",
|
|
|
|
|
"PORT": 42143,
|
|
|
|
|
"NODE_ID": "P1"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"HOST": "10.10.160.4",
|
|
|
|
|
"PORT": 53169,
|
|
|
|
|
"NODE_ID": "P2"
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
"DATA_NODES": [
|
|
|
|
|
"P0",
|
|
|
|
|
"P1",
|
|
|
|
|
"P2"
|
|
|
|
|
],
|
|
|
|
|
"COMPUTATION_NODES": {
|
|
|
|
|
"P0": 0,
|
|
|
|
|
"P1": 1,
|
|
|
|
|
"P2": 2
|
|
|
|
|
},
|
|
|
|
|
"RESULT_NODES": [
|
|
|
|
|
"P0",
|
|
|
|
|
"P1",
|
|
|
|
|
"P2"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def main(parid):
|
|
|
|
|
np.random.seed(199)
|
|
|
|
|
colnum, rownum = 2, 100000
|
|
|
|
|
lefttable = np.random.rand(colnum * rownum)*(2**10)
|
|
|
|
|
lefttable.shape = (colnum, rownum)
|
|
|
|
|
confbuf = json.dumps(conf)
|
|
|
|
|
dbsecmpc.init(parid, confbuf)
|
|
|
|
|
s_lefttable = dbsecmpc.privateinput(["P0"], lefttable)
|
|
|
|
|
res = dbsecmpc.opvector(s_lefttable[0], s_lefttable[1], dbsecmpc.OP_ADD)
|
|
|
|
|
res = dbsecmpc.reveal(["P0"], res)
|
|
|
|
|
print(res)
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2024-01-20 14:44:25 +08:00
|
|
|
|
# 此处需要注意,NKDBSec是三个参与方进行交互模拟,所以需要建立三个py文件,比如分别命名为test1.py, test2.py, test3.py
|
2024-01-20 14:14:46 +08:00
|
|
|
|
# 对于test1.py文件此处为"main(0)", 其余两个文件main的参数分别为1和2,然后使用三个进程进行模拟即可运行此实例。
|
|
|
|
|
main(0)
|
|
|
|
|
```
|
|
|
|
|
第一个bash模拟第一个计算参与方:
|
|
|
|
|
```bash
|
|
|
|
|
python3 test1.py
|
|
|
|
|
```
|
|
|
|
|
第二个bash模拟第一个计算参与方:
|
|
|
|
|
```bash
|
|
|
|
|
python3 test2.py
|
|
|
|
|
```
|
|
|
|
|
第三个bash模拟第一个计算参与方:
|
|
|
|
|
```bash
|
|
|
|
|
python3 test3.py
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 接口说明
|
2024-01-20 14:44:25 +08:00
|
|
|
|
目前NKDBSec提供如下基本运算接口,用户可以在此之上调用接口,实现相应的MPC任务。
|
2024-01-20 14:14:46 +08:00
|
|
|
|
| **操作类型** | **运算符** | **调用方式** |
|
2024-01-20 14:47:02 +08:00
|
|
|
|
| ------ | ------ | ------ |
|
2024-01-20 14:14:46 +08:00
|
|
|
|
| 加法操作 | OP_ADD | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_ADD) |
|
|
|
|
|
| 减法操作 | OP_SUB | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_SUB) |
|
|
|
|
|
| 乘法操作 | OP_MUL | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_MUL) |
|
|
|
|
|
| 除法操作 | OP_DIV | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_DIV) |
|
|
|
|
|
| 模运算 | OP_MOD | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_MOD) |
|
|
|
|
|
| 小于运算 | OP_LESS | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_LESS) |
|
|
|
|
|
| 大于运算 | OP_GREATER | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_GREATER) |
|
|
|
|
|
| 小于等于运算 | OP_LESSEQUAL | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_LESSEQUAL) |
|
|
|
|
|
| 大于等于运算 | OP_GREATEREQUAL | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_GREATEREQUAL) |
|
|
|
|
|
| 等于运算 | OP_EQUAL | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_EQUAL) |
|
|
|
|
|
| 不等运算 | OP_NOTEQUAL | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_NOTEQUAL) |
|
|
|
|
|
| 与 | OP_AND | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_AND) |
|
|
|
|
|
| 或 | OP_OR | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_OR) |
|
|
|
|
|
| 非 | OP_NOT | dbsecmpc.opvector(rtx, dbsecmpc.OP_NOT) |
|
|
|
|
|
| 异或 | OP_XOR | dbsecmpc.opvector(rtx, rty, dbsecmpc.OP_XOR) |
|
|
|
|
|
|
|
|
|
|
## 引用方式
|
|
|
|
|
如果需要引用我们的项目,可以参考如下引用格式。
|
|
|
|
|
```
|
2024-01-20 14:44:25 +08:00
|
|
|
|
@misc{NKDBSec,
|
|
|
|
|
author = {Junjian Shi, Zheli Liu, Xiaotao Liu, Yun Pan, Hao Yang, Jihong Guo},
|
|
|
|
|
title = {{NKDBSec: An MPC Framework Based on Rosetta}},
|
2024-01-20 14:14:46 +08:00
|
|
|
|
howpublished = {\url{https://osredm.com/nankaicyber/NKDBsec}},
|
|
|
|
|
year={2024}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 许可证
|
2024-01-20 14:44:25 +08:00
|
|
|
|
NKDBSec代码库基于[GNU Lesser General Public License v3.0]()许可证开放使用。
|