數位簽章的 sign 和 verify 裡面都有把訊息(message)雜湊(hash)起來的雜湊函式。雜湊函數(hash functions)與資料完整性(data integrity)可以怎麼理解?
雜湊函數可以說是資料的「指紋」(fingerprint)。把一大筆資料映射(mapping)到固定的大小。不同的區塊鏈可能用不同的 hash function。以太坊區塊鏈技術採用的 hash function 是 keccak256,他的 hash 值是固定大小 32 byte。
以太坊區塊鏈中很多地方都需要 hash functions。例如,區塊需要 hash 起來,通常會叫 block hash,也就是整個區塊資料的雜湊值。把整個區塊當成 hash function 的 input,他的 output 就是 block hash。又或是以太坊交易需要 hash 起來,交易有 transaction hash,在 Etherscan 上看到的 Transaction Hash 就是整筆交易資料的雜湊值。常聽到的 merkle trie,就是由 hash function 組合而成的一棵樹。
如果暫時不談區塊鏈,一般的雜湊函數的用途,可以搭著數位簽章用。舉例來說,想像今天有 1 GB 的資料要做數位簽章,如果沒有雜湊函數的話,要做數位簽章很有可能會跑不完。但如果今天我有雜湊函數,1 GB 的資料要做數位簽章,那麼我們只要對著 1 GB 的資料的 hash 值,也就是這個固定的大小,例如 32 byte,做數位簽章即可,這就會是幾乎瞬間就跑完數位簽章。也就是只要對著這筆資料的指紋做簽章。
網路上看到有美國人學生在學雜湊函數時,表示不太能理解 hash 這個詞,為什麼把資料變小,資料壓縮成摘要,把資料的格式固定下來,這件事要叫 hash。英文的 hash 可以說是從法語來的,法文動詞「hacher」是料理及食物相關用詞,意思是 to chop 或 to cut into small pieces,指把食物切碎,剁碎,搗碎。動詞變化現在式 je hache, tu haches, il/elle hache, nous hachons, vous hachez, ils/elles hachent。複合過去式 j'ai haché。
例如,把牛肉剁碎,變成牛肉碎肉,形容詞的用法。牛絞肉 Viande hachée(陰性的詞字尾加 e)( https://fr.wikipedia.org/wiki/Viande_hach%C3%A9e )、牛肉漢堡排 Steak haché( https://fr.wikipedia.org/wiki/Steak_hach%C3%A9 )。
因此這裡用詞的命名,個人認為可以看作是一種比喻,把「資料」比喻成廚房裡的牛肉食材,需要切塊、攪碎,就像是把資料打亂一樣。而經過雜湊後的資料,碎碎的牛絞肉,不能被逆推回來,原始是從哪一塊大牛肉塊來的。
不知道運用這個比喻,創造一些生動的下廚做菜想像畫面,是否會增加記憶點或有加強理解嗎?剛才拍了這張照片,想表現深夜查字典比賽,快速翻到 h 就會找到「hacher」。他有寫「to chop」。隨手翻閱確認一下。這本 Collins and Le Robert 字典,閒逛加拿大的書店很容易看到也很容易想買。是一本九塊加拿大幣就能輕鬆買到的口袋版的法英字典。
雜湊函數其中一個關鍵性質是 collision resistance( https://en.wikipedia.org/wiki/Collision_resistance ) 。雜湊函式就像資料指紋的意思是,每個人的指紋都長得不同。不會有撞指紋的情形。兩個不同的人,不會有一樣的指紋的「撞」。換句話說,兩筆不同的資料,卻有同樣的 hash 值,這樣就是雜湊碰撞 collision。
以區塊鏈交易舉例,「我要給馬來西亞朋友 100 塊錢」這筆交易資料訊息,通過雜湊函式 hash function 產生固定的大小 32 byte。地球的另一端,有個住在山洞裡的陌生網友,他時間很多,一個一個找到另外一個訊息「我要給住在山洞裡的陌生網友 100 塊錢」,而他找到的這個交易訊息剛好和「我要給馬來西亞朋友 100 塊錢」這個訊息,有一模一樣的 32 byte 的 hash 值。山洞裡的陌生網友可以在過程中,路上攔截調包原始交易資料訊息,偷偷抽換掉訊息,把本來要給馬來西亞朋友的 100 塊錢變成反而要給完全不認識的,住在山洞的奇怪網友 100 塊錢。如果我用了一個不安全的 hash function 去搭數位簽章,那麼這個數位簽章也會變得不安全,數位簽章也就沒辦法代表我到底同意了第一筆交易資料還是第二筆,另外要冒出來撞指紋的資料。
這裡的結論是,資料的指紋不能撞。我對某筆資料的指紋簽章,就代表我對那一筆資料簽章,不能出現有另外一筆資料也有全然一模一樣的指紋。也就是說,這一個雜湊 hash value,世界上只能映射(mapping)到一個資料指紋。比喻來想,就像是訂單編號一樣。一個訂單編號只能對這一筆訂單。hash function 確保不一樣的資料,即使是只差一個空白鍵,只差一丁點,這個單號就會變得超級不一樣,確保資料的完整性(data integrity)。並且也不能從單號逆推 hash value 回到原本的 data,不可逆推的性質(preimage resistance)。
維基百科參考資料:
https://en.wikipedia.org/wiki/Cryptographic_hash_function
https://en.wikipedia.org/wiki/Data_integrity
https://en.wikipedia.org/wiki/Collision_resistance
https://en.wikipedia.org/wiki/Preimage_attack
https://en.wikipedia.org/wiki/Birthday_problem
https://en.wikipedia.org/wiki/Pigeonhole_principle