流行加密庫中有趣的實現實踐
因此,通過閱讀 go-lang 加密庫的 salsa20 實現,我發現了一些有趣的東西。特別是這部分。這看起來像是我對學習程式的人所期望的。他們編寫了 80 行程式碼,這些程式碼本來可以使用數組和迭代輕鬆完成。查找其他實現我發現了這個非官方的,它確實使用了迭代。看看其他他們都選擇使用循環來完成這部分。但這些都不是官方的。那麼為什麼官方不使用更簡潔但等效的方式呢?
我的問題真的是,在沒有額外數組和循環的情況下做事是否有一些安全優勢?是速度嗎?當你有一個額外的數組和循環時,是否有一些攻擊?
這似乎是Loop Unrolling的一個簡單案例,它是一種通用的軟體優化。加密算法的實現通常是“展開”的,這意味著採用通常進入循環的語句並按照它們發生的順序對它們進行硬編碼。這是一種性能優化:循環計數器需要循環來遞增和比較,以及寄存器空間來執行任何一項(這也可能意味著額外的 MOV 指令)。
所以答案是速度,而不是安全性——循環展開等優化不會改變算法的輸出,它們是一種實現選擇。
很有可能,如果您向 10 個不同的人描述一個算法並要求他們實現它,您將收到同一程序的 10 種不同變體——儘管速度和實現複雜性不同,但它們仍然產生相同的輸出。尤其是在 C 級別,性能往往是以程式碼清晰度為代價的。
從理論上講,這意味著忽略側通道攻擊,實現應該只影響算法的性能,而不是安全性。然而在實踐中,由於潛在的側通道,實現可能會影響安全性,儘管循環展開很可能不是罪魁禍首。如果是這種情況,在算法的輸出中將不會看到缺乏安全性 - 側通道利用僅在實際算法在實踐中物理實現時才存在的資訊,並且通過其他方式提取資訊。
為什麼這不留給編譯器優化
我們不一定喜歡讓編譯器積極優化我們的加密程式碼。- 它可以做一些不太理想的事情。密碼算法通常相對較小且在實現上非常簡單(如果不是在概念上如此),有時直接在 Assembly 中實現以最大化性能或最小化程式碼大小。
循環展開也用於硬體實現。
為什麼在官方實現中會這樣做
官方實現是實際使用人數最多的實現,因此顯然應該是最有效的實現。這實際上只是一種常見的禮貌,因為 CPU 週期需要花費金錢和時間。這不是密碼學特有的,但很可能是一般軟體的情況。
您看到的“非官方”實現可能是由某個學習算法的地方編寫的,對此,清晰度是優先級,而不是效率。