用Hash證明秘密
假設我知道某個秘密,但現在時候未到還不能講,可是我又想證明「我真的知道喔」,該怎麼做呢?舉例來說,假設我想證明我能預測下一期樂透號碼,但我又不想自己去買,也不想現在告訴大家號碼,該怎麼在開獎後證明我事前真的知道呢?
一個快速能想到的做法是事先拍影片寫下答案,事後才上傳公布。但問題是要怎麼證明影片不是事後拍的?附上時鐘嗎?附上當時的電視新聞台轉播嗎?這些都有造假的可能性存在。
因此,我們想的這個做法必須要滿足:
(1) 這個答案要由我在特定時間公開,我沒公開前不會有人知道
(2) 答案不能被篡改
雖然聽起來可能有點困難,但其實利用大家熟知的 hash 就行了。
假設我宣稱的樂透號碼是 1,4,17,18,25,30 好了,我先隨便訂一個 salt 如 OIZG5NFXZ,接著把它跟答案加在一起變成一個字串:OIZG5NFXZ:1,4,17,18,25,30,然後丟去 hash,得到 3d60…..51ef 這個結果。
接著,我把這個 hash 發到鏈上,基於區塊鏈不可修改的特性,大家可以相信這個字串公佈答案後也改不了,符合了第二點(先不考慮大多數節點被 compromised 或是算力被掌握等情境)。
而因為這是個 hash,假設我的 salt 夠長(上面只是範例所以很短,實際上會很長),除了暴力破解以外,沒有其他人猜得出來原始內容是什麼,因此符合了第一點。
等到樂透開獎以後,我再把 salt 跟號碼公開出去,大家自己把 OIZG5NFXZ:1,4,17,18,25,30 拿去 hash,就會發現是我當天 po 的那個字串,表示我真的事先知道就是這組數字,才有辦法先把 hash 算出來。
(有個例外是「我其實不知道,只是開獎後再找到了含有樂透號碼的字串產生碰撞」,但只要用夠強的 hash 演算法就可以排除這個可能性)
上面講的這些聽一聽有點密碼學的味道對吧,因為它確實就是。這個在密碼學有個專有名詞叫做 Commitment scheme,近代最多的實際應用是在區塊鏈上面,而且有更多種更巧妙的演算法,這部分我不熟,就不繼續講了。
不久後的 9/5~9/7 是 PyCon Taiwan 2025 的日子,議程都已經公佈了,各式各樣的主題都有。
這次有一天的 Sprints 加兩天的 5 軌議程,還有超強 Keynote 講者陣容,包括 FastAPI creator、CPython 核心開發者與前 NBA 76 人隊數據 UX 設計師等等,細節可以看官方議程。
而我這剛好有一張票想要送大家,要讓大家抽獎。但由於我懶得算數量,因此就用猜數字來決定。只要在留言猜 1-30 這個範圍的數字,猜中就直接把票送給你!每人只能猜一次,最早猜中的贏,順序由臉書的「由新到舊」留言排序決定,以我的網頁看到的畫面為主。
08:20 更新:票已經抽掉囉,可以不用留言了。
那大家要怎麼知道我不會黑箱作業,心中的數字不會變呢?上面已經把原理都講完了,只是我們不上鏈,改成用臉書的編輯紀錄當作我不會修改的證明。
hash: 4f98735337f13a56f804c49d055fe348b788f566ec274ac905e89665fe5ed1a6
公佈答案時會附上原始字串讓大家驗證。話說這方法防不了我把答案洩露給別人這件事,這點只能請大家相信我的人品了 😆
08:20 更新:答案是 19
原始字串:PyC0nTaiwan2025!!!the_answer_is:19
評論