王沛然 李加福 雷志偉 張桂剛 張 勇 邢春曉
(1.清華大學(xué)行業(yè)可信區(qū)塊鏈應(yīng)用技術(shù)聯(lián)合研究中心,計(jì)算機(jī)系,信息技術(shù)研究院 北京 100084)(2.中國(guó)科學(xué)院自動(dòng)化研究所 北京 100190)(3.清華大學(xué)北京信息科學(xué)與技術(shù)國(guó)家研究中心,計(jì)算機(jī)系,信息技術(shù)研究院,互聯(lián)網(wǎng)產(chǎn)業(yè)研究院 北京 100084)
區(qū)塊鏈技術(shù)從Bitcoin發(fā)展到Ethereum之后,支持圖靈完備的編程語言的智能合約的引入[1],使得Ethereum成為可以支持開發(fā)和運(yùn)行DApp的系統(tǒng)。而Ethereum的智能合約被調(diào)用并形成交易后,需要網(wǎng)絡(luò)上其他節(jié)點(diǎn)對(duì)其正確性進(jìn)行驗(yàn)證[2]。智能合約調(diào)用及驗(yàn)證的過程如圖1所示。
圖1 Ethereum智能合約調(diào)用及驗(yàn)證過程
在圖1中,智能合約調(diào)用者即交易發(fā)起者,其調(diào)用合約時(shí)使用的參數(shù)全集,必須是明文且公開的,如此,網(wǎng)絡(luò)上的其他節(jié)點(diǎn)即智能合約驗(yàn)證者才能根據(jù)這個(gè)參數(shù)全集來驗(yàn)證該智能合約執(zhí)行結(jié)果是否正確。
顯然,這樣的驗(yàn)證方式,對(duì)于智能合約調(diào)用者節(jié)點(diǎn)來說,沒有任何隱私保護(hù)可言[3]。對(duì)此,Ethereum技術(shù)團(tuán)隊(duì)也曾坦言,由于同態(tài)加密技術(shù)遠(yuǎn)不能夠支持圖靈完備的智能合約語言,所以只好放棄了智能合約調(diào)用過程中的加密功能。
與技術(shù)上的障礙相對(duì)應(yīng)的,是一些應(yīng)用場(chǎng)景對(duì)于智能合約加密的迫切需求。事實(shí)上,有很多可以運(yùn)行在Ethereum或類似區(qū)塊鏈上的應(yīng)用場(chǎng)景,都是需要保護(hù)隱私的。例如:需要多方參與的競(jìng)拍競(jìng)價(jià)、競(jìng)選投票之類的應(yīng)用[4],各方調(diào)用智能合約的輸入都是需要被保密的。再如:醫(yī)療健康數(shù)據(jù)會(huì)涉及到個(gè)人隱私,因此信息持有者在通過調(diào)用智能合約來分享相關(guān)信息的時(shí)候也會(huì)有顧慮。
由于全同態(tài)加密技術(shù)距離支持圖靈完備的智能合約語言還有很長(zhǎng)的路要走,所以業(yè)界目前普遍采用一些折衷的辦法,例如Commit-Reveal辦法[5]:通常是將智能合約的輸入?yún)?shù)中加入鹽,從而在保護(hù)原參數(shù)的前提下,讓其他節(jié)點(diǎn)可以驗(yàn)證合約的調(diào)用情況,并在未來通過提供具體的鹽的方式,來證明調(diào)用者知曉相關(guān)的調(diào)用參數(shù)。
同態(tài)加密是基于數(shù)學(xué)難題的計(jì)算復(fù)雜性理論的密碼學(xué)技術(shù),其概念可以簡(jiǎn)單理解為:對(duì)經(jīng)過同態(tài)加密的密文數(shù)據(jù)進(jìn)行運(yùn)算所得到的結(jié)果,與對(duì)數(shù)據(jù)原文進(jìn)行同樣運(yùn)算后得到的結(jié)果再進(jìn)行同態(tài)加密的結(jié)果,恰好是一樣的[6]。正如如下公式所示:
其中,f()為數(shù)據(jù)處理方法,E()為同態(tài)加密算法。
同態(tài)加密概念來自于代數(shù)學(xué),通常分為加法同態(tài)和乘法同態(tài)。而如果同時(shí)滿足加法同態(tài)和乘法同態(tài),則稱該同態(tài)加密算法滿足全同態(tài)。自1978年同態(tài)加密概念被提出以來,尋找滿足全同態(tài)的加密算法成為了開放性的密碼學(xué)難題。直到2009年,IBM的Craig Gentry才突破了這一難題[7~8]。
同態(tài)機(jī)密技術(shù)首先被應(yīng)用于云計(jì)算中,而對(duì)于區(qū)塊鏈技術(shù),同態(tài)加密同樣是很好的支撐技術(shù)。在實(shí)際的行業(yè)應(yīng)用里,同態(tài)加密更多被用作普通交易數(shù)據(jù)的保護(hù),特別是對(duì)交易金額和賬戶余額等信息進(jìn)行保密。例如:華為區(qū)塊鏈提供了同態(tài)加密庫(kù),可以將用戶賬戶和賬本數(shù)據(jù)以密文形式保護(hù),并且交易也采用密文運(yùn)算[9];趣鏈(Hyperchain)同樣采用同態(tài)加密的辦法來保護(hù)賬戶及交易的隱私性,同時(shí)保留其在網(wǎng)絡(luò)中的可驗(yàn)證性[10]。
值得一提的是,行業(yè)中選擇同態(tài)加密的區(qū)塊鏈,更傾向于使用滿足加法同態(tài)的Paillier算法[11]。該算法于1999年被Paillier發(fā)明,基于復(fù)合剩余類的困難問題,其原理此處不再贅述。由于該算法必然會(huì)產(chǎn)生密鑰,所以其在工程領(lǐng)域應(yīng)用的時(shí)候,需要有配套的密鑰管理機(jī)制,包括創(chuàng)建、保存、頒發(fā)、撤銷等。除了Paillier算法外,滿足乘法同態(tài)的El-Gamal算法[12]也常被業(yè)界使用。它是除RSA外最具代表性的公開密鑰密碼之一,其安全性建立在離散對(duì)數(shù)問題的困難性之上,其原理此處亦不再贅述。
值得注意的是,業(yè)界尚未出現(xiàn)直接將全同態(tài)加密方案直接運(yùn)用于智能合約加密的相關(guān)思路及具體實(shí)現(xiàn)。究其原因在于:行業(yè)對(duì)于智能合約的一個(gè)默認(rèn)的基本要求是具備圖靈完備性,盡管業(yè)界也承認(rèn)無法提供無限存儲(chǔ)能力供圖靈完備的智能合約使用[13]。而圖靈完備意味著,合約語言必須支持跳轉(zhuǎn)。而跳轉(zhuǎn)則意味著,合約語言必須能夠?qū)τ?jì)算的中間結(jié)果進(jìn)行判斷或比較。換言之,同態(tài)加密方案要保證計(jì)算過程中的單調(diào)性,而這是不可能做到的,因?yàn)閱握{(diào)性是對(duì)破解非常有幫助的特性。
為了解決圖靈完備特性對(duì)全同態(tài)加密方案的不切實(shí)際的要求,我們寄希望于通過將智能合約的執(zhí)行過程分段,從而在不涉及比較和判斷的地方使用全同態(tài)加密技術(shù)。
為了對(duì)智能合約分段進(jìn)行同態(tài)加密,我們首先要了解智能合約的編譯和執(zhí)行過程。從Ethereum引入智能合約開始,到Fabric中基于Golang語言編譯器及docker模擬器的強(qiáng)大的智能合約[14],智能合約的編寫語言從定制走向通用,相應(yīng)的模擬器也從定制走向通用,但智能合約的編譯和執(zhí)行過程一直都是相似的。如圖2所示。
圖2 智能合約的編譯和執(zhí)行過程
首先,智能合約的編寫者需要使用圖靈完備的高級(jí)語言編寫合約/鏈碼,然后使用相應(yīng)的編譯器將其編譯為字節(jié)碼,并存儲(chǔ)于區(qū)塊鏈中[15]。而智能合約調(diào)用者則需要提供相應(yīng)的輸入?yún)?shù),將區(qū)塊鏈上的智能合約運(yùn)行于模擬器上,并將結(jié)果以交易的形式提交到區(qū)塊鏈,供其他節(jié)點(diǎn)驗(yàn)證。驗(yàn)證節(jié)點(diǎn)同樣是根據(jù)交易中提供的輸入?yún)?shù),將智能合約再次放到模擬器上運(yùn)行,以驗(yàn)證交易結(jié)果的正確性[16]。
所以,我們可以將智能合約理解為一個(gè)程序的源代碼,是用高級(jí)語言編寫的,可讀的文本。而當(dāng)智能合約被提交到區(qū)塊鏈上的時(shí)候,它首先需要被編譯,形成類似匯編語言的指令序列,并被存儲(chǔ)到區(qū)塊鏈上。此時(shí),該智能合約就類似于通用計(jì)算機(jī)上的“可執(zhí)行程序”,可以被區(qū)塊鏈網(wǎng)絡(luò)中的其他節(jié)點(diǎn)調(diào)用,并且在調(diào)用的時(shí)候可以接受不同的輸入?yún)?shù),從而得到不盡相同的結(jié)果。也就是說,當(dāng)某個(gè)節(jié)點(diǎn)調(diào)用智能合約時(shí),就類似于一臺(tái)個(gè)人電腦調(diào)用了網(wǎng)絡(luò)上的一個(gè)程序來進(jìn)行計(jì)算,并將計(jì)算結(jié)果存儲(chǔ)到網(wǎng)絡(luò)中。所不同的是,所有被存儲(chǔ)到網(wǎng)絡(luò)上的智能合約計(jì)算結(jié)果,都需要被網(wǎng)絡(luò)上的其他節(jié)點(diǎn)進(jìn)行驗(yàn)證。而驗(yàn)證的過程,就是各個(gè)節(jié)點(diǎn)利用該合約被調(diào)用時(shí)所傳入的參數(shù),在節(jié)點(diǎn)本地利用模擬器再次進(jìn)行計(jì)算,來驗(yàn)證網(wǎng)絡(luò)上的結(jié)果與自己本地是否一致。
這一過程中,最值得我們注意的是:可被調(diào)用的智能合約,是以一種可被模擬器執(zhí)行的指令流的方式存儲(chǔ)到區(qū)塊鏈中的,這樣才好被不同的節(jié)點(diǎn)反復(fù)執(zhí)行并驗(yàn)證。而這個(gè)指令流中的指令,一定屬于一個(gè)指令集,而且該指令集最好是圖靈完備的[17],才有可能被業(yè)界接受。
顯然,我們需要一個(gè)相對(duì)精簡(jiǎn)的,圖靈完備指令集。我們知道,如果巧妙地選取一條指令來構(gòu)成一個(gè)指令集(One Instruction Set Computer,OISC)[18],并給予它無限的資源,是可以構(gòu)成一個(gè)圖靈機(jī)的。這樣的OISC的大致可以分為三類:位操縱機(jī)、傳輸觸發(fā)架構(gòu)(Transport Triggered Architecture)機(jī)器[19]和基于算數(shù)運(yùn)算的圖靈完備機(jī)器[20]。
最簡(jiǎn)單的圖靈完備的單一指令集的思路是:“SBNZ abcd”指令,其中a、b、c、d都是地址指針。該指令的功能是:如果a中的內(nèi)容與b中的內(nèi)容不相等,則將b中的內(nèi)容減去a中的內(nèi)容,并將結(jié)果存儲(chǔ)到c地址中,然后將控制轉(zhuǎn)移到地址d;否則按順序執(zhí)行下一條指令。
顯然,滿足圖靈完備的充要條件是:該指令集支持算數(shù)運(yùn)算和“判斷+跳轉(zhuǎn)”。算數(shù)運(yùn)算可以由加法和乘法指令組合完成,并且加法與乘法是可以被全同態(tài)加密方案支持的?!芭袛?跳轉(zhuǎn)”的關(guān)鍵是判斷,即判斷兩個(gè)數(shù)字的大小。如果全同態(tài)加密方案在對(duì)明文和密文運(yùn)算的時(shí)候,可以保證單調(diào)性,就可以認(rèn)為能夠支持判斷。例如:明文的x1小于x2,那么密文的x1也要小于密文的x2。但這對(duì)于同態(tài)加密技術(shù)來說不切實(shí)際。試想,如果我們現(xiàn)在得到了E(x)的值,想反求x的值,此時(shí)如果同態(tài)加密能夠保證單調(diào)性的話,那么我們很容易找到x1,x2,使得E(x1) 所以,我們只有讓同態(tài)加密繞過全部判斷指令,這也正是本文所要著重說明的“分段加密”的原因。所謂分段,指的不是對(duì)指令流字節(jié)碼分段,而是在該指令流字節(jié)碼被虛擬機(jī)執(zhí)行過程中的指令執(zhí)行序列進(jìn)行分段。指令流字節(jié)碼是編譯結(jié)果,而指令執(zhí)行序列是運(yùn)行時(shí)才能確定的序列。圖3可以說明指令流字節(jié)碼和指令執(zhí)行序列之間的區(qū)別。 如圖3所示,指令流字節(jié)碼,類似于一個(gè)可執(zhí)行程序;而指令執(zhí)行序列,則類似于程序運(yùn)行時(shí),調(diào)度到CPU上運(yùn)行的指令的順序列表。一個(gè)智能合約,可以一一映射到一個(gè)指令流字節(jié)碼,且后者一定要先被存儲(chǔ)到區(qū)塊鏈上,才能被調(diào)用。而智能合約的每次調(diào)用,都可以一一映射到一個(gè)指令執(zhí)行序列。需要指出的是,節(jié)點(diǎn)在對(duì)智能合約調(diào)用進(jìn)行驗(yàn)證的時(shí)候,其所對(duì)應(yīng)的指令執(zhí)行序列,必然與原調(diào)用者調(diào)用智能合約時(shí)所對(duì)應(yīng)的指令執(zhí)行序列完全一致。所以我們可以說,同一個(gè)智能合約,在輸入?yún)?shù)相同的情況下,其執(zhí)行過程中的指令執(zhí)行序列也一定相同,所以合約執(zhí)行結(jié)果也一定相同。 圖3 指令流字節(jié)碼與指令執(zhí)行序列 顯然,由于智能合約調(diào)用者掌握著輸入?yún)?shù)的明文,其合約執(zhí)行過程中也是進(jìn)行明文計(jì)算,所以合約調(diào)用者可以在現(xiàn)有的虛擬機(jī)上運(yùn)行現(xiàn)有的指令流字節(jié)碼,而且可以在執(zhí)行的過程中獲得每次遇到判斷指令時(shí)的判斷結(jié)果。 而智能合約驗(yàn)證者由于只掌握了輸入?yún)?shù)的密文,其合約執(zhí)行過程中也只能進(jìn)行密文計(jì)算,而同態(tài)加密是不能保證單調(diào)性的,所以合約執(zhí)行者在現(xiàn)有虛擬機(jī)上運(yùn)行現(xiàn)有指令流字節(jié)碼的時(shí)候,勢(shì)必會(huì)在判斷指令上于明文運(yùn)算存在一定概率的不一致,而這個(gè)概率可能會(huì)逼近0.5,即密文的大小關(guān)系是隨機(jī)的,與明文大小關(guān)系無關(guān)。 既然我們現(xiàn)在缺少且僅缺少針對(duì)判斷的同態(tài)加密方案,那么我們可以考慮通過圖3中的判斷結(jié)果序列來繞開判斷指令的同態(tài)加密:這就是本文的核心思路:利用判斷結(jié)果序列來輔助同態(tài)加密方案,構(gòu)成針對(duì)圖靈完備的智能合約的同態(tài)加密方案。 為了解決合約驗(yàn)證者在執(zhí)行判斷指令的時(shí)候存在不一致的問題,我們可以要求智能合約調(diào)用者在用明文參數(shù)執(zhí)行完合約的同時(shí),將這一過程中遇到的所有判斷指令的結(jié)果(即一個(gè)Y/N序列,或二進(jìn)制串)保存下來,并以判斷序列的方式作為輔助參數(shù),一并發(fā)布到區(qū)塊鏈上。與此同時(shí),智能合約驗(yàn)證者在得到輸入?yún)?shù)密文,以及判斷序列后,同樣可以在虛擬機(jī)上再次執(zhí)行該合約,并在遇到判斷指令的時(shí)候,不對(duì)其進(jìn)行判斷,而是直接使用判斷序列里的值,從而避開同態(tài)加密所不支持的判斷。流程參考圖4。 這一方案的實(shí)現(xiàn),需要考慮智能合約的調(diào)用者和驗(yàn)證者在執(zhí)行智能合約時(shí)所使用的不同的參數(shù)即不同的執(zhí)行過程,即我們需要對(duì)模擬器進(jìn)行一次升級(jí),才能驗(yàn)證這一方案。 首先,智能合約調(diào)用者節(jié)點(diǎn),在其本地使用明文參數(shù)執(zhí)行智能合約時(shí),模擬器需要知道這是明文參數(shù),可以按照智能合約指令流字節(jié)碼來執(zhí)行,并且每次遇到判斷指令的時(shí)候,記錄下判斷的結(jié)果(Y/N或1/0)。當(dāng)該合約執(zhí)行完成后,模擬器不僅需要記錄下合約執(zhí)行結(jié)果,同時(shí)還要將執(zhí)行過程中所生成的判斷結(jié)果序列保留下來,因?yàn)檫@將是其他節(jié)點(diǎn)對(duì)該次合約執(zhí)行結(jié)果進(jìn)行驗(yàn)證的必須的參數(shù)。 圖4 分段加密的執(zhí)行過程 在合約執(zhí)行完畢后,支持同態(tài)加密的區(qū)塊鏈節(jié)點(diǎn)需要對(duì)輸入?yún)?shù)和執(zhí)行結(jié)果進(jìn)行同態(tài)加密,并且連同判斷結(jié)果序列的明文,一并提交,存儲(chǔ)到區(qū)塊鏈上。 與此同時(shí),其他節(jié)點(diǎn)需要對(duì)合約執(zhí)行結(jié)果進(jìn)行驗(yàn)證,而它們所得到的參數(shù)將是密文形式,以及一串明文的判斷結(jié)果序列。此時(shí),不僅需要模擬器進(jìn)行密文計(jì)算,并且在遇到判斷指令的時(shí)候,不去執(zhí)行指令,而是順序使用判斷結(jié)果序列中的值。如此,模擬器的整個(gè)執(zhí)行過程,等價(jià)于一連串的針對(duì)密文的算數(shù)運(yùn)算。由于判斷結(jié)果序列是唯一的,所以這個(gè)一連串的算數(shù)運(yùn)算,每條指令都與明文計(jì)算時(shí)的算數(shù)運(yùn)算指令保持一致,其結(jié)果作為密文計(jì)算的結(jié)果,應(yīng)該與明文計(jì)算的結(jié)果加密后是一致的。 綜上,我們需要對(duì)模擬器進(jìn)行升級(jí),使其既可以生成判斷結(jié)果序列,也可以根據(jù)判斷結(jié)果序列對(duì)智能合約進(jìn)行密文計(jì)算。 Ethereum是第一個(gè)承載智能合約的區(qū)塊鏈,其模擬器(EVM)是最經(jīng)典也最簡(jiǎn)單的能夠運(yùn)行智能合約的虛擬機(jī)。EVM是一個(gè)準(zhǔn)圖靈機(jī),可以運(yùn)行包含復(fù)雜的隨機(jī)的算法的智能合約字節(jié)碼,其運(yùn)行原理入圖5。 我們構(gòu)造一個(gè)非常簡(jiǎn)單的智能合約,并通過如圖6的合約編譯界面來生成字節(jié)碼,從而在EVM上運(yùn)行該智能合約。 從圖6中可以看到,簡(jiǎn)單的智能合約中所出現(xiàn)的判斷語句“if(b==1)”,在編譯結(jié)果中有“ISZERO”指令與之相對(duì)應(yīng),而這樣的判斷指令正是智能合約分段加密工作的研究對(duì)象。 圖5 EVM結(jié)構(gòu) 圖6 Remix-Ethereum IDE 最終在EVM上執(zhí)行的智能合約字節(jié)碼,其執(zhí)行邏輯便是將圖6右側(cè)的類匯編指令逐條地利用圖5中的EVM的內(nèi)存和堆棧來執(zhí)行,并將結(jié)果寫入圖5中的狀態(tài)數(shù)據(jù)庫(kù)。 基于上述實(shí)驗(yàn),我們可以更加明確以Ethereum智能合約為代表的區(qū)塊鏈智能合約的執(zhí)行原理和細(xì)節(jié)。而我們接下來的工作,則集中在針對(duì)模擬器的重構(gòu),使之能夠分別以明文和密文的模式來運(yùn)行智能合約,其部署原理及流程如圖7所示。 圖7 EVM的執(zhí)行模式與驗(yàn)證模式 智能合約所涉及到的算數(shù)運(yùn)算通常具有一定的規(guī)模,例如Ethereum上標(biāo)準(zhǔn)發(fā)幣合約會(huì)被官方編譯器編譯為約1500條類匯編指令。而目前不能確定同態(tài)加密方案對(duì)于復(fù)雜運(yùn)算的支持程度,所以這方面需要進(jìn)一步的調(diào)研和試驗(yàn)。 由于判斷序列是由合約調(diào)用者通過明文運(yùn)算后給出的,所以存在該調(diào)用者惡意造假的可能性。因?yàn)閰?shù)明文是該調(diào)用者唯一持有的,所以其他節(jié)點(diǎn)無法再次參數(shù)明文來執(zhí)行智能合約,也就無法直接驗(yàn)證該判斷序列的正確性。 由于智能合約本身是公開的,而判斷序列同樣是公開的,所以不能排除有人可能會(huì)根據(jù)判斷序列來反推出調(diào)用者明文參數(shù)的一些特征。不過判斷序列所帶有的隱私信息是非常有限的,并且可以在合約頭部代碼中加入一些干擾代碼來增加這種“破譯”難度。 本文通過對(duì)智能合約執(zhí)行過程的介紹、對(duì)全同態(tài)加密領(lǐng)域的調(diào)研以及對(duì)“圖靈完備”指令集的分析,論證了難以尋找到適用于圖靈完備的智能合約的全同態(tài)加密方案的原因,進(jìn)而提出了利用判斷結(jié)果序列的方法來講智能合約簡(jiǎn)化為算數(shù)運(yùn)算,從而使用全同態(tài)加密方案進(jìn)行加密。接下來的驗(yàn)證工作,需要升級(jí)模擬器,為全同態(tài)加密在智能合約中的應(yīng)用提供基礎(chǔ)設(shè)施。4 分段加密實(shí)踐
5 尚需解決的問題
5.1 算術(shù)運(yùn)算的規(guī)模
5.2 判斷序列的真實(shí)性
5.3 判斷序列的隱私性
6 結(jié)語