用Python和libOTe库5分钟实现不经意传输(OT)隐私计算Demo

想象一下这个场景:你想从旅行社获取某个景点的资料,但又不希望对方知道你具体选了哪个景点。这看似矛盾的需求,正是密码学中"不经意传输"(Oblivious Transfer)要解决的经典问题。今天我们就用Python和libOTe库,带你快速实现一个1-out-of-2 OT的隐私计算Demo。

1. 环境准备与基础概念

在开始编码前,我们需要先搭建开发环境并理解OT的基本原理。不经意传输是一种密码学协议,允许发送方(如旅行社)向接收方(如游客)传输多个信息中的一个,而发送方不知道接收方具体选择了哪个信息。

安装所需库:

pip install python-libote numpy

OT协议有三个关键特性:

  1. 隐私性 :发送方无法得知接收方选择了哪个信息
  2. 正确性 :接收方只能获取自己选择的信息
  3. 安全性 :发送方的其他信息不会被泄露

在1-out-of-2 OT中:

  • 发送方提供两个信息(m₀, m₁)
  • 接收方选择一个索引c∈{0,1}
  • 接收方只能获得m_c,而不知道m_{1-c}
  • 发送方不知道c的值

2. libOTe库基础使用

libOTe是一个高效的OT扩展库,支持多种OT协议。我们先看一个最简单的ROT(Random OT)示例:

import numpy as np
from libote import rot_sender, rot_receiver

# 随机OT示例
def demo_random_ot():
    # 发送方和接收方各生成128个随机OT
    count = 128
    sender = rot_sender(count)
    receiver = rot_receiver(count)
    
    # 执行协议
    sender.send()
    receiver.receive()
    
    # 获取结果
    s_output = sender.get_output()
    r_output = receiver.get_output()
    
    print(f"发送方随机数: {s_output[:2]}...")
    print(f"接收方选择位: {r_output['choices'][:2]}...")
    print(f"接收方结果: {r_output['outputs'][:2]}...")

这个简单的ROT演示了最基本的OT交互流程。在实际应用中,我们更常用的是Standard OT,下面我们来实现一个完整的1-out-of-2 OT。

3. 实现1-out-of-2 OT协议

让我们用libOTe实现一个完整的1-out-of-2 OT,模拟旅行社和小王的场景:

from libote import ot_sender, ot_receiver

def demo_standard_ot():
    # 旅行社(发送方)准备两个景点的资料
    messages = [
        b"这是景点A的详细资料...",
        b"这是景点B的详细资料..."
    ]
    
    # 小王(接收方)选择想获取的景点索引(0或1)
    choice = 0  # 假设选择景点A
    
    # 初始化发送方和接收方
    sender = ot_sender(messages)
    receiver = ot_receiver(choice)
    
    # 执行OT协议
    sender.send()
    receiver.receive()
    
    # 获取结果
    result = receiver.get_result()
    print(f"小王获取的资料: {result.decode()}")

这个实现虽然简单,但完整展示了OT协议的核心流程。让我们分析下其中的关键点:

  1. 发送方输入 :两个独立的消息(m₀, m₁)
  2. 接收方输入 :选择位c
  3. 协议执行 :通过加密交换确保隐私
  4. 输出结果 :接收方只获得m_c

4. 协议优化与性能考虑

在实际应用中,我们需要考虑OT协议的性能优化。libOTe提供了OT扩展技术,可以显著提高效率:

def demo_ot_extension():
    # 批量处理多个OT请求
    batch_size = 1024
    
    # 发送方准备批量消息
    messages = [
        (f"消息{i}_0".encode(), f"消息{i}_1".encode())
        for i in range(batch_size)
    ]
    
    # 接收方准备批量选择位
    choices = np.random.randint(0, 2, batch_size)
    
    # 使用OT扩展
    sender = ot_sender(messages, use_extension=True)
    receiver = ot_receiver(choices, use_extension=True)
    
    # 执行协议
    sender.send()
    receiver.receive()
    
    # 验证结果
    results = receiver.get_results()
    print(f"处理了{len(results)}个OT请求")
    print(f"第一个结果: {results[0].decode()}")

OT扩展技术通过以下方式提升性能:

  1. 基础OT :先执行少量(如128个)"昂贵"的基础OT
  2. 扩展阶段 :使用密码学哈希函数扩展出大量OT
  3. 效率提升 :将计算复杂度从O(n)降低到O(1)

5. 实际应用场景与进阶

OT协议在隐私计算中有广泛应用,比如:

  • 隐私信息检索 :用户可以从数据库中获取信息而不泄露查询内容
  • 安全多方计算 :作为基础组件构建更复杂的隐私保护协议
  • 机器学习隐私 :保护模型训练中的数据隐私

下面是一个模拟隐私信息检索的示例:

def demo_private_information_retrieval():
    # 模拟数据库(发送方)
    database = [
        b"产品A的价格是$100",
        b"产品B的价格是$200",
        b"产品C的价格是$150",
        b"产品D的价格是$300"
    ]
    
    # 用户(接收方)想查询第2个产品(索引从0开始)
    query_index = 2
    
    # 将数据库转换为OT格式(每对相邻元素为一组)
    ot_messages = [
        (database[i], database[i+1]) 
        for i in range(0, len(database), 2)
    ]
    
    # 计算选择位
    choice_bit = 0 if query_index % 2 == 0 else 1
    group_index = query_index // 2
    
    # 执行OT
    sender = ot_sender(ot_messages[group_index])
    receiver = ot_receiver(choice_bit)
    
    sender.send()
    receiver.receive()
    
    result = receiver.get_result()
    print(f"查询结果: {result.decode()}")

这个例子展示了如何用OT实现最基本的隐私信息检索。在实际系统中,还需要考虑:

  • 数据库的规模扩展
  • 多轮查询优化
  • 与其他密码学原语的结合

更多推荐