區塊鏈加密技術之環簽名(2)

隱私是用戶最關心的問題之一,也是 PPIO 研究的重點。區塊鏈世界涉及隱私保護的技術很多,前不久 PPIO Code Talks 的李星老師 給我們分享的“零知識證明 zk-SNARKs”技術 就是 隱私保護的典型代表,今天我們再來分析一下另一個用於隱私保護的技術——環簽名 Ring Signature。

零知識證明解決的問題是,我有一個祕密,我需要向你證明我知道這個祕密,但是我又不能讓你知道這個祕密。而環簽名解決的問題是,我對你說了一句話,但是你只知道是某一羣人中有人對你說了這句話,而不知道這羣人裏具體哪個人說的。簡言之就是,我把自己藏進了人羣裏。環簽名通過將實際簽名者的公鑰藏進一個公鑰集合,來達到保護簽名者身份的目的。

環簽名(Ring Signature)方案由 Rivest,Shamir 和 Tauman 三位密碼學家 於2001年首次提出。環簽名也被稱爲 CryptoNote,由羣簽名演化而來,典型的應用案例是門羅幣。羣簽名是利用公開的羣公鑰和羣簽名進行驗證的方案,其中羣公鑰是公開的,羣成員可以生成羣簽名,驗證者能利用羣公鑰驗證所得羣簽名的正確性,但不能確定羣中的正式簽名者。可是羣管理員可以撤銷簽名,揭露真正的簽名者羣簽名,這是羣簽名的關鍵問題所在。

環簽名方案則去掉了羣組管理員,不需要環成員之間的合作,簽名者利用自己的私鑰和集合中其他成員的公鑰就能獨立的進行簽名,集合中的其他成員可能不知道自己被包含在了其中。這種方案的優勢除了能夠對簽名者進行無條件的匿名外,環中的其他成員也不能僞造真實簽名者簽名。外部攻擊者即使在獲得某個有效環簽名的基礎上,也不能僞造一個簽名。

那麼環簽名是如何做到這點的呢?接下來我們用橢圓曲線來舉例說明環簽名的具體技術關鍵點和原理。

環簽名生成過程

假設簽名者擁有某私鑰 sk 和公鑰 pk(爲表述方便,下文中所有粗體表示橢圓曲線上的點),其中 pk = sk·g,這裏 g 是 橢圓曲線上的 基點(base point),也被稱爲生成元(generator)。而 “·” 這裏是倍乘,sk·g 表示 sk 個 g 點在橢圓曲線上進行加法運算。更多關於橢圓曲線密碼學相關的知識,可以參見 PPIO 的另一篇文章《橢圓曲線密碼學》。

· 首先,先定義一個 hash 函數,這個 hash 函數的輸入是 待簽名的消息 m 和 橢圓曲線上的一個點 A,即 Hash(m, A)。該 hash 函數和橢圓曲線一樣,是這個簽名和驗籤體系的前提。

該 hash 函數的一個參考實現爲:將 m 和 A 的字節數據拼接,然後用傳統的 hash 函數(如keccak256),得到的值再對 N 取模(這裏的 N 是橢圓曲線上有限羣的階)。

· 接下來 ,簽名方想對一消息 m 進行簽名,但是又不想在公開簽名的同時,讓別人知道自己的確切身份,因此 簽名方 決定用環簽名的方式將自己藏到一羣人中。於是 簽名方 找來 n-1 個其他人的公鑰(這些公鑰最好之前在系統中已經出現過和使用過,不然 簽名方 藏在一堆新人中,還是會很容易的被識別出來),並編好序號,並將自己的公鑰隨機地插入其中,共同組合了一個包含 n 個公鑰的集合。不妨假設這 n 個公鑰爲

pk0, pk1, pk2, …, pki-1, pki, pki+1, …, pkn-1

其中 pki 爲簽名方的公鑰。

· 然後,簽名方隨機生成 n-1 個隨機數 s0, s1, …, si-1, si+1, …, sn-1, 分別與除 pki 以外的 n-1 個公鑰一一對應。

注意:這一步無需隨機生成 si,因爲 si 會在後面通過計算得到。

· 接着,簽名方隨機生成 k, 並計算 k·g, 這裏我們先假設

k·g = si·g+ci·pki (等式①)

這裏 等式① 的用途暫時可能不太好理解,但可先不用管。但根據 等式① 我們可以確定的是,如果擁有 pki 的私鑰 ski,且如果已知 ci 和 k,那就可以反向求出 si。

注意:這裏的 ci 是根據上一個公鑰 pki-1 和消息 m 計算出的 hash 值

· 接下來引入第2個式子,

cx = Hash(m, sx-1·g+cx-1·pkx-1) (等式②)

等式② 是一個遞推式,且 Hash 函數的第二個參數形式上跟 等式① 的右側是一樣的。這個遞推式的意思是:已知第 x-1 個公鑰對應的 sx-1 和 hash 值 cx-1,求下一個公鑰對應的 hash 值 cx。注意,當 x=0 時,x 的上一個其實是 n-1,因爲下標也要對 n 取模。

· 由於在 等式① 中我們定義了 k·g = si·g+ci·pki 所以 ci+1 可直接由計算得到

ci+1 = Hash(m, si·g+ci·pki) = Hash(m, k·g)

注意:此時求 ci+1 過程中我們暫時並不知道 si 和 ci,但後面計算得到 ci 後,可以由 k, ci+1 和 ci 求出 si。

緊接着,依次計算 ci+2, … , cn-1, c0, …, ci-1, ci: (如圖 1)

ci+2 = Hash(m, si+1·g+ci+1·pki+1)

...

cn-1 = Hash(m, sn-2·g+cn-2·pkn-2)

c0 = Hash(m, sn-1·g+cn-1·pkn-1)

c1 = Hash(m, s0·g+c0·pk0)

ci = Hash(m, si-1·g+ci-1·pki-1)

 

圖 1 計算 ci+1, … , cn-1, c0, …, ci-1, ci 過程 · 有了 ci之後,回頭觀察等式① ,由於 pki 的私鑰是已知的,即

pki = ski·g

因此 等式① 可寫成

k·g = si·g+ci*ski·g

兩邊約去 g,變爲

k = si + ci*ski

從而根據 k,ci,ski 可以求出 si (如圖 2)即

si = k - ci*ski

注意:私鑰 ski 在這裏發揮了作用,如果沒有 ski,si也無法求出。

圖 2 根據私鑰 ski, k, ci求解 si 過程 · si 一旦求出後,環簽名的環就形成了。而且此時 k 值的使命也已完成,可以被拋棄掉了。

換句話說,正因爲我們擁有私鑰 ski, 所以可以構造出一個 si,配合隨機生成的s0, s1, …, si-1, si+1, …, sn-1,使得以下式子都成立:

c0 = Hash(m, sn-1·g+cn-1·pkn-1)

c1 = Hash(m, s0·g+c0·pk0)



cn-1 = Hash(m, sn-2·g+cn-2·pkn-2)

反之,如果這 n 個公鑰中的任何一把私鑰 簽名者都沒有,那麼他也就無法求出 si 使得{c0, pk0, …. pkn-1, s0, …., sn-1}形成一個 環。

因此,如果上述 n 個等式成立,那麼也有意味着,生成這 n 個等式的人至少擁有這 n 個公鑰中一把私鑰。

· 最後消息 m 的環簽名數據爲:

Signature = {c0, pk0, …. pkn-1, s0, …., sn-1}

簽名驗證過程

驗證者根據 c0, pk0, …. pkn-1, s0, …., sn-1,消息 m 和 等式② 依次求出 c1, c2, …., cn-1, 最後根據 cn-1 求出 c’0,並判斷

c0 ?= c’0

如果相等則簽名有效,如果不等則簽名無效。

應用場景

目前,使用環簽名方案的項目包括門羅幣 Moreno、布爾幣 Boolberry、StealthCoin、XCurrency 等,以太坊平臺也增加了一個類 CryptoNote 環簽名。

門羅幣(Monero):門羅幣是應用環簽名的典型代表,環簽名技術使得門羅被公認爲是一個私密性強,不可追蹤的加密貨幣。環簽名幫助門羅幣實現了交易的隱私性:通過區塊鏈系統中無關節點無法追查交易的發送方,當其它節點驗證交易時,只能確定簽名是諸多公鑰中的一個,卻無從定位到哪個公鑰纔是具體的發送方。

一票否決場景:例如,某協會主席提出一種議案,但如果協會成員中有人提出反對意見則議案需被取消。但投反對票的會員又不想暴露自己的身份,因此他可以用環簽名的技術,將自己的反對票用自己的私鑰和其他協會成員的公鑰進行簽名。簽名之後所有協會成員都可以看到協會中有人反對該項議案,但不知道確切的反對者是誰。

總結

回顧一下簽名的整個過程,關鍵的巧妙點在於,如果知道私鑰 ski,那麼就可以反推出 si,使 c1, c2, …., cn-1 形成一個環。就好像簽名者找了一根鐵絲,數學保證了只有擁有私鑰的人,才能把鐵絲的兩頭接起來,形成鐵絲環。而且一旦成爲鐵絲環之後,環的接點處也沒有任何痕跡,這使得驗證者無法判斷鐵環是在哪個位置上接起來的。

環簽名雖然可以用來做到一定程度的匿名性,不過畢竟真實的簽名者還是會暴露在環中。且在目前的公有鏈市場上,與環簽名相比,零知識證明依然是最佳的匿名方案之一。只是在某些場景下,如果對隱私的要求沒有那麼高,同時簽名方的計算能力又很弱,環簽名不失爲一個不錯的選擇。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章