关于python:隐语-PSI-benchmark-白皮书

4次阅读

共计 5872 个字符,预计需要花费 15 分钟才能阅读完成。

导语: 为了不便大家理解隐语的 Benchmark,本文设计了 10 分钟上手手册,蕴含了亮点介绍、SecretFlow 集群的易用搭建、Benchmark 脚本、两方和三方的 Benchmark,使相干业务方做调研时不便拿到可度量的性能数据和可复现的门路。

隐语 PSI 亮点

隐衷汇合求交(Private Set Intersection,PSI)是一类特定的多方平安计算(Multi-Party Computation, MPC)问题,其问题能够简略了解为:Alice 输出汇合 X,Bob 输出汇合 Y,单方执行 PSI 协定能够失去 Alice 和 Bob 两者的交加,同时不在交加范畴内的局部是受爱护的,即 Alice 和 Bob 无奈学习出交加以外的任何信息。

隐衷汇合求交 (PSI) 协定有很多分类办法,依照底层依赖的明码技术分类次要包含:

  • 基于公钥明码的 PSI 计划,包含:基于断定型密钥替换(Decisional Diffie-Hellman,DDH)的 PSI 计划和 RSA 盲签名的 PSI 计划;
  • 基于不经意传输(Oblivious Transfer,OT)的 PSI 计划;
  • 基于通用 MPC 的 PSI 计划,例如基于混同电路(Garbled Circuit,GC)的 PSI 计划;
  • 基于同态加密(Homomorphic Encryption,HE)的 PSI 计划。

隐衷汇合求交 (PSI) 协定依照参与方的数量进行分类,可分为:

  • 两方 PSI:参与方为 2 个;
  • 多方 PSI:参与方 >2 个。

隐衷汇合求交 (PSI) 协定依照设定平安模型分类,可分为:

  • 半诚恳模型的 PSI;
  • 歹意模型的 PSI。

SecretFlow SPU 实现了半诚恳模型下的两方和三方 PSI 协定,密钥平安强度是 128bit,统计平安参数是 40bit。

两方 PSI 协定:

  • 基于 DDH 的 PSI(Private Set Intersection)协定

基于 DDH 的 PSI 协定先对简略易于了解和实现,依赖的明码技术已被宽泛论证,通信量低,但计算量较大。

隐语实现了基于椭圆曲线 (Elliptic Curve) 群的 DDH PSI 协定,反对的椭圆曲线类型包含:Curve25519,SM2,Secp256k1。本次 benchmark 选用的曲线是 Curve25519。

  • 基于 OT 扩大的 KKRT16

KKRT16 是第一个千万规模 (224) 求交工夫在 1 分钟之内的 PSI 计划,通信量较大;

隐语实现了 KKRT16 协定,并参考了进年来的性能优化和平安改良计划,例如:stash-less CuckooHash,[GKWW20]中 FixedKey AES 作为 correlation-robust 哈希函数。

  • 基于 PCG 的 BC22

BC22 PSI 依赖的 PCG(Pseudorandom Correlation Generator)计划是近年来 mpc 方向的钻研热点,相比 KKRT16 计算量和通信两方面都有了很大改良,从老本 (monetary cost) 角度更能满足理论业务需要。PCG 实现依赖 LPN(Learning Parity with Noise)问题,因为是 2022 年最新的协定,协定的安全性还须要更多明码专家的剖析和论文。

隐语 v0.7 中实现了 BC22 PSI 计划,其中的 PCG/VOLE 应用了 emp-zk 中的 [WYKW21] 实现,欢送大家审查和进一步改良;

三方 PSI(Private Set Intersection)协定

  • 基于 DDH 的三方 PSI 协定

隐语实现了自研的基于 ECDH 的三方 PSI 协定,留神咱们实现的这个协定会透露两方交加大小,请自行判断是否满足应用场景的安全性,本次 benchmark 选用的曲线是 Curve25519。

复现形式

一、测试机型环境

  • Python:3.8
  • pip: >= 19.3
  • OS: CentOS 7
  • CPU/Memory: 举荐最低配置是 8C16G
  • 硬盘:500G

二、装置 conda

应用 conda 治理 python 环境,如果机器没有 conda 须要先装置,步骤如下:

# 别离在三台机器的 root 目录下执行
# sudo apt-get install wget
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh

# 装置
bash Miniconda3-latest-Linux-x86_64.sh

# 始终按回车而后输出 yes
please answer 'yes' or 'no':
>>> yes

# 抉择装置门路, 文件名前加点号示意暗藏文件
Miniconda3 will now be installed into this location:
>>> ~/.miniconda3

# 增加配置信息到 ~/.bashrc 文件
Do you wish the installer to initialize Miniconda3 by running conda init? [yes|no]
[no] >>> yes

# 运行配置信息文件或重启电脑
source ~/.bashrc

# 测试是否装置胜利
conda --version

三、装置 secretflow

# 别离在三台机器的 root 目录下执行
# 创立洁净的 python 环境
conda create -n sf-benchmark python=3.8

# 进入 benchmark 环境
conda activate sf-benchmark

# 装置 secretflow
pip install -U secretflow

# 创立一个 sf-benchmark 目录
mkdir sf-benchmark
cd sf-benchmark

1. 验证装置是否胜利

root 目录下输出 python 而后回车

# 顺次执行,每执行一条回车一次

>>> import secretflow as sf
>>> sf.init(['alice', 'bob', 'carol'], num_cpus=8, log_to_driver=True)
>>> dev = sf.PYU('alice')
>>> import numpy as np
>>> data = dev(np.random.rand)(3, 4)
>>> sf.reveal(data)

如下图所示就代表环境搭建胜利了

四、创立节点并启动集群

1. 创立 ray header 节点

创立 ray header 节点,抉择一台机器为主机,在主机上执行如下命令,ip 替换为主机的内网 ip,命名为 alice,端口抉择一个闲暇端口即可留神:192.168.0.1 ip 为 mock 的,请替换为理论的 ip 地址

# alice 机器执行

RAY_DISABLE_REMOTE_CODE=true \
ray start --head --node-ip-address="192.168.0.1" --port="9394" --resources='{"alice": 8}' --include-dashboard=False

2. 创立隶属节点

创立隶属节点,在 bob 机器执行如下命令,ip 仍然填 alice 机器的内网 ip,命名为 bob,端口不变

# bob 机器执行

RAY_DISABLE_REMOTE_CODE=true \
ray start --address="192.168.0.1:9394" --resources='{"bob": 8}'

创立隶属节点,在 carol 机器执行如下命令,ip 仍然填 alice 机器的内网 ip,命名为 carol,端口不变

# carol 机器执行

RAY_DISABLE_REMOTE_CODE=true \
ray start --address="192.168.0.1:9394" --resources='{"carol": 8}'

3. 验证节点是否启动

在 python 中测试节点是否启动胜利,任意选一台机器输出 python,执行下列代码,参数中 address 为头节点 (alice) 的地址,拿 alice 机器来验证,每输出一行下列代码回车一次:

#alice 机器输出 python 后再执行

>>> import secretflow as sf
>>> sf.init(address='192.168.0.1:9394')
>>> alice = sf.PYU('alice')
>>> bob = sf.PYU('bob')
>>> sf.reveal(alice(lambda x : x)(2))
>>> sf.reveal(bob(lambda x : x)(2))

如下图就代表节点创立胜利了

同时咱们也能够通过 ray status 去看节点的状态,前提是先进入 sf 环境(conda activate sf-benchmark)

4. 生成数据

把脚本 generate_psi.py:https://github.com/secretflow…
传到 alice 机器的 root 目录下

执行如下代码

# 生成三份一千万数据
python3 generate_psi.py 10000000

# 生成三份一亿数据
python3 generate_psi.py 100000000

把生成的 psi_1.csv cp 到 benchmark 目录下,再通过 scp 的命令把 psi_2.csv/psi_3.csv 别离移到 bob 的 benchmark 目录下跟 carol 的 benchark 目录下

5. 限度宽带 / 提早

#100Mbps 20ms
tc qdisc add dev eth0 root handle 1: tbf rate 100mbit burst 256kb latency 800ms 
tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 20msec limit 8000

  • 革除限度

tc qdisc del dev eth0 root

  • 查看已有配置

tc qdisc show dev eth0

6.Benchmark 脚本

反对的 PSI 协定列表:

  • ECDH_PSI_2PC
  • KKRT_PSI_2PC
  • BC22_PSI_2PC
  • ECDH_PSI_3PC
import sys
import time
import logging

from absl import app
import spu
import secretflow as sf

# init log
logging.basicConfig(stream=sys.stdout, level=logging.INFO)

# SPU settings
cluster_def = {
'nodes': [
# <<< !!! >>> replace <192.168.0.1:12945> to alice node's local ip & free port
        {'party': 'alice', 'id': 'local:0', 'address': '192.168.0.1:12945', 'listen_address': '0.0.0.0:12945'},
# <<< !!! >>> replace <192.168.0.2:12946> to bob node's local ip & free port
        {'party': 'bob', 'id': 'local:1', 'address': '192.168.0.2:12946', 'listen_address': '0.0.0.0:12946'},
# <<< !!! >>> if you need 3pc test, please add node here, for example, add carol as rank 2
# {'party': 'carol', 'id': 'local:2', 'address': '127.0.0.1:12347'},
    ],
'runtime_config': {
'protocol': spu.spu_pb2.SEMI2K,
'field': spu.spu_pb2.FM128,
    },
}

def main(_):

# sf init
# <<< !!! >>> replace <192.168.0.1:9394> to your ray head
    sf.init(address='192.168.0.1:9394')
    alice = sf.PYU('alice')
    bob = sf.PYU('bob')
    carol = sf.PYU('carol')

# <<< !!! >>> replace path to real parties local file path.
    input_path = {
        alice: '/data/psi_1.csv',
        bob: '/data/psi_2.csv',
# if run with `ECDH_PSI_3PC`, add carol
# carol: '/data/psi_3.csv',
    }
    output_path = {
        alice: '/data/psi_output.csv',
        bob: '/data/psi_output.csv',
# if run with `ECDH_PSI_3PC`, add carol
# carol: '/data/psi_output.csv',
    }
    select_keys = {alice: ['id'],
        bob: ['id'],
# if run with `ECDH_PSI_3PC`, add carol
# carol: ['id'],
    }
    spu = sf.SPU(cluster_def)

# prepare data
    start = time.time()

    reports = spu.psi_csv(
        key=select_keys,
        input_path=input_path,
        output_path=output_path,
        receiver='alice',  # if `broadcast_result=False`, only receiver can get output file.
        protocol='KKRT_PSI_2PC',  # psi protocol
        precheck_input=False,  # will cost ext time if set True
        sort=False,  # will cost ext time if set True
        broadcast_result=False,  # will cost ext time if set True
    )
    print(f"psi reports: {reports}")
    logging.info(f"cost time: {time.time() - start}")

    sf.shutdown()

if __name__ == '__main__':
    app.run(main)

五、Benchmark 报告

目前 bechmark 数据中,bc22 psi 的性能还在进一步工程优化,单测 spu 中 bc22 协定内核的性能比照能够参考 pcg psi 的介绍。

对于隐语 SecretFlow

隐语官网:

www.secretflow.org.cn

隐语社区及代码拜访:

github.com/secretflow

gitee.com/secretflow

关注微信公众号:隐语的小剧场

正文完
 0