从旅行社到隐私计算:用Python模拟不经意传输(OT)协议,理解隐私保护的核心
从旅行社到隐私计算:用Python模拟不经意传输(OT)协议,理解隐私保护的核心
想象一下这样的场景:你想向旅行社咨询某个景点的详细信息,但又不想透露自己具体对哪个景点感兴趣。这听起来像是个不可能完成的任务——毕竟,旅行社总要知道你想了解哪个景点才能提供相应资料。但密码学中的"不经意传输"(Oblivious Transfer,简称OT)协议,恰恰能让这种看似矛盾的需求成为现实。
OT协议是隐私计算领域的基石技术之一,它允许信息发送方将多个信息项传递给接收方,但接收方只能获取其中一部分,而发送方无法知道接收方具体选择了哪些信息。这种神奇的特性使其在电子投票、隐私保护数据挖掘、安全多方计算等场景中发挥着关键作用。
1. 不经意传输协议的核心思想
OT协议最经典的版本是1-out-of-2 OT,即发送方持有两条信息(m₀和m₁),接收方可以选择获取其中一条,但无法获取另一条,同时发送方也不知道接收方选择了哪条信息。这完美对应了我们开头的旅行社场景:
- 旅行社持有景点A和B的资料(m₀和m₁)
- 游客(接收方)可以选择获取其中一个景点的资料
- 游客无法获取另一个未选择景点的资料
- 旅行社无法知道游客最终选择了哪个景点
这种协议的神奇之处在于,它同时保护了双方的隐私:接收方的选择隐私和发送方的数据隐私。要实现这一点,OT协议通常依赖于公钥密码学和一些巧妙的数学构造。
2. 用Python模拟OT协议
让我们通过一个简化的Python实现来理解OT协议的工作原理。我们将使用RSA加密算法作为基础,构建一个1-out-of-2 OT协议模拟。
import random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
class Sender:
def __init__(self, m0, m1):
self.m0 = m0
self.m1 = m1
self.key = RSA.generate(2048)
self.x0 = random.getrandbits(256)
self.x1 = random.getrandbits(256)
def get_public_key(self):
return self.key.publickey()
def receive_encrypted_k(self, encrypted_k_plus_xi):
cipher = PKCS1_OAEP.new(self.key)
k0 = cipher.decrypt((encrypted_k_plus_xi - self.x0).to_bytes(256, 'big'))
k1 = cipher.decrypt((encrypted_k_plus_xi - self.x1).to_bytes(256, 'big'))
return (self.m0 + k0, self.m1 + k1)
class Receiver:
def __init__(self, choice):
self.choice = choice # 0 or 1
self.k = random.getrandbits(256)
def encrypt_k(self, sender_pubkey, x0, x1):
cipher = PKCS1_OAEP.new(sender_pubkey)
encrypted_k = int.from_bytes(cipher.encrypt(self.k.to_bytes(256, 'big')), 'big')
xi = x0 if self.choice == 0 else x1
return encrypted_k + xi
def decrypt_result(self, m0_prime, m1_prime):
mi_prime = m0_prime if self.choice == 0 else m1_prime
return mi_prime - self.k
这个实现虽然简化,但包含了OT协议的核心要素:
-
发送方(Sender) :
- 持有两条信息m₀和m₁
- 生成RSA密钥对和两个随机数x₀、x₁
- 能够处理接收方加密后的选择
-
接收方(Receiver) :
- 持有选择位(0或1)
- 生成随机数k
- 能够加密自己的选择并发送给发送方
- 能够解密最终结果
3. 协议执行流程
让我们看看这个协议在实际中如何工作:
# 模拟数据
m0 = 12345 # 景点A的资料
m1 = 67890 # 景点B的资料
choice = 0 # 游客想获取景点A的资料
# 初始化双方
sender = Sender(m0, m1)
receiver = Receiver(choice)
# 协议执行步骤
# 1. 接收方获取发送方公钥和随机数
sender_pubkey = sender.get_public_key()
x0, x1 = sender.x0, sender.x1
# 2. 接收方加密k并加上x_i
encrypted_k_plus_xi = receiver.encrypt_k(sender_pubkey, x0, x1)
# 3. 发送方处理加密后的选择
m0_prime, m1_prime = sender.receive_encrypted_k(encrypted_k_plus_xi)
# 4. 接收方解密结果
result = receiver.decrypt_result(m0_prime, m1_prime)
print(f"接收方获取的结果: {result}") # 应该输出12345(m0)
这个模拟展示了OT协议的关键特性:
- 接收方成功获取了选择的信息(m₀),而不知道m₁的值
- 发送方无法从encrypted_k_plus_xi中确定接收方的选择,因为x₀和x₁都是随机数
- 整个过程中,双方的真实信息都得到了保护
4. OT协议的安全性与优化
虽然上面的实现展示了基本原理,但实际应用中OT协议需要考虑更多安全因素和性能优化:
安全性考虑 :
- 随机数生成必须密码学安全
- RSA加密需要适当的填充方案(如OAEP)
- 需要防范各种主动攻击(如中间人攻击)
性能优化 :
- 实际应用中会使用OT扩展技术,通过少量基础OT生成大量OT实例
- 使用更高效的加密原语(如椭圆曲线密码)
- 预处理技术(离线阶段生成随机OT,在线阶段快速计算)
以下是一个简化的性能对比表:
| 方法 | 计算复杂度 | 通信轮数 | 适合场景 |
|---|---|---|---|
| 基础RSA OT | 高 | 2-3 | 少量OT |
| OT扩展 | 低 | 多轮 | 大量OT |
| 椭圆曲线OT | 中 | 2-3 | 带宽敏感 |
5. OT协议在隐私计算中的应用
OT协议不仅仅是理论上的奇思妙想,它在实际隐私计算场景中有着广泛应用:
-
隐私保护数据查询 :
- 用户可以从数据库中查询特定信息而不泄露查询内容
- 数据库提供商不知道用户查询了哪些数据
-
安全多方计算 :
- 多方可以在不泄露各自输入的情况下共同计算函数结果
- OT是构建通用安全多方计算协议的基础组件
-
隐私保护机器学习 :
- 模型可以在加密数据上训练,保护数据隐私
- 预测时可以保护用户的查询隐私
# 隐私保护数据查询的简化示例
class Database:
def __init__(self, records):
self.records = records
def process_ot_query(self, ot_protocol, query_index):
# 使用OT协议处理查询
# record0和record1可以是任意两条记录
# 实际中会使用更复杂的索引方案
record0 = self.records[query_index]
record1 = self.records[(query_index + 1) % len(self.records)]
return ot_protocol.transfer(record0, record1)
这个例子展示了如何将OT协议应用于数据库查询场景,保护用户的查询隐私和数据库的数据隐私。
更多推荐

所有评论(0)