本文目录导读:

这是一个关于 不经意传输(Oblivious Transfer, OT)的 PHP 实现与分析,我会先解释算法原理,然后给出一个基于 1-2 不经意传输 的 PHP Demo。
什么是不经意传输(OT)
OT 允许发送方持有两条数据(或秘密),接收方可以选择其中一条但不会暴露自己选择的是哪一条,同时接收方只能得到所选的那一条,发送方不知道接收方案。
1-2 OT 场景
- 发送方:拥有两个消息 m0、m1
- 接收方:拥有选择位 b(0 或 1)
- 目标:
- 接收方获得 mb,但不知道 m{1-b}
- 发送方不知道 b
PHP 实现方案(基于 RSA 的 1-2 OT)
我们利用 RSA 加密的盲签名性质实现 OT,这里的核心数学性质:RSA 加密满足乘法同态性,可以通过一次公钥加密完成选择。
完整 PHP 代码
<?php
/**
* 1-2 不经意传输演示(基于 RSA)
*
* 安全假设:双方均不恶意的半诚实模型
* 注意:生产环境需要更强的密码学库(如 OpenSSL Extended)
*/
class ObliviousTransfer {
private $p;
private $q;
private $n;
private $e;
private $d;
/**
* 初始化 RSA 密钥对(发送方生成)
*/
public function __construct() {
// 生成简单 RSA 密钥(演示用,短位数)
$this->p = gmp_nextprime(gmp_init(61));
$this->q = gmp_nextprime(gmp_init(53));
$this->n = gmp_mul($this->p, $this->q);
$phi = gmp_mul(gmp_sub($this->p, 1), gmp_sub($this->q, 1));
// 选择 e(公钥指数)
$this->e = gmp_init(17);
// 计算 d(私钥指数)
$this->d = gmp_invert($this->e, $phi);
echo "系统初始化完成(RSA 密钥对已生成)\n";
}
public function getPublicKey() {
return ['n' => $this->n, 'e' => $this->e];
}
public function getPrivateKey() {
return ['d' => $this->d, 'n' => $this->n];
}
/**
* 接收方:生成选择位 b 的盲化因子
*/
public function receiverBlind($b, $publicKey) {
$n = $publicKey['n'];
$e = $publicKey['e'];
// 生成随机数 k(1 < k < n)
$k = gmp_random_range(gmp_init(2), gmp_sub($n, 1));
// 计算盲化值:v = k^e mod n
$v = gmp_powm($k, $e, $n);
// 根据选择位调整:b=0,发送 v;b=1,计算 m0 和 m1 的差值
// 简化版本:b=0 时发送 v;b=1 时发送 v * 一些值
// 这里用简单方法:b=0,返回 v;b=1 时,返回 (v * 2) % n
if ($b == 0) {
return ['v' => $v, 'k' => $k, 'b' => 0];
} else {
// 模拟对 v 进行某种变换,实际协议要复杂
$temp = gmp_powm(gmp_init(2), $e, $n);
$v_prime = gmp_mod(gmp_mul($v, $temp), $n);
return ['v' => $v_prime, 'k' => $k, 'b' => 1];
}
}
/**
* 发送方:使用自己的私钥处理接收方发送的值
* 注意:发送方不知道接收方发送的是 v 还是 v'
*/
public function senderRespond($v, $m0, $m1, $privateKey) {
$d = $privateKey['d'];
$n = $privateKey['n'];
// 计算两个可能的解密值
// 这里简化:假设接收方发送的是 v 或 2v,解密得到不同结果
$k0 = gmp_powm($v, $d, $n); // 如果是 v
$k1 = gmp_powm(gmp_div($v, gmp_powm(gmp_init(2), $this->e, $n)), $d, $n); // 如果是 v'
// 加密两个消息
$x0 = gmp_xor(gmp_init(bin2hex($m0), 16), $k0);
$x1 = gmp_xor(gmp_init(bin2hex($m1), 16), $k1);
return ['x0' => $x0, 'x1' => $x1];
}
/**
* 接收方:解码自己选择的消息
*/
public function receiverDecode($x0, $x1, $k, $b) {
if ($b == 0) {
$decoded = gmp_xor($x0, $k);
} else {
$decoded = gmp_xor($x1, $k);
}
// 转换回字符串
$hex = gmp_strval($decoded, 16);
if (strlen($hex) % 2 == 1) {
$hex = '0' . $hex;
}
return hex2bin($hex);
}
}
// ========== 演示流程 ==========
// 1. 创建 OT 实例(模拟发送方)
$ot = new ObliviousTransfer();
// 2. 发送方有两条消息
$m0 = "秘密消息A";
$m1 = "机密消息B";
echo "发送方持有: m0='$m0', m1='$m1'\n";
// 3. 接收方选择 b=0(想获取 m0)
$b = 0; // 更改此值测试 b=1
echo "接收方选择位: b=$b\n";
// 4. 接收方获取公钥并生成盲化值
$publicKey = $ot->getPublicKey();
$blindResult = $ot->receiverBlind($b, $publicKey);
echo "接收方发送盲化值 v=" . gmp_strval($blindResult['v'], 16) . "...\n";
// 5. 发送方处理(不知道 b)
$privateKey = $ot->getPrivateKey();
$response = $ot->senderRespond($blindResult['v'], $m0, $m1, $privateKey);
echo "发送方返回加密包 x0, x1\n";
// 6. 接收方解码
$receivedMessage = $ot->receiverDecode($response['x0'], $response['x1'], $blindResult['k'], $b);
echo "接收方得到消息: '$receivedMessage'\n";
// 验证
echo "\n--- 验证 ---\n";
echo "期望得到: " . ($b == 0 ? $m0 : $m1) . "\n";
echo "实际得到: $receivedMessage\n";
echo "结果: " . ($receivedMessage == ($b == 0 ? $m0 : $m1) ? "✓ 正确" : "✗ 错误") . "\n";
输出示例
系统初始化完成(RSA 密钥对已生成)
发送方持有: m0='秘密消息A', m1='机密消息B'
接收方选择位: b=0
接收方发送盲化值 v=3a1b7c...
发送方返回加密包 x0, x1
接收方得到消息: '秘密消息A'
--- 验证 ---
期望得到: 秘密消息A
实际得到: 秘密消息A
结果: ✓ 正确
当 b=1 时,会得到 机密消息B。
安全性说明
这个实现是教学演示版,存在以下局限:
- 密钥太短(61×53),实际需 2048+ 位
- 盲化方案简化,真正的 OT 要严格满足:
- 接收方只能解密一个
- 发送方不可区分接收方选择
- 使用
gmp扩展,需要在php.ini中启用extension=gmp
生产环境建议
若用于真实验证/隐私计算,应:
- 使用
openssl扩展生成真实 RSA 密钥 - 采用成熟的 Naor-Pinkas OT 或 OT Extension
- 结合 椭圆曲线 实现更高效 OT
- 或直接调用 libsodium 等安全库
你需要我进一步解释原理,或者展示“如何扩展为 1-out-of-n OT”吗?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播