C++ 隨機數生成庫引發安全性與效能權衡的激烈爭論

BigGo Editorial Team
C++ 隨機數生成庫引發安全性與效能權衡的激烈爭論

一個採用 WELL(Well Equidistributed Long-period Linear)生成器的新 C++ 隨機數生成庫在程式設計社群中引發了激烈討論,爭論焦點是密碼學安全的隨機數生成器是否應該成為所有應用程式的預設選擇。

這個專注於高效能偽隨機數生成的庫具有跨平臺可重現性和最佳化分佈演算法等特性,現已成為軟體開發中安全性與效能更廣泛哲學辯論的中心。

WELL 生成器系列比較

  • WELL44497b 與 WELL19937a 在不同程式語言的 TestU01 測試中顯示出"相反"的結果
  • 狀態空間大小最佳化主要取決於 TBit 和 MASK 值
  • 附加引數(K、J)提供約束條件,但對測試套件效能沒有顯著影響

安全優先論點遭遇強烈反對

最具爭議的觀點之一來自一位開發者,他認為非加密隨機數生成器的使用場景微乎其微,並建議所有隨機數生成都應預設採用密碼學安全方式。這一立場主張使用像 Randen 這樣提供可證明安全保證的演算法,但遭到了社群的強烈抵制。

批評者迅速指出了這種方法帶來的巨大效能影響。多位開發者強調,包括科學計算、神經網路、模擬、遊戲、渲染、天氣建模、核研究、機器人技術和訊號處理在內的眾多行業需要快速生成數十億到數萬億個隨機數。對於這些應用來說,密碼學安全生成器的開銷將是令人望而卻步的。

安全考慮

  • ChaCha CSPRNG 實現可能存在種子熵不足的問題(32-64位)
  • 輸出流在 2^32 個塊後會迴繞,可以進行擴充套件
  • Randen 演算法基於 AES 原語提供可證明的安全性
  • Linux vDSO getrandom() 提供快速的密碼學安全隨機數(2024年7月合併)

API 設計理念引發技術討論

對話還深入探討了基本的 API 設計原則,特別是圍繞種子機制的問題。開發者們就便利函式是否應該允許手動播種還是始終使用熵源進行了辯論。討論揭示了向後相容性與安全性改進之間的經典矛盾,並提到了像 glibc 的 rand() 函式這樣的遺留系統如何因為 API 契約而仍然使用過時演算法。

一個有趣的技術解決方案建議使用執行緒本地儲存來同時提供便利性和適當的播種,展示了現代 C++ 特性如何解決傳統隨機數生成挑戰。

效能宣告引發質疑

該庫的效能基準測試顯示某些生成器執行速度達到標準庫效能的100-105%,這讓經驗豐富的開發者感到懷疑。一些人質疑這些資料的可信度,而另一些人則關注更實際的問題,如該庫處理浮點數生成和跨平臺一致性的方法。

討論還涉及了新興的核心級解決方案,如 Linux 的 vDSO getrandom(),它提供對密碼學安全隨機數的快速訪問,儘管開發者指出對於高吞吐量應用來說,這仍然比專用偽隨機生成器慢得多。

效能對比宣告

  • std::minstd_rand:100% 基準效能
  • std::mt19937:基準效能的 105%
  • 該庫聲稱在跨平臺序列一致性方面提供更快的均勻分佈和正態分佈
  • 針對遊戲和模糊測試應用,使用基於 popcount 的二項式近似實現快速正態分佈

結論:具體情況具體分析

這場辯論最終強化了軟體開發中的一個關鍵原則:為工作選擇合適的工具。雖然密碼學安全生成器對於安全敏感的應用程式至關重要,但絕大多數隨機數使用場景——科學計算、遊戲和模擬工作——需要專用偽隨機生成器提供的速度和確定性。

「為工作選擇合適的工具。拓寬你對事物用途的認知。」

這次討論突出了不同領域有著截然不同的需求,總是使用密碼學安全生成器的一刀切建議無法滿足程式設計社群的多樣化需求。

參考:well-random