畢業設計裏用到了一些密碼學的知識,在博客做個記錄。
祕密共享
祕密共享(Secret Sharing),如其名,是一種用來共享祕密的技術。理解這個技術,首先需要把意義搞清楚,然後瞭解技術實現原理,最後用工具實現一個demo。
共享的意義
一個祕密信息,必然有其最初的持有者,也即發佈者。發佈者具有祕密的使用權和共享權,即他有權利將祕密分享給別人。但這裏存在一個問題:如何保證這個共享過程是安全的?
傳統的方法,是加密。如對稱加密,雙方用約定的密鑰進行加密解密通信——但也有一個問題:如何安全傳遞密鑰?總是需要有一個最初“絕對安全”的信道。非對稱加密解決了這個矛盾,發佈方自己生成公私鑰對,通過公開公鑰,用私鑰加密、公鑰解密,無需事先約定。
非對稱加密解決了絕大部分加密的問題,目前廣泛應用的RSA就是明證。但其實它依賴了一個潛在假設(雖然這個假設很接近現實):公開環境是一個誠實信道,它不會篡改發佈的共享信息。否則,中間人攻擊就會破獲祕密。
假設這樣一個場景:發佈者A與接受者B之間存在N條獨立信道,在不清楚各信道信任度和穩定度的情況下,A如何將信息發送給B?祕密共享應運而生。它通過某種方法將祕密拆分,從N個信道同時發送,即使有信道存在惡意者,也無法恢復祕密。
在實際應用中,祕密共享常用於密鑰的分佈式存儲,將一個密鑰拆分後多地存儲,分散風險,等到需要用的時候再聚合到一起。
共享原理
形式化定義如下:
其中s表示需要拆分的祕密,t表示恢復門限,n爲拆分數目。
存在恢複函數,對於任意有。
shamir算法
shamir是一種祕密共享的實現1,利用了拉格朗日插值公式2。詳細原理見參考文獻。
下面補充一個shamir算法的有用的性質:加同態。
已知已有兩個用於祕密共享的多項式、以及素數。通過祕密共享分享的分片形式是,。
將分片中的多項式結果求和,得到。
根據shamir算法中的定義, 是原祕密。因此通過恢復算法對求和後的分片進行恢復,將會得到。這就實現了祕密求和。在雙方求和的情況下,沒有意義,但在參與者數目大於等於3時,就會有用。
下面的demo將會演示這個過程。
實現應用
github上有對shamir算法的實現3,這裏直接借用實現一個拆分求和後恢復的過程。
from secretsharing import secret_int_to_points, points_to_secret_int
from secretsharing import primes
p = primes.get_large_enough_prime([100000])
n_frac = 3
n_rcvr = 2
// 拆分
def ss(n):
return secret_int_to_points(n, n_rcvr, n_frac, p)
// 恢復
def recover(s):
return points_to_secret_int(s, p)
// 對祕密求和
def secret_sum(s1, s2):
return [(i+1, (s1[i][1]+s2[i][1])%p) for i in range(3)]
>>> sh = seret_sum(ss(123),ss(234))
>>> recover(sh)
357
後記
本來寫了一堆原理,結果沒保存點了發佈,發現已經掉線,全沒了,心累。算了,參考文獻裏寫的也很詳細了。
https://github.com/blockstack/secret-sharing ↩︎