iT邦幫忙

2025 iThome 鐵人賽

DAY 1
0
Security

裸機實作 SLH-DSA 簽章:FIPS 205 之演算法實作、測試、防禦與跨平台系列 第 1

Day 1 序篇: 裸機實作 SLH-DSA 簽章的幾個面向

  • 分享至 

  • xImage
  •  

探討如何在裸機實作 SLH-DSA 的簽章演算法,並實現原始碼層級的跨平台。

NIST 在2024年8月13日發佈了 FIPS 205 [1],它規範了 SLH-DSA 的演算法,其前身就是 SPHINCS+ [2]。本系列的重點不在於後量子密碼學本身,而是 如何在裸機的環境下實作 SLH-DSA 簽章。會依照 FIPS 205 描述的演算法,搭配學習 SPHINCS+ 官方的 reference code [3],然後在裸機下用 C 實作簽章。

v20250831-001-alpha 這是 2025/08/31 我建的tag, 這一版雖然能簽章, 但簽出來的是錯的, 該版有 98%以上的原始碼是由 ChatGPT 產生, 然後由我人工進行 debug、測試與整合

我將接續著 tag v20250831-001-alpha 的版本繼續做延伸開發,一開始 SHA2 和 取亂數 都會是軟體來完成,不會用硬體加速 SHA2 也不會用硬體取亂數。在往後的幾天就會將 SHA2 和 取亂數 從軟體改成由 CryptoCell-310 [4] 和 CryptoCell-312 [5] 來實現。基於跨平台的考量,會增加一個抽象層, 每次更換平台, 只要提供硬體相關的程式碼,然後重新 編譯 -> 產生亂數 -> 產生金鑰,就能在不需要修改程式的情況下,實現原始碼層級的跨平台。

這些實驗構成了 裸機實作跨平台 SLH-DSA 簽章 的基礎,然後我將在此基礎上探討開發一個 PQC dongle 會有哪些相關的標準與實作,並且進行低成本的實驗與測試。

這些實驗將會在 Renode、nRF52840 dongle 和 nRF5340 DK 上進行,由於 nRF5340 DK 有 secure zone,所以也會進行 secure zone 上的實驗。主要的流程是在 nRF52840、nRF5340 上簽章,然後在 PC 或 Android 上驗章,或者只比對 KAT (Known Answer Tests) [6]。初期基於開發的方便,是直接在 GitHub 上用 CI 執行 Renode,然後在 Renode 上進行 nRF52840 的裸機模擬。等 SLH-DSA 簽章的演算法實作完成後,就會到 nRF5340 DK 和 nRF52840 dongle 上進行真實版子的實驗。

SPHINCS+ 有參考的官方實作碼 [3],我想試試自己寫一版並讓他支援 CryptoCell-310 和 CryptoCell-312,所以參考官方的 reference code 另外寫一個版本。SPHINCS+ 提出了 36 個 instances,而 NIST FIPS 205 只 approve 其中的 12 個 (全是 simple,沒有 robust)。這 30 天我會把重點放在其中的 SLH-DSA-SHA2-128s,這樣 parameter set 就會相對單純,而只實作 SHA2 是因為 SHA2 方便整合 CryptoCell-310、CryptoCell-312。

除了依照 FIPS 205 描述的 SLH-DSA 演算法去實作,我也會將過程中發現值得注意的細節做一些整理。雖然 ChatGPT 也能做這件事,但一看到這句話 “ChatGPT 可能會出錯。請查核重要資訊”,讓我覺得分享自己整理過、驗證過的資訊,還是有參考價值的。

FIPS 205 的演算法有 25 個,簽章佔了 21 個。21 個演算法看起來很多,但其實有一半以上是呼叫重複出現的 function,尤其是 ADRS 的 member function 和 toByte,所以只要先完成這幾個常用 function (大約10個),很快就能把簽章的程式寫完。舉例來說,FIPS 205 第 18 頁的 Algorithm 6 wots_pkGen,它的演算法如下

Algorithm 6 wots_pkGen(SK.seed, PK.seed, ADRS)
Generates a WOTS+ public key.
Input: Secret seed SK.seed, public seed PK.seed, address ADRS.
Output: WOTS+ public key 𝑝𝑘.
1:  skADRS ← ADRS ▷ copy address to create key generation key address
2:  skADRS.setTypeAndClear(WOTS_PRF)
3:  skADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
4:  for 𝑖 from 0 to 𝑙𝑒𝑛 − 1 do
5:      skADRS.setChainAddress(𝑖)
6:      𝑠𝑘 ← PRF(PK.seed, SK.seed, skADRS)          ▷ compute secret value for chain 𝑖
7:      ADRS.setChainAddress(𝑖)
8:      𝑡𝑚𝑝[𝑖] ← chain(𝑠𝑘, 0, 𝑤 − 1,PK.seed,ADRS)   ▷ compute public value for chain 𝑖
9:  end for
10: wotspkADRS ← ADRS        ▷ copy address to create WOTS+public key address
11: wotspkADRS.setTypeAndClear(WOTS_PK)
12: wotspkADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
13: 𝑝𝑘 ← T𝑙𝑒𝑛(PK.seed, wotspkADRS, 𝑡𝑚𝑝)        ▷ compress public key
14: return 𝑝𝑘

這 14 行裡面就有 6 行是呼叫 ADRS 的 member function,這 6 個 member function 也經常出現在 FIPS 205 裡的各個 algorithms 裡,所以在 Day 2 會探討 ADRS member function 的實現。

NIST 有提供程式用來產生 PQCsignKAT_64.rsp,SPHINCS+ 在 round 3 的 submission 也有包括它,可以到這 Download 3rd round NIST submission package (zip) 下載。我們把簽章的程式寫完後也會用 NIST 提供的程式產生 PQCsignKAT_64.rsp,透過一個 byte 一個 byte 的比對,來確保我們的簽章結果和官方的一致。

至此, 我大概把 30 天鐵人賽涉及的範圍做了一個概括的說明,明天將說明 ADRS member function 以及如何產生 SLH-DSA 金鑰。

References

  1. FIPS 205 Stateless Hash-Based Digital Signature Standard
  2. https://sphincs.org/index.html
  3. The SPHINCS+ reference code, accompanying the submission to NIST's Post-Quantum Cryptography project
  4. CRYPTOCELL — Arm TrustZone CryptoCell 310
  5. CRYPTOCELL — Arm TrustZone CryptoCell 312
  6. PQC – Known Answer Tests and Test Vectors

下一篇
Day 2 跨平台產生 SLH-DSA 金鑰 (一)
系列文
裸機實作 SLH-DSA 簽章:FIPS 205 之演算法實作、測試、防禦與跨平台5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言