iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0

本日重點:ht_sign、xmss_sign 和 KAT rng.c

ht_sign 的 input 有 SK.seed, PK.seed,這兩個都必須要透過 approved RBG 產生亂數,因為還沒有把 CC310/CC312 整合進來,同時也因為簽章後會使用 Known Answer Tests (KAT) 比對簽章結果,所以乾脆就先用 KAT 的 rng.c 取代目前取亂數的function。

NIST 會提供 KAT,壓縮檔包括 rng.c

換成 KAT 的 rng.c 之後,compile 的時候發現他依賴 openssl
https://ithelp.ithome.com.tw/upload/images/20250927/20140129xC90i8Nbvo.png
這樣我在 nrf52840 就沒辦法用 KAT rng.c,雖然我還是能在 x86 上跑,但我不想要這樣的結果,我還是希望 nrf52840 和 nRF5340 都能用 KAT rng.c,所以我把 openssl 的依賴換掉,因此我要提供一份 AES256_ECB 的 source code。

除此之外,要在 KAT rng.c 裡把兩個 function (handleErrorsAES256_ECB) 予以 comment。

這裡我直接讓 chatGPT 產生 AES256_ECB 的 source code,畢竟這是用於 KAT,未來也會走 approved RBG,所以不在這裡花太多時間重造輪子。

AES256_ECB 的 implementation 我放在 kat 之下,然後修改 Makefile

# Only use KAT rng.c when make KAT_RNG=1
ifeq ($(KAT_RNG),1)
  RNG_SRC := kat/rng.c kat/kat_rng.c kat/aes256.c
else
  RNG_SRC := $(PLATFORM)/rng.c
endif

make KAT_RNG=1 就是用 KAT 的 rng.c

相關原始碼參考 連結

ci.yml 也要改,暫時把 x86、nrf52840 和 nRF5340 都用 KAT_RNG=1

jobs:
  build-and-test:
    ...
    steps:
    ...
      - name: Build x86, then run
        run: |
          make TARGET=x86 KAT_RNG=1

      - name: Build nrf52840
        run: |
          make TARGET=nrf52840 NRFXLIB_DIR="${NRFXLIB_DIR}" KAT_RNG=1

      - name: Build nRF5340 DK
        run: |
          make TARGET=nrf5340dk NRFXLIB_DIR="${NRFXLIB_DIR}" KAT_RNG=1

然後,GitHub Actions 能看到取亂數的結果。由於 x86、nrf52840 和 nRF5340 的 rng_bytes 都是一個空的 implementation,所以能取得亂數就表示目前是用 KAT rng.c
https://ithelp.ithome.com.tw/upload/images/20250927/20140129wEHZfRTiNb.png

再看一次 ht_signxmss_node 的演算法
https://ithelp.ithome.com.tw/upload/images/20250927/20140129l6QsAb3wub.png

https://ithelp.ithome.com.tw/upload/images/20250927/20140129DC64fLtxEX.png

xmss_sign 的 line 2 就是 idx 除以 (2^j),然後取整數,最後 XOR 1,就是 (idx >> j) ^ 1u,所以xmss_sign 的程式大概是這樣 (在 SLH-DSA-SHA2-128s 的參數集,h' = 9)

void xmss_sign(uint8_t out[704], 
               const uint8_t M[16], 
               const uint8_t sk_seed[16], 
               unsigned int idx,
               const uint8_t pk_seed[16],
               const uint8_t adrs[32])
{
    // h` = 9
    uint8_t auth[9][SPX_N];
    
    for(int j = 0; j < 9; ++j)
    {
        unsigned int k = (idx >> j) ^ 1u;
        xmss_node(auth+j, sk_seed, k, j, pk_seed, adrs);
    }
    set_type_and_clear(adrs, WOTS_HASH);
    set_key_pair_addr(adrs, idx);

    // size of sig is len * n bytes
    // len = 35, for SLH-DSA-SHA2-128s
    wots_sign(out, M, sk_seed, pk_seed, adrs);

    // out ← WOTS+ signature ∥ AUTH
    memcpy(out + 35, (uint8_t *)auth[0][0], sizeof(auth)); 
}

memcpy(out + 35, ... 這裡的 35 是這樣算出來的,參考 FIPS 第 17 頁

len = len1 + len2 = 32 + 3 = 35

https://ithelp.ithome.com.tw/upload/images/20250927/201401293widJCRB8f.png

ht_sign 是在 slh_sign_internal 裡被呼叫,我想準備一組input來測 ht_sign,所以我們再一次的來看 slh_sign_internal 會傳什麼給 ht_sign
https://ithelp.ithome.com.tw/upload/images/20250927/20140129bxRYJpOkUf.png

algorithm 19 的 line 3 (PRF_msg) 和 line 5 (H_msg),這兩個 function 的定義在第 45、46 頁
https://ithelp.ithome.com.tw/upload/images/20250927/20140129TmB7DzzDdj.png

PRF_msgH_msg 的產出最終會成為 ht_sign 的最後兩個參數 idx_tree、idx_leaf,其中會用到 HMAC-SHA-256、MGF1-SHA-256 的計算,HMAC-SHA-256、MGF1-SHA-256我們明天再說

References

  1. FIPS 205 Stateless Hash-Based Digital Signature Standard

上一篇
Day 13 Implements ht_sign
下一篇
Day 15 產生 hypertree signature: HT signature, XMSS signature 和 WOTS+ signature
系列文
裸機實作 SLH-DSA 簽章:FIPS 205 之演算法實作、測試、防禦與跨平台15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言