EdwardAThomson/Private-Set-Intersection

GitHub: EdwardAThomson/Private-Set-Intersection

基于 ristetrotto255 和 Blake3 的隐私集合求交协议 C++ 实现,提供 CLI、HTTP 服务及 React 前端集成,支持两方在不泄露明文的前提下计算集合交集。

Stars: 1 | Forks: 0

# 隐私集合求交 (PSI) C++ PSI 协议参考实现的 C++ 移植版,基于 libsodium (ristretto255, XSalsa20-Poly1305) 和 Blake3 C 实现构建,包含确定性测试、CLI 工具以及用于 UI 集成的 HTTP endpoint。 该项目遵循 JavaScript 演示的四阶段工作流。两个实现最初都将元素哈希到曲线,形式为 `H(x)·G`(这是一个已知的离散对数,允许一方在离线状态下枚举另一方的集合),并将明文元素与盲化值一起发送。这两个缺陷在此处均已修复(参见 `docs/security_hardening.md`),并且相同的修复也已移植到 JS 仓库中([psi-demo PR #1](https://github.com/EdwardAThomson/psi-demo/pull/1)):现在两者都使用 ristretto255 的 hash-to-group、成员标签以及无明文的传输消息。`reference/` 下打包的旧版 JS 代码早于这些修复,仅保留作为可视化辅助工具。 之前版本的代码(JS 版)包含在此处,但也单独存在于 GitHub 上:https://github.com/EdwardAThomson/psi-demo。 ![截图](https://static.pigsec.cn/wp-content/uploads/repos/cas/2a/2ad4f624683356c8eb44b421272fda7300f6feb203eb517dcf1b5623763448d0.png) ## 功能 - 通过 ristretto255 `from_hash` 进行 hash-to-group(Elligator 2,未知离散对数),H2 密钥派生,以及基于 Blake3 的确定性随机派生。 - 默认使用 Tag 模式:Bob 发送单向 BLAKE3 成员标签,因此最终确定为 O(A) 次哈希查找;authenticated-secretbox 变体仍然可用(`runPSIProtocol`)。 - 传输消息仅包含盲化点和固定大小的标签(或在 secretbox 模式下的认证密文);没有任何明文元素会离开参与方。 - 面向阶段的 PSI API (`psi_protocol`),提供换行符和 JSON 序列化辅助工具。 - `psi_demo`:示例单元的 CLI 演示,打印明文值、序列化 payload 以及各阶段的耗时。 - `psi_server`:提供 `POST /psi` 的 HTTP 服务,返回可直接用于 React 集成的 JSON payload 和耗时指标。 - GoogleTest 套件涵盖辅助函数行为、序列化往返、PSI 流程和错误处理。 - 用于可见性单元格的多级网格编码,镜像原始的 JavaScript 前端。 - 对 Web Worker 友好的 HTTP 层,确保浏览器在运行 C++ PSI 后端时保持响应。 ## 构建 ``` cmake -S . -B build cmake --build build cd build && ctest # run tests ``` ## 运行 CLI 演示 ``` ./build/psi_demo ``` ## 运行 HTTP 服务器 ``` ./build/psi_server ``` # 监听 http://localhost:8080/psi (POST) ## 运行 React 前端 1. 从仓库根目录构建或启动 `psi_server`(见上文)。 2. 在第二个终端中,启动纯 C++ 的 React 演示: cd reference_cpp_only npm install # 仅第一次 npm start 应用将在 http://localhost:3000 打开,并将 PSI 请求代理到 `http://localhost:8080/psi`。要更改后端 URL,请在运行 `npm start` 之前设置 `REACT_APP_PSI_ENDPOINT`,或者在 `public/index.html` 中赋值 `window.__PSI_SERVER_ENDPOINT__`。 3. 如果您需要原始的基于 worker 的回退方案,旧版 JavaScript 演示仍保留在 `reference/` 中。 ## HTTP API ### 请求 ``` POST /psi Content-Type: application/json { "bob_units": [{"id": "u1", "x": 100.0, "y": 100.0}, ...], "alice_units": [{"id": "a1", "x": 150.0, "y": 150.0}, ...] } ``` ### 响应 ``` { "bob_message": {"items": [{"tag": ""}, ...]}, "alice_message": {"items": [{"blindedPoint": ""}, ...]}, "bob_response": {"items": [{"transformedPoint": ""}, ...]}, "intersection": ["450 450", ...], "timings_ms": { "bob_setup": , "alice_setup": , "bob_response": , "alice_finalize": } } ``` ## React 集成草图 ``` async function runPsi(bobUnits, aliceUnits) { const res = await fetch('http://localhost:8080/psi', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ bob_units: bobUnits, alice_units: aliceUnits }) }); if (!res.ok) throw new Error('PSI request failed'); return res.json(); } ``` ## 威胁模型 该协议针对诚实且好奇的参与方是隐私的。恶意参与方可以伪造其输入集,并将该协议用作成员资格预言机:它可以得知其选择探测的任何元素是否存在于诚实参与方的集合中,而诚实参与方无法区分探测行为与真实输入。集合的基数也会从消息数量中泄露。将输入绑定到先前的承诺(争议解决)以及将集合填充到固定大小的功能已在 `ROADMAP.md` 中追踪。 ## 报告与文档 - `reports/psi_demo_report.md`:包含 payload 和耗时的 CLI 示例运行。 - `reports/progress_2025-10-16.md`:每日进度摘要。 - `docs/porting_plan.md`:路线图、里程碑和 API 参考。 ## 前端变体 - `reference/`:旧版 React 演示,带有自动的 JavaScript worker 回退。 - `reference_cpp_only/`:纯 C++ 的 React 演示,通过轻量级 Web Worker 将 PSI 请求转发到后端,在 UI 中展示服务器耗时,并拒绝回退到原始的浏览器实现。 ## 许可证 有关上游库各自许可证的信息,请参阅它们(libsodium、Blake3 C 实现)。
标签:Bash脚本, C++, Ristretto255, Web服务, 密码学, 手动系统调用, 数据可视化, 数据擦除, 私密集合求交, 隐私计算