陳 強,譚 林,王云麗,肖 靖
(1.湖南大學電氣與信息工程學院,湖南 長沙 410082;2.湖南天河國云科技有限公司,湖南 長沙 410100)
隨著傳感器、嵌入式芯片和人工智能等技術的發展,工業生產過程時刻在產生海量的數據,比如生產設備的運行環境、機械設備的運轉狀態、生產過程中的能源消耗、物料損耗等。使如此大規模的工業數據發揮其價值的關鍵環節在于數據的流通[1]。然而,如何使工業數據在不同企業間或同一企業的不同部門間安全、高效地流通是目前面臨的首要問題。數據交易是數據流通的具體表現形式之一。在傳統的數據交易系統中,一般存在數據擁有者、數據需求者及中間商3種角色。中間商的存在能給數據擁有者和數據需求者提供一個可信的交易環境,從而使雙方能有效地進行數據交易[2,3]。然而,中間商的存在也給數據交易帶來了復雜的交易流程、較高的交易費用以及信用依賴。因此,利用區塊鏈技術去中心化、不可篡改和可溯源的優勢,可以通過工業區塊鏈交易系統提供可信的交易環境,使數據擁有者和數據需求者在沒有可信中間商的情況下依然能夠安全、有效地完成交易[4,5]。但是,由于區塊鏈本身的局限性,區塊容量較小不足以將大數據文件直接存儲到區塊。比如,在比特幣中一個區塊的最大容量只有6 MB左右,在Fabric中一個區塊的最大容量也只有100 MB左右。因此,一般的解決方法是將源數據的哈希值或者源數據的存儲地址等作為元數據存儲到區塊中,源數據本身則存儲在云端或本地,從而形成鏈上存元數據、鏈下存源數據的存儲方式[6-10]。但是,這樣的做法在工業區塊鏈中也存在以下2點不足:一是由于串行計算哈希值所需的時間隨著數據量的增大而線性增長,因此,串行計算這種方式在工業區塊鏈中難以滿足大規模數據高效上鏈的需求;二是由于源數據本身沒有存儲到區塊鏈,在交易時數據需求者無法確認源數據是否被篡改。所以,本文將重點研究基于CUDA的數據并行處理方法來提高大規模工業數據上鏈的效率,并在數據交易雙方之間構建有效的數據完整性驗證模型,使數據需求者在交易時就能夠確認源數據本身的完整性。
在區塊鏈系統中,將源數據存儲到區塊鏈時,其處理過程可以分為2個階段:第1階段包括業務數據處理和數據序列化等,第2階段包括廣播、打包和共識等。在業務數據處理步驟中,針對大數據文件一般是在CPU平臺上利用OpenSSL等標準庫計算其哈希值[11,12]。這些計算方法都是將大規模工業數據當作一個整體串行計算其哈希值,計算速度相對較慢。在區塊鏈中,不論是將大數據文件當作一個整體來獲得其哈希值,還是將大數據文件分塊來獲得其哈希值,只需計算所得的哈希值與大數據文件一一對應,上述2種方式獲得的哈希值都可作為元數據存儲到區塊鏈。因此,本文針對工業數據規模大的特點,利用GPU在單指令多數據方面的計算優勢[13-16],設計了基于CUDA的數據哈希值并行計算方法,對工業數據實施了分塊、哈希值并行計算等處理,以提高大規模工業數據哈希值的計算效率。
在傳統的數據完整性驗證方案和基于區塊鏈的數據完整性驗證方案中,都是持有簽名私鑰的數據擁有者或可信第三方向云服務商驗證源數據的完整性[17-22]。然而,在工業區塊鏈數據交易系統中構建的數據完整性驗證模型中,持有簽名私鑰的數據擁有者是作為證明者出現的。因此,當數據需求者向數據擁有者驗證源數據的完整性時,數據擁有者可能利用簽名私鑰向數據需求者提供偽造的證明信息,因為鏈上存元數據、鏈下存源數據的方式只能確保元數據不被篡改,而無法使數據需求者在交易時確認源數據本身的完整性。數據需求者只有在交易得到源數據本身后,才能驗證源數據的完整性[23-25]。對于大數據文件的交易,如果數據擁有者不小心或故意篡改了源數據,那么數據需求者付出較大的通信代價得到的卻是無用的數據。因此,如果在傳輸大規模工業數據前就能夠確認其完整性,可以減小上述無意義交易帶來的通信代價。所以,本文在現有的數據完整性驗證方案上,將簽名信息構建成默克爾哈希樹并把默克爾根存儲到區塊鏈。在驗證源數據完整性前,首先驗證簽名信息,避免用偽造的簽名信息去驗證源數據完整性,從而使數據需求者能夠有效地驗證源數據的完整性。
綜上所述,通過基于CUDA的數據并行處理方法和兩方完整性驗證模型可以實現:
(1)通過合理的數據分塊、線程布局等手段,使大規模工業數據哈希值的計算效率可以得到較明顯的改善,提高了大規模工業數據上鏈的效率。
(2)在數據擁有者持有簽名私鑰的特殊情形下,通過區塊鏈不可篡改、可溯源等特性,數據需求者仍可對數據擁有者提供的源數據進行有效的完整性驗證。
基于SHA256哈希函數的原理,本文設計了基于CUDA的數據并行處理方法。SHA256函數的實現主要由以下4個算法構成[26]:
(1)PaddingChars(·):首先對源數據進行分塊,然后分別對數據塊進行填充,使填充后的數據塊長度為512的倍數,數據塊長度用二進制位表示。
(2)Convert(·):將填充后的每個數據塊劃分成M組長度為512位的數據,然后將每組數據轉換成16個32位的無符號整數。
(3)Expand(·):將16個32位無符號整數擴展成64個32位的無符號整數。
(4)Compress(·):對每個數據塊循環M次,每次基于64個32位的無符號整數計算中間哈希值,循環結束后得到的中間哈希值即為最終的哈希值。
本文設計的基于CUDA的數據并行處理方法如算法1所示,主要設計思路如下所示:
(1)當源數據的大小dataSize (2)當dataSize≥dataSizeThreshold時,由于GPU內存大小的限制,需要分批將源數據從主機端復制到GPU內存。在每次將數據復制到GPU內存后,對數據進行分塊,基于數據塊大小dataBlockSize并發相應的線程數并行計算數據塊哈希值、構建默克爾哈希樹T1,并將T1從GPU內存復制到主機端,對應算法1第6~10步。 算法1基于CUDA的數據并行處理方法 Input:Source fileF。 Output:Merkle hash treeT1。 1:IfdataSize 2: Dividing source dataFintonblocks anddataBlockAmount=n; 3:fori=1 tondo Computing hash value of data blocks by CPU; endfor 4: Constructing Merkle hash treeT1by CPU; 5:else 6:fori=0 tocopyTimesdo 7: (1)Copy data from host memory to GPU device memory; (2)Dividing source dataFintonblocks anddataBlockAmount=n,threadAmount=n; (3)Parallelly employingnthreads to executePaddingChars(·),Convert(·),Expand(·)andCopmpress(·); 8:endfor 9: Constructing Merkle hash treeT1on GPU; 10: Copy hash values from GPU memory to host memory; 11:endif 12:returnMerkle hash treeT1. 影響本文設計的因素主要有以下3個:(1)源數據的大小dataSize;(2)GPU內存的大小GPUMemorySize;(3)并行計算時的數據塊大小dataBlockSize,它與SHA256函數的原理、GPU的CUDA核心數量、共享內存大小和寄存器文件大小等相關。 因素1源數據大小。 源數據大小dataSize直接決定是由CPU串行還是GPU并行來計算數據塊的哈希值。因為源數據在主機端和GPU之間復制需要通信時間,并且CPU單線程的運算速度遠遠高于GPU單個線程的,所以,并不是所有大小的源數據都適合利用GPU來計算哈希值和構建默克爾哈希樹。定義CPU計算數據塊哈希值并構建默克爾哈希樹的時間為TCPU,對應算法1中第1~4步的運行時間;把源數據從主機端復制到GPU的時間為Th→GPU,對應算法1中第7(1)步的運行時間乘以copyTimes;利用GPU計算各個數據塊哈希值并構建默克爾哈希樹的時間為TGPU,對應算法1中第6~9步的運行時間;將數據塊哈希值從GPU傳回主機端的時間是TGPU→h,對應算法1中第10步的運行時間。隨著源數據的增大,TCPU、Th→GPU、TGPU、TGPU→h都將增大,但是TCPU的增大速度大于TGPU的增大速度,并且TCPU遠大于Th→GPU和TGPU→h。因此,當源數據的大小dataSize超過閾值dataSizeThreshold時,式(1)所示的不等式將成立: TCPU>Th→GPU+TGPU+TGPU→h (1) 所以,當源數據的大小dataSize 因素2GPU內存大小。 由于GPU內存大小GPUMemorySize的限制,當源數據足夠大時,不能一次性把源數據從主機端復制到GPU內存。定義每次可從主機端復制到GPU內存的數據最大值為dataSizePerCopyMB。由SHA256函數原理可知,在執行Expand(·)算法時需要的GPU內存空間將達到最大值,此時,輸入數據占用的內存空間為dataSizePerCopyMB,輸出數據占用的內存空間為4×datasizePerCopyMB。由此可知,dataSizePerCopy應滿足式(2): 5×dataSizePerCopy (2) 則將源數據復制到GPU內存的次數CopyTimes如式(3)所示: copyTimes=ceil(dataSize/dataSizePerCopy) (3) 其中,ceil(·)函數表示向上取整。 因素3數據塊大小。 在利用GPU并行計算時,如何對源數據進行分塊對哈希值的計算效率非常重要。如果分塊數量過少,將導致GPU中并行程度不夠,從而無法發揮GPU的并行計算優勢;如果分塊數量過多,由于GPU硬件資源的限制,沒有足夠多的線程來支撐哈希值計算,反而會降低計算效率。在本文方法中,數據塊的大小dataBlockSize主要由SHA256函數的原理及GPU的硬件資源決定。 在SHA256函數原理方面,如何對數據塊進行填充是關鍵。假設源數據F的長度L(L以二進制位數量表示)為:L=512k+b,其中k,b都是非負整數。在執行PaddingChars(·)算法時,對源數據F的填充分2種情形進行: (1)情形1:如果 0 ≤b<448,則填充后的結果如圖1a所示。 首先,需要填充1個二進制數1和448-b-1個二進制數0。然后,再填充用64位二進制數表示的源數據長度L。完成填充后,數據的長度L′=512(k+1)。 (2)情形2:如果 448≤b<512,則填充后的結果如圖1b所示。 首先,需要填1個二進制數1和512-b-1+448 個二進制數0。然后,再填充用64位二進制數表示的源數據長度L。完成填充后,數據的長度L′=512(k+2)。 Figure 1 Schematic diagram after filling the source data 由此可知,填充后情形2比情形1多了512位數據,在之后計算哈希值的過程中,每個數據塊執行Convert(·)、Expand(·)和Compress(·)算法時都會多1次計算,并且每個數據塊多余的填充數據將占據更多的CPU或GPU內存。所以,在進行數據分塊時,數據塊的大小應滿足情形1。 在GPU硬件資源方面,CUDA核心數量、寄存器文件的大小等都會限制并行計算中的線程數量,而線程的數量會直接影響源數據如何進行分塊。在有限的硬件資源下,GPU并行計算性能的發揮主要依賴內核網格和線程塊的配置。配置網格和塊的大小時的準則主要有:(1)保持每個線程塊中線程數量是線程束大小的倍數;(2)線程塊的數量要大于流式多處理器的數量,并且是流式處理器的倍數,保障在GPU中有足夠多的并行。 本文設計的兩方數據完整性驗證模型由數據建立和驗證2個階段構成。 源數據處理階段的流程如圖2所示。首先,利用本文提出的數據并行處理方法對源數據F進行分塊,可以得到n個數據塊{m1,m2,…,mn},其中,mi∈ZP,1≤i≤n,Z為整數集,P為一個大素數。同時,利用該方法計算數據塊的哈希值并構建默克爾哈希樹T1。默克爾哈希樹T1的構建過程如下所示:(1)并行計算數據塊的哈希值;(2)將相鄰數據塊的哈希值兩兩拼接在一起再并行計算哈希值,如果拼接時哈希值的數量為奇數,則對尾部的哈希值進行復制;(3)循環第2步操作,直至得到最后1個哈希值默克爾根R1。 Figure 2 Flow chart of source data processing 然后,令e:G1×G1→G2為一個雙線性映射,其中,G1和G2為乘法循環群,g是G1的生成元。數據擁有者隨機選擇一個數α∈ZP,計算v=gα,并把α作為私鑰SK,v作為公鑰PK。接著,數據擁有者隨機選擇u∈G1,并計算數據塊{m1,m2,…,mn}的簽名信息Φ={σ1,σ2,…,σn},σi=(H(mi)·umi)α,i=1,2,…,n,H(mi)為第i個數據塊的哈希值,并對簽名信息構建默克爾哈希樹T2,其構建過程與T1相似,最終同樣可以得到其相應的默克爾根R2。 最后,數據擁有者將源數據的元數據MetaData={g,v,R1,R2}存儲到區塊鏈上的智能合約SM中。 如圖3所示,在本文的完整性驗證模型中,數據擁有者和數據需求者兩方實體分別扮演證明者和驗證者角色。當進行數據完整性驗證時,首先,數據需求者向數據擁有者發送挑戰信息Chal;然后,數據擁有者根據挑戰信息Chal計算相關證明信息Proof,并同時調用智能合約SM;最后,數據需求者根據數據擁有者返回的證明信息和元數據信息驗證源數據的完整性。 Figure 3 Integrity verification of source data 數據需求者從集合{1,2,…,n}中隨機選擇c個元素,組成子集S={s1,s2,…,sc},其中1≤s1≤s2≤…≤sc≤n。對于每一個si∈S,在ZP中隨機選擇一個數vi與之對應,形成V={vs1,vs2,…,vsc}。首先,數據需求者將挑戰信息Chal={S,V}發送給數據擁有者,即圖3的步驟1。數據擁有者在接收到挑戰信息Chal后,根據式(4)計算μ和Δ: (4) 其中,mi為第i個數據塊,vi為隨機數,H(mi)為第i個數據塊的哈希值,u為數據擁有者在建立階段選擇的隨機數。接著,數據擁有者調用存儲了元數據MetaData={g,v,R1,R2}的智能合約SM(即圖3的步驟2),并將證明信息Proof={H(mi),A1,Φ′,A2,Δ}發送給數據需求者(即圖3的步驟3),其中,s1≤i≤sc,H(mi)為第i個數據塊的哈希值;Φ′為數據塊的簽名信息子集,Φ′={σs1,σs2,…,σsc};A1為恢復默克爾根R1的輔助信息;A2為恢復默克爾根R2的輔助信息。A1和A2的具體含義如圖4所示。假設將源數據分為4個數據塊{m1,m2,m3,m4},基于這4個數據塊構建默克爾哈希樹得到的默克爾根為R。在只擁有數據塊m2的情況下,由輔助信息A={H(m1),H34}恢復默克爾根R的計算過程如下所示: (1)由數據塊m2計算得到H(m2); (2)由H(m1)和H(m2)計算出H12; (3)由H12和H34可恢復得到默克爾根R。 Figure 4 Recovering Merkle root with auxiliary information 數據需求者在接收到證明信息Proof和元數據MetaData后進行驗證(即圖3的步驟4),其詳細的驗證流程如圖 5所示。在第1步驗證中,數據需求者根據{H(mi),A1,A2}恢復默克爾根R′1和R′2,并判斷R′1和R′2是否與MetaData中的默克爾根R1和R2相等。如果不相等,則認為證明信息是偽造的,證明信息無法證明源數據的完整性。如果相等,則繼續第2步驗證,數據需求者根據數據塊的簽名信息子集Φ′={σs1,σs2,…,σsc}和V={vs1,vs2,…,vsc}通過式(5)計算σ: (5) 再根據證明信息Proof中的Δ和元數據中的{g,v},驗證式(6): e(σ,g)=e(Δ,v) (6) 是否成立。如果成立則認為數據是完整的,如果不成立則認為源數據已經被改動。式(6)中g是G1的生成元,v=gα是公鑰,這2個數據都存儲在區塊鏈上的智能合約SM中,是不可篡改的。σ是由數據需求者根據簽名信息Φ′和數據集V={vs1,vs2,…,vsc}計算所得。Δ是由數據擁有者根據挑戰信息Chal計算所得。 Figure 5 Flow chart of data integrity verification 此部分實驗的主要目的是獲得本文并行處理方法中的參數dataSizeThreshold、threadAmount、copyTimes以及該方法的運行效率。實驗計算平臺的CPU和GPU信息如表 1所示。 由于GPU內存大小為4 GB,由式(2)可知其應滿足式(7): dataSizePerCopy≤819.2 (7) 因此,可以將dataSizePerCopy設置為700 MB。然后,由式(3)計算出將源數據由主機端復制 Table 1 Basic information of CPU and GPU 到GPU內存的次數copyTimes,如式(8)所示: copyTimes=ceil(dataSize/700) (8) 當源數據大于700 MB時,需要分copyTimes次處理源數據。當每次處理相同大小的源數據時,并行處理方法所用時間幾乎相同。因此,本文在電網日常監測數據中選取大小分別為 {26,54,86,118,152,209,253,306,352,402,453,506,549,608,658,692}(單位為MB)的源數據進行分塊,其中152 MB以下以30 MB左右為步長,152 MB以上以50 MB左右為步長。26 MB~152 MB源數據的分塊大小dataBlockSize∈{10,50,100,150,200,…,950,1 000}(單位為KB),152 MB~692 MB源數據的分塊大小dataBlockSize∈{50,100,150,200,…,950,1 000,1 100,…,1 600}(單位為KB)。然后,對不同大小的分塊,利用基于OpenSSL的數據串行處理方法和基于CUDA的數據并行處理方法分別進行100次運算,得到每次運算時間后去掉其中的最大值和最小值,再求取運算時間的平均值。 2種方法的運算時間如圖6所示。從圖6可知,當源數據大小大于86 MB時,基于CUDA的數據并行處理方法的運算時間小于基于OpenSSL的數據串行處理方法的運算時間。所以,本文方法中的dataSizeThreshold設置為86 MB。當dataSize≤86 MB時,選擇串行方法處理源數據;當dataSize≥86 MB時,選擇并行方法處理源數據。 基于圖6的運行時間,本文所提出的并行處理方法相較于基于OpenSSL的數據串行處理方法的加速效率如圖7所示。顯然,源數據越大,基于CUDA的數據并行處理方法的加速效果越好。當源數據大小大于253 MB時,加速效率在22%以上,并且在等于506 MB時,加速效率達到最大值27.7%。 Figure 6 Comparison of the running time of two methods Figure 7 Acceleration efficiency of CUDA-based data parallel processing method 當源數據大小小于86 MB時,本文使用基于OpenSSL的串行處理方法。針對不同大小源數據的運行結果如圖8所示,圖8中標示了最短運行時間。從圖8可知,對于不同大小的源數據,該方法的運行效率在數據塊大小為10 KB時較低,而在數據塊大于10 KB時運行效率變化不大,因此dataBlockSize可根據實際需求設置為100 KB以上的任意值。 Figure 8 Running time of OpenSSL-based data serial processing method 當源數據大小大于86 MB時,本文使用基于CUDA的并行處理方法。不同大小源數據的運算結果如圖9所示,圖9中標示了最短運行時間。從圖9可知,當dataBlockSize太小或者太大時,數據并行處理方法的運行時間較長、效率較低。這是因為當源數據的分塊太小時會產生大量的數據塊,GPU硬件資源的限制導致無法支持過多的并行線程,使得運行時間極速增加;當數據塊太大時,并行線程太少導致無法發揮GPU并行計算的優勢,也會使得效率較低。 Figure 9 Running time of CUDA-based data parallel processing method 根據圖9可以得到不同大小源數據的最佳dataBlockSize取值,因此針對不同源數據可以得到具體分塊策略,如圖10所示。例如,在區間(250,300]MB時,dataBlockSize設置為150 KB,對應圖9b中253 M曲線的最少運行時間的分塊大小為150 KB。依次類推能得到不同大小源數據的合適的分塊大小dataBlockSize。由不同大小的dataBlockSize可以計算出每次執行基于CUDA的數據并行處理方法時使用的線程數量threadAmount,如式(9)所示: threadAmount=ceil(700(MB)/ dataBlockSize(KB)) (9) 其中,ceil(·)表示向上取整。 綜上所述,本文提出的并行處理方法,基于所用實驗平臺,需將dataSizePerCopy設置為700 MB,即在源數據大于700 MB時分批傳輸到GPU端進行處理。當源數據大于86 MB時,在GPU端的運行效率優于在CPU端的運行效率,因此將dataSizeThreshold設置為86 MB。針對不同大小的源數據,數據分塊策略如圖10所示,根據不同大小的源數據選擇不同大小的分塊,從而配置不同的線程布局以獲得較好的運行效率。 Figure 10 Blocking strategy of different source data for CUDA-based data parallel processing method 與傳統完整性驗證不同的是,在本文的完整性驗證中數據擁有者是持有簽名私鑰的。在不做保護措施的情形下,數據擁有者可以利用簽名私鑰偽造證明信息使完整性驗證通過。因此,本文在圖5的第1步驗證中,首先驗證了簽名信息的默克爾根R2和R′2是否相等。如果不相等,那么我們就直接認為源數據已經被篡改。如果相等,那么可以確定簽名信息Φ′={σs1,σs2,…,σsc}是沒有被篡改的,為下一步驗證提供了保證。 綜上所述,在數據擁有者持有簽名私鑰的特殊情形下,本文設計的數據完整性驗證方案能夠在數據擁有者不小心或故意改動源數據的情況下發現數據變動,及時終止接下來無意義的交易步驟。在本文數據完整性驗證方案中,若數據擁有者將數據存儲到云端而本地無備份時,只需將證明者替換成云服務提供者即可在數據需求者和云服務商之間對源數據進行完整性驗證。 針對工業數據規模大的特點,本文提出了一種基于CUDA的數據并行處理方法。在源數據大小大于86 MB時,該方法針對不同大小的源數據利用給出的分塊策略,使運行效率優于基于OpenSSL的數據串行處理方法。并且,源數據越大,并行處理方法的運行效率越好。同時,基于此方法提出的兩方完整性驗證模型即使在數據擁有者持有私鑰的特殊情形下,數據需求者依然能夠在得到源數據之前、只得到元數據的情況下,有效地驗證源數據的完整性,避免因傳輸無用數據而付出的通信代價。
3 兩方數據完整性驗證模型設計
3.1 建立階段

3.2 驗證階段



4 結果分析與討論
4.1 數據文件哈希值計算對比實驗及結果分析






4.2 兩方數據完整性驗證模型安全性分析

5 結束語