區塊鏈技術系列(2) - 環形簽名
在密碼學中,環簽名是一種數字簽名,其可以由每個具有密鑰的一組用戶的任何成員完成。因此,使用環簽名簽名的消息由特定人群中的某一人簽署。環簽名的一個安全屬性是若要確定哪個組成員的密鑰用於產生簽名在計算上是不可行的。環簽名與群簽名類似,但在兩個關鍵方面有所不同:
- 無法撤銷單個簽名的匿名性;
- 任何用戶組都可以作為一個組使用,無需額外設置。
環簽名技術由Ron Rivest, Adi Shamir, 和 Yael Tauman發明的,於2001發表出來的。環簽名得名於其環狀結構簽名算法。
對於區塊鏈方面多技術,我還是建議大家多看英文文檔,多利用Google來搜索技術文章。
怎麽搭建自己專屬V-P-N來訪問Google,請看我之前發的文章: 新人如何快速搭建自己的個人網站以及自己專屬V-P-N代理
定義
假設有一組用戶,每個人都有公鑰和私鑰對,(P1, S1), (P2, S2), ..., (Pn, Sn)。用戶i可以基於消息m計算一個環簽名σ ,輸入參數為(m, Si, P1, ..., Pn)。如果給定參數σ, m以及所有的公鑰(P1, ..., Pn),任何人都可以檢查該環簽名的合法性。如果環簽名是正確的,那麽它應該可以通過剛才的驗證。另外,如果沒有當前用戶組中任何一個用戶的私鑰,任何人應該是不太可能基於任何組消息來創建一個合法的環簽名。
環簽名滿足的性質
-
無條件匿名性:攻-擊-者者無法確定簽名是由環中哪個成員生成,即使在獲得環成員私鑰的情況下,概率也不超過1/n。
-
正確性:簽名必需能被所有其他人驗證。
- 不可偽造性:環中其他成員不能偽造真實簽名者簽名,外部攻-擊-者者即使在獲得某個有效環簽名的基礎上,也不能為消息m偽造一個簽名。
環簽名實現:
(1)密鑰生成。為環中每個成員產生一個密鑰對(公鑰PKi,私鑰SKi)。
(2)簽名。簽名者用自己的私鑰和任意n個環成員(包括自己)的公鑰為消息m生成簽名a。
(3)簽名驗證。驗證者根據環簽名和消息m,驗證簽名是否為環中成員所簽,如果有效就接收,否則丟棄。
Python實現樣例
import os, hashlib, random, Crypto.PublicKey.RSA class ring: def __init__(self, k, L=1024): self.k = k self.l = L self.n = len(k) self.q = 1 << (L - 1) def sign(self, m, z): self.permut(m) s = [None] * self.n u = random.randint(0, self.q) c = v = self.E(u) for i in (range(z+1, self.n) + range(z)): s[i] = random.randint(0, self.q) e = self.g(s[i], self.k[i].e, self.k[i].n) v = self.E(v^e) if (i+1) % self.n == 0: c = v s[z] = self.g(v^u, self.k[z].d, self.k[z].n) return [c] + s def verify(self, m, X): self.permut(m) def _f(i): return self.g(X[i+1], self.k[i].e, self.k[i].n) y = map(_f, range(len(X)-1)) def _g(x, i): return self.E(x^y[i]) r = reduce(_g, range(self.n), X[0]) return r == X[0] def permut(self, m): self.p = int(hashlib.sha1(‘%s‘ % m).hexdigest(),16) def E(self, x): msg = ‘%s%s‘ % (x, self.p) return int(hashlib.sha1(msg).hexdigest(), 16) def g(self, x, e, n): q, r = divmod(x, n) if ((q + 1) * n) <= ((1 << self.l) - 1): rslt = q * n + pow(r, e, n) else: rslt = x return rslt
簽名並驗證兩個由4個用戶組成的環簽名消息:
size = 4
msg1, msg2 = ‘hello‘, ‘world!‘
def _rn(_):
return Crypto.PublicKey.RSA.generate(1024, os.urandom)
key = map(_rn, range(size))
r = ring(key)
for i in range(size):
s1 = r.sign(msg1, i)
s2 = r.sign(msg2, i)
assert r.verify(msg1, s1) and r.verify(msg2, s2) and not r.verify(msg1, s2)
Go語音的實現版本請參考 --> 用Go語言實現環簽名的簽名和驗證
對於區塊鏈方面多技術,我還是建議大家多看英文文檔,多利用Google來搜索技術文章。
怎麽搭建自己專屬V-P-N來訪問Google,請看我之前發的文章: 新人如何快速搭建自己的個人網站以及自己專屬V-P-N代理
區塊鏈技術系列(2) - 環形簽名