隐私计算-6-隐语PIR介绍及开发实践

日向远 2024-04-03 13:10:16

1. 隐匿查询(PIR)概念

  • 定义:用户从服务端数据库检索信息而不泄露查询内容的技术。
  • 分类
    • 按服务器数量:单服务器方案、多服务器方案。
    • 按查询类型:Index PIR、Keyword PIR。

2. 隐语支持的PIR方式

  • SealPIR:适用于单服务器Index PIR。
  • Labeled PSI:适用于单服务器Keyword PIR。

3. SealPIR介绍

  • BFV方案
    • 参数:多项式次数N、明文模t、密文模q、扩展率。
    • 问题:查询请求的密文向量可能过大。
  • 同态密码学原理
    • 数据打包:多个数据打包到一个HE Plaintext。
    • 查询向量压缩:减少通信量,支持多维查询。
    • 多查询支持:使用cuckoo hash进行多个查询。

4. Labeled PSI介绍

  • 基本原理:点值表示转换为插值多项式系数表示。
  • 优化技术
    • 窗口化(Windowing):减少密文乘法。
    • 分区(Partitioning):减少乘法次数和计算量。
    • 极值邮资基础:减少通信量。
  • 工作流程
    • 服务端预处理:选择参数、计算PRF、插入Simple Hash等。
    • 客户端查询:请求参数、执行OPRF协议、计算同态密文幂集合等。

5. 实现位置和外部库依赖

  • 文件位置:列出了隐语PIR实现的具体位置,包括头文件和源文件。
  • 外部库:包括SEAL、Microsoft APSI、GSL等。

代码实践

实现隐私查询,alice作为服务器,bob作为客户端。
我的环境是win11,python3.10,wsl2,ubuntu20.04,miniconda创建的环境,pip方式安装的secretflow。
使用docker-compose up方式启动secretnote,选择了1.5.0.dev版本,docker-compose.yml如下

services:
  alice:
    image: 'secretflow/secretnote:1.5.0.dev'
    platform: linux/amd64
    environment:
      - SELF_PARTY=alice
      - ALL_PARTIES=alice,bob
    ports:
      # SecretNote
      - 8090:8888
    entrypoint: /root/scripts/start.sh
    volumes:
      - /root/scripts

  bob:
    image: 'secretflow/secretnote:1.5.0.dev'
    platform: linux/amd64
    environment:
      - SELF_PARTY=bob
      - ALL_PARTIES=alice,bob
    ports:
      # SecretNote
      - 8092:8888
    entrypoint: /root/scripts/start.sh
    volumes:
      - /root/scripts

执行步骤

由127.0.0.1:8090进入alice端的secretnote(哪端都行),随后以如下形式组织ipynb

import secretflow as sf
import spu
import os

network_conf = {
    "parties": {
        "alice": {
            "address": "alice:8090",
        },
        "bob": {
            "address": "bob:8092",
        },
    },
}

party = os.getenv("SELF_PARTY", "alice")
sf.shutdown()
sf.init(
    address="127.0.0.1:6379",
    cluster_config={**network_conf, "self_party": party},
    log_to_driver=True,
)
alice, bob = sf.PYU("alice"), sf.PYU("bob")
spu_conf = {
    "nodes": [
        {
            "party": "alice",
            "address": "alice:8091",
            "listen_addr": "alice:8091",
        },
        {
            "party": "bob",
            "address": "bob:8091",
            "listen_addr": "bob:8091",
        },
    ],
    "runtime_config": {
        "protocol": spu.spu_pb2.SEMI2K,
        "field": spu.spu_pb2.FM128,
        "sigmoid_mode": spu.spu_pb2.RuntimeConfig.SIGMOID_REAL,
    },
}
spu = sf.SPU(
    cluster_def=spu_conf, 
    link_desc={
        "connect_retry_times": 60,
        "connect_retry_interval_ms": 1000
    },
)
# only alice
import pandas  as pd

alice_df = pd.DataFrame({
    "name": ["alice", "bob", "carol", "tony"],
    "age": [11, 13, 14, 26]
})


current_dir = os.getcwd()
alice_df.to_csv(f"{current_dir}/alice_pir_input.csv", index=False)
# only bob
import pandas  as pd

alice_df = pd.DataFrame({
    "name": ["tony", "alice"]
})


current_dir = os.getcwd()
alice_df.to_csv(f"{current_dir}/bob_pir_query.csv", index=False)

需要事先在alice的docker container内执行openssl rand 32 >/root/workspace/alice_oprf_key创建秘钥

spu.pir_setup(
    server="alice",
    input_path=f"{current_dir}/alice_pir_input.csv",
    key_columns=["name"],
    label_columns=["age"],
    oprf_key_path=f"{current_dir}/alice_oprf_key",
    setup_path=f"{current_dir}/alice_setup",
    num_per_query=1,
    label_max_len=20,
    bucket_size=1000000
)
spu.pir_query(
    server="alice",
    client="bob",
    server_setup_path=f"{current_dir}/alice_setup",
    client_key_columns=["name"],
    client_input_path=f"{current_dir}/bob_pir_query.csv",
    client_output_path=f"{current_dir}/bob_pir_result.csv",
)
sf.shutdown()

结果检验

img

img

生成了对应的csv文件

img

output的结果也是正确的。

作业2

执行步骤

首先将给出的setup好了的结果文件及文件夹放到对应位置

docker cp /mnt/d/tmp/pir_server_setup sim-alice-1:/root/workspace
docker cp /mnt/d/tmp/server_secret_key.bin sim-alice-1:/tmp
docker cp /mnt/d/tmp/server_secret_key.bin sim-bob-1:/tmp

然后正常启动secretnote,上传pir_query.csv到bob,操作部分直接query就能得到结果文件

current_dir = os.getcwd()
spu.pir_query(
    server="alice",
    client="bob",
    server_setup_path=f"{current_dir}/pir_server_setup",
    client_key_columns=["uid"],
    client_input_path=f"{current_dir}/pir_query.csv",
    client_output_path=f"{current_dir}/pir_result.csv",
)

结果检验

img

img

img

可以看到代码执行良好,生成结果文件,隐私查询成功。

课程总结

张磊 | 蚂蚁集团安全协议团队技术专家
冯骏 I 蚂蚁集团隐私计算技术专家隐语开源社区Maintainer
视频地址pdf地址
代码实践的关键就是在alice的docker内创建秘钥,而不是wsl-ubuntu下的用户目录下。

...全文
266 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
周子吃肘子 2024-04-07
  • 打赏
  • 举报
回复

您好请问我按照您的做出现这种情况如何解决呢

img

日向远 2024-04-07
  • 举报
回复
@周子吃肘子 你的镜像是'secretflow/secretnote:1.5.0.dev'吗,可以检查下你的docker-compose.yml

554

社区成员

发帖
与我相关
我的任务
社区描述
隐语开源社区,隐私计算开发者交流和讨论的平台。
密码学可信计算技术安全 企业社区
社区管理员
  • 隐语SecretFlow
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

【最新活动】

3月18日:隐私计算实训营第一期

试试用AI创作助手写篇文章吧