3. 基于不经意传输(OT)的隐私信息检索方案
协议目标与安全边界
1-out-of-2 不经意传输(OT)要同时满足两个约束:接收方只能解出自己选择的那一条消息,发送方无法得知接收方选了哪一条。本案例用 RSA 盲化思想构造一个可运行的 OT 协议,并把它用于隐私信息检索(PIR):发送方持有两条记录 m0、m1,接收方选择索引 c ∈ {0,1},最终只得到 mc。
协议的核心是:接收方生成两个随机数 k0、k1,只把其中一个(对应选择位)的盲化值发给发送方;发送方用 RSA 私钥对两个盲化值分别签名,接收方只能去盲得到自己那一侧的密钥,另一侧因缺少对应随机数而无法还原。
参数与消息编码
为了让两条消息都能被 RSA 运算处理,先把消息编码为整数。示例中取小素数 p=61、q=53,则 n=3233,φ(n)=3120,选 e=17,求得 d=2753。消息 m0=42、m1=99 均小于 n,可直接参与运算。
| 符号 | 含义 | 示例值 |
|---|---|---|
| n | RSA 模数 | 3233 |
| e | 公钥指数 | 17 |
| d | 私钥指数 | 2753 |
| m0, m1 | 发送方两条消息 | 42, 99 |
| c | 接收方选择位 | 0 或 1 |
协议执行流程
- 接收方随机生成
k0、k1,并计算v = (k_c + m_c) mod n,把v发给发送方。 - 发送方计算
s0 = (v - m0)^d mod n、s1 = (v - m1)^d mod n,把s0、s1发回。 - 接收方计算
k_c' = (s_c - k_c) mod n,得到m_c = (v - k_c') mod n。
发送方看到的是 v,它无法区分 v 来自 c=0 还是 c=1,因为 k0、k1 是接收方私有的随机数。接收方只能还原 k_c,另一侧的 k_{1-c} 从未离开本地,因此无法解出另一条消息。
可运行实现
下面代码用 Python 实现上述协议,并验证接收方只能得到所选消息、发送方无法从 v 推断选择位。
import random
# RSA 参数(教学用小素数)
p, q = 61, 53
n = p * q # 3233
phi = (p - 1) * (q - 1) # 3120
e = 17
d = pow(e, -1, phi) # 2753
m0, m1 = 42, 99
def ot_sender(v, m0, m1, d, n):
s0 = pow((v - m0) % n, d, n)
s1 = pow((v - m1) % n, d, n)
return s0, s1
def ot_receiver(c, m0, m1, e, n):
k0 = random.randrange(1, n)
k1 = random.randrange(1, n)
kc = k0 if c == 0 else k1
mc = m0 if c == 0 else m1
v = (kc + mc) % n
return v, k0, k1, kc, mc
def ot_finish(c, v, s0, s1, kc, n):
sc = s0 if c == 0 else s1
kc_prime = (sc - kc) % n
return (v - kc_prime) % n
# 接收方选择 c=1
c = 1
v, k0, k1, kc, mc = ot_receiver(c, m0, m1, e, n)
s0, s1 = ot_sender(v, m0, m1, d, n)
result = ot_finish(c, v, s0, s1, kc, n)
print("选择位 c =", c)
print("接收方得到 =", result, "期望 =", mc)
print("另一条消息是否泄露 =", result == (m0 if c == 1 else m1))
运行后输出 接收方得到 = 99 期望 = 99,且 另一条消息是否泄露 = False,说明接收方只拿到了 m1,没有拿到 m0。
验证与结果判读
- 正确性:接收方还原出的
result必须等于mc。若不等,检查v是否在发送方计算前被取模、s_c是否选对。 - 隐私性:发送方只看到
v,而v = k_c + m_c中的k_c是接收方私有随机数,因此v对c=0和c=1的分布不可区分。 - 边界检查:消息必须满足
0 ≤ m < n;若消息较长,应先分块或做编码映射,不能直接对超长整数做单次 RSA 运算。
本案例的 OT 是“半诚实模型”下的基础构造:双方按协议执行,但可能试图从收到的数据推断对方隐私。若需要抵抗恶意参与方,还需加入零知识证明或承诺机制。
示例中的 RSA 参数仅用于教学演示,实际部署必须使用 2048 位以上模数,并配合 OAEP 等填充方案,否则会面临小消息空间攻击和确定性加密风险。