PHP项目随机信标与可验证随机

wen PHP项目 2

本文目录导读:

PHP项目随机信标与可验证随机

  1. 随机信标实现
  2. 可验证随机函数 (VRF) 实现
  3. 综合应用:公平抽奖系统
  4. 增强安全性:多方计算实现

我来帮你实现PHP项目的随机信标(Random Beacon)和可验证随机函数(Verifiable Random Function, VRF)。

随机信标实现

基本随机信标类

<?php
class RandomBeacon {
    private $source;
    private $timestamp;
    private $entropy;
    private $hash;
    /**
     * 生成随机信标
     */
    public function generateBeacon() {
        // 收集多源熵值
        $this->entropy = $this->collectEntropy();
        // 生成时间戳
        $this->timestamp = time();
        // 生成哈希
        $this->hash = $this->computeHash();
        return [
            'timestamp' => $this->timestamp,
            'entropy' => $this->entropy,
            'hash' => $this->hash,
            'random' => $this->getRandomNumber(0, 1000000)
        ];
    }
    /**
     * 收集多源熵值
     */
    private function collectEntropy() {
        $sources = [
            microtime(true) * 10000,
            memory_get_usage(),
            getmypid(),
            mt_rand(),
            $this->getSystemRandom()
        ];
        return implode('|', $sources);
    }
    /**
     * 获取系统随机数
     */
    private function getSystemRandom() {
        if (function_exists('random_bytes')) {
            return bin2hex(random_bytes(32));
        }
        return openssl_random_pseudo_bytes(32);
    }
    /**
     * 计算哈希值
     */
    private function computeHash() {
        $data = $this->timestamp . '|' . $this->entropy . '|' . uniqid('', true);
        return hash('sha256', $data);
    }
    /**
     * 获取随机数
     */
    public function getRandomNumber($min = 0, $max = 1000000) {
        $hex = substr($this->hash, 0, 8);
        $dec = hexdec($hex);
        // 使用 hash 值生成随机数
        return $min + ($dec % ($max - $min + 1));
    }
    /**
     * 验证信标
     */
    public function verifyBeacon($beacon) {
        $data = $beacon['timestamp'] . '|' . $beacon['entropy'] . '|' . $beacon['random'];
        $computedHash = hash('sha256', $data);
        return $computedHash === $beacon['hash'];
    }
}
// 使用示例
$beacon = new RandomBeacon();
$beaconData = $beacon->generateBeacon();
echo "随机信标: " . json_encode($beaconData) . "\n";
echo "验证结果: " . ($beacon->verifyBeacon($beaconData) ? "有效" : "无效") . "\n";

可验证随机函数 (VRF) 实现

使用 ECDSA 的 VRF 实现

<?php
class VRF {
    private $privateKey;
    private $publicKey;
    /**
     * 构造函数,生成密钥对
     */
    public function __construct() {
        $this->generateKeyPair();
    }
    /**
     * 生成密钥对
     */
    private function generateKeyPair() {
        $config = [
            'private_key_type' => OPENSSL_KEYTYPE_EC,
            'curve_name' => 'secp256k1',  // 使用椭圆曲线
            'digest_alg' => 'sha256'
        ];
        // 生成私钥
        $res = openssl_pkey_new($config);
        openssl_pkey_export($res, $this->privateKey);
        // 获取公钥
        $keyDetails = openssl_pkey_get_details($res);
        $this->publicKey = $keyDetails['key'];
    }
    /**
     * 生成 VRF 证明和输出
     */
    public function generateProof($message) {
        $proof = hash_hmac('sha256', $message, $this->privateKey, true);
        $output = hash('sha256', $proof, true);
        // 签名证明
        $signature = '';
        openssl_sign($proof, $signature, $this->privateKey, OPENSSL_ALGO_SHA256);
        return [
            'proof' => bin2hex($proof),
            'output' => bin2hex($output),
            'signature' => bin2hex($signature),
            'public_key' => $this->publicKey
        ];
    }
    /**
     * 验证 VRF 输出
     */
    public function verifyProof($message, $proof, $output, $publicKey) {
        // 将十六进制转换回二进制
        $proofBinary = hex2bin($proof);
        $outputBinary = hex2bin($output);
        // 验证输出
        $computedOutput = hash('sha256', $proofBinary, true);
        if ($computedOutput !== $outputBinary) {
            return false;
        }
        // 验证签名
        $signature = hex2bin($proof);  // 使用证明作为签名的一部分
        $result = openssl_verify($proofBinary, $signature, $publicKey, OPENSSL_ALGO_SHA256);
        return $result === 1;
    }
    /**
     * 将 VRF 输出转换为指定范围的整数
     */
    public function toInteger($output, $min = 0, $max = 1000000) {
        $hex = substr($output, 0, 8);
        $dec = hexdec($hex);
        return $min + ($dec % ($max - $min + 1));
    }
}
// 使用示例
$vrf = new VRF();
$message = "lottery_round_1";
try {
    $proof = $vrf->generateProof($message);
    echo "VRF 证明生成成功:\n";
    echo "消息: " . $message . "\n";
    echo "证明: " . substr($proof['proof'], 0, 30) . "...\n";
    echo "输出: " . substr($proof['output'], 0, 30) . "...\n";
    // 验证
    $isValid = $vrf->verifyProof(
        $message, 
        $proof['proof'], 
        $proof['output'], 
        $proof['public_key']
    );
    echo "验证结果: " . ($isValid ? "有效" : "无效") . "\n";
    // 输出随机数
    $randomNumber = $vrf->toInteger($proof['output'], 1, 100);
    echo "生成的随机数: " . $randomNumber . "\n";
} catch (Exception $e) {
    echo "错误: " . $e->getMessage() . "\n";
}

综合应用:公平抽奖系统

<?php
class FairLottery {
    private $vrf;
    private $beacon;
    public function __construct() {
        $this->vrf = new VRF();
        $this->beacon = new RandomBeacon();
    }
    /**
     * 创建彩票轮次
     */
    public function createRound($roundId, $participants) {
        // 生成信标种子
        $beaconData = $this->beacon->generateBeacon();
        $round = [
            'id' => $roundId,
            'beacon' => $beaconData,
            'participants' => $participants,
            'timestamp' => time(),
            'results' => []
        ];
        return $round;
    }
    /**
     * 抽取中奖者
     */
    public function drawWinners($round, $winnerCount) {
        $message = $round['id'] . '|' . $round['beacon']['hash'];
        $proof = $this->vrf->generateProof($message);
        $participants = $round['participants'];
        $indices = [];
        // 使用 VRF 输出选择中奖者
        for ($i = 0; $i < $winnerCount; $i++) {
            $seed = $proof['output'] . '|' . $i;
            $winnerIndex = $this->vrf->toInteger($seed, 0, count($participants) - 1);
            // 确保不重复选择
            while (in_array($winnerIndex, $indices)) {
                $winnerIndex = ($winnerIndex + 1) % count($participants);
            }
            $indices[] = $winnerIndex;
        }
        // 记录结果和证明
        $winners = [];
        foreach ($indices as $index) {
            $winners[] = [
                'participant' => $participants[$index],
                'position' => $index,
                'verification_hash' => hash('sha256', $index . '|' . $proof['proof'])
            ];
        }
        return [
            'round_id' => $round['id'],
            'winners' => $winners,
            'vrf_proof' => $proof,
            'beacon_hash' => $round['beacon']['hash']
        ];
    }
    /**
     * 验证抽奖结果
     */
    public function verifyLottery($round, $result) {
        // 验证信标
        if (!$this->beacon->verifyBeacon($round['beacon'])) {
            return ['valid' => false, 'reason' => '信标验证失败'];
        }
        // 验证 VRF
        $message = $round['id'] . '|' . $round['beacon']['hash'];
        if (!$this->vrf->verifyProof(
            $message,
            $result['vrf_proof']['proof'],
            $result['vrf_proof']['output'],
            $result['vrf_proof']['public_key']
        )) {
            return ['valid' => false, 'reason' => 'VRF 验证失败'];
        }
        return ['valid' => true, 'reason' => '验证通过'];
    }
}
// 使用示例
$lottery = new FairLottery();
// 创建参与者列表
$participants = [];
for ($i = 1; $i <= 100; $i++) {
    $participants[] = "user_" . $i;
}
// 创建抽奖轮次
$round = $lottery->createRound('round_2024_001', $participants);
echo "抽奖轮次创建成功\n";
// 抽取中奖者
$result = $lottery->drawWinners($round, 3);
echo "\n中奖结果:\n";
foreach ($result['winners'] as $winner) {
    echo "  - " . $winner['participant'] . "\n";
}
// 验证结果
$verification = $lottery->verifyLottery($round, $result);
echo "\n验证结果: " . $verification['reason'] . "\n";

增强安全性:多方计算实现

<?php
class DistributedBeacon {
    private $parties = [];
    private $threshold;
    /**
     * 添加参与方
     */
    public function addParty($partyId, $publicKey) {
        $this->parties[$partyId] = [
            'public_key' => $publicKey,
            'commitment' => null,
            'reveal' => null
        ];
    }
    /**
     * 提交承诺
     */
    public function commit($partyId, $secret) {
        // 生成承诺 (哈希加盐)
        $salt = bin2hex(random_bytes(16));
        $commitment = hash('sha256', $secret . '|' . $salt);
        $this->parties[$partyId] = [
            'commitment' => $commitment,
            'salt' => $salt,
            'secret' => $secret,
            'revealed' => false
        ];
        return $commitment;
    }
    /**
     * 揭示秘密
     */
    public function reveal($partyId) {
        $party = $this->parties[$partyId];
        // 验证承诺
        $expectedCommitment = hash('sha256', $party['secret'] . '|' . $party['salt']);
        if ($expectedCommitment !== $party['commitment']) {
            throw new Exception("承诺验证失败");
        }
        $this->parties[$partyId]['revealed'] = true;
        return [
            'secret' => $party['secret'],
            'salt' => $party['salt']
        ];
    }
    /**
     * 生成最终信标
     */
    public function finalize() {
        $combinedSecret = '';
        foreach ($this->parties as $partyId => $party) {
            if (!$party['revealed']) {
                throw new Exception("参与方 $partyId 未揭示秘密");
            }
            $combinedSecret .= $party['secret'];
        }
        // 组合所有秘密生成最终信标
        $finalHash = hash('sha256', $combinedSecret . time());
        return [
            'hash' => $finalHash,
            'participants' => count($this->parties),
            'timestamp' => time()
        ];
    }
}
// 使用示例
$db = new DistributedBeacon();
// 添加参与方
$db->addParty('party1', 'key1');
$db->addParty('party2', 'key2');
$db->addParty('party3', 'key3');
// 提交承诺
$commitment1 = $db->commit('party1', 'secret1');
$commitment2 = $db->commit('party2', 'secret2');
$commitment3 = $db->commit('party3', 'secret3');
echo "所有参与方已提交承诺\n";
// 揭示秘密
$reveal1 = $db->reveal('party1');
$reveal2 = $db->reveal('party2');
$reveal3 = $db->reveal('party3');
echo "所有参与方已揭示秘密\n";
// 生成最终信标
$finalBeacon = $db->finalize();
echo "最终信标哈希: " . $finalBeacon['hash'] . "\n";

核心特点:

  1. 随机信标:提供不可预测的随机源
  2. 可验证随机函数(VRF):证明随机性的正确性
  3. 公平性:所有参与者可验证结果
  4. 抗篡改:使用加密技术保护过程

应用场景:

  • 在线抽奖和游戏
  • 加密货币合约
  • 分布式决策系统
  • 密码学协议

安全建议:

  1. 使用安全的随机数生成器
  2. 定期更换密钥
  3. 审计和日志记录
  4. 多重签名验证

这些实现提供了完整的随机信标和VRF功能,可以用于需要公平性和可验证性的分布式系统。

抱歉,评论功能暂时关闭!