1. 摘要
本文分析go語言包中的"crypto/rand"和"math/rand",芯鏈hpb系統的區塊鏈隨機數,並給出了權衡效率和隨機性,並給出了一款區塊鏈搖號抽獎系統如何實現隨機數的演算法和流程。
2. 背景知識
2.1 真隨機和偽隨機概念
根據密碼學原理,要想對一個“隨機數”進行隨機性檢驗有以下幾個標準:
- 統計學偽隨機性 - 在給定的隨機位元流樣本中,1 的數量大致等於 0 的數量,也就是說,“10”“01”“00”“11” 四者數量大致相等。說人話就是:“一眼看上去是隨機的”。
- 密碼學安全偽隨機性 - 就是給定隨機樣本的一部分和隨機演算法,不能有效的演算出隨機樣本的剩餘部分。
- 真隨機性 - 其定義為隨機樣本不可重現。
根據以上幾個標準,其對應的隨機數也就分為以下幾類:
- 偽隨機數 - 滿足第一個條件的隨機數。
- 密碼學安全的偽隨機數 - 同時滿足前兩個條件的隨機數。可以透過密碼學安全偽隨機數生成器計算得出。
- 真隨機數 -同時滿足三個條件的隨機數
2.2 go語言包的隨機函式包介紹
2.2.1 math/rand 包
math/rand 包實現了偽隨機數生成器,就是如果使用相同的種子來生成兩個 rand 例項,對這兩個例項進行相同次序和函式的呼叫,那麼將會得到兩串 完全相同 的輸出。如果兩個 rand 物件使用了不同的值來做種子,就不具有這種相同的行為了。但是math/rand 包在介面豐富性和效率方面比較好。
2.2.1.1 主要方法
(1)func seed(seed int64)
設定隨機種子,不設定則預設seed(1)
(2)func intn(n int) int
返回一個取值範圍在[0,n)的偽隨機int值,如果n<=0會panic
(3)func perm(n int) []int
返回一個有n個元素的,[0,n)範圍內整數的偽隨機排列的切片
2.2.1.2 應用場景
(1)驗證碼
(2)隨機密碼
(3)抽獎
(4)隨機演算法
2.2.2 crypto/rand 包
crypto/rand 包實現了用於加解密的更安全的隨機數生成器,其中有個變數 reader io.reader。reader是一個全域性、共享的密碼用強隨機生成器。在unix型別系統中,會從/dev/urandom讀取,而windows中會呼叫cryptgenrandom api。
在unix 核心中的隨機數發生器(/dev/random),理論上它能產生真隨機。即這個隨機數的生成,獨立於生成函式,這時我們說這個隨機數發生器是非確定的。具體來講,unix 維護了一個熵池,不斷收集非確定性的裝置事件,即機器執行環境中產生的硬體噪音,來作為種子。比如說,時鐘,io 請求的響應時間,特定硬體中斷的時間間隔,鍵盤敲擊速度,滑鼠位置變化,甚至周圍的電磁波等等……直觀地講,你每按一次鍵盤,動一下滑鼠,鄰居家 wifi 訊號強度變化,磁碟寫入速度等等訊號,都可能被用來生成隨機數。更具體的,核心提供了向熵池填充資料的介面,比如滑鼠的大概就長成這樣:void add_mouse_randomness(__u32 mouse_data) 核心子系統和驅動呼叫這個函式,把滑鼠的位置和中斷間隔時間作為噪音源填充進熵池。
在windows環境中,一個健壯的隨機函式是:cryptgenrandom(),定義在wincrypt.h。cryptgenrandom從windows2000的眾多的資源中,獲得其隨機性[也稱作“熵”(entropy)]:
①當前程序的id;
②當前執行緒的id;
③系統引導以來的時鐘數;
④各種高精度的效能計數器;
⑤使用者環境模組的md4(message digest 4,資訊摘要4)雜湊,包括使用者名稱,計算機名和搜尋路徑等;
⑥高精度的內部cpu計算器,如rdisc,romsr,rdpm等;
⑦底層系統資訊,如空閒時間,內檢時刻,中斷時間,提交限定,頁面計數,快取計數,作業系統外部計數等。
cryptgenrandom跟硬體關聯,具有真正的隨機性和不可預測性。
2.2.2.1 主要方法
(1)func int(rand io.reader, max *big.int) (n *big.int, err error)
返回一個在[0, max)區間服從均勻分佈的隨機值,如果max<=0則會panic
(2)func prime(rand io.reader, bits int) (p *big.int, err error)
返回一個具有指定字位數(二進位制的位數)的數字,該數字具有很高可能性是質數(除了1和它自身外,不能被其他自然數整除的數叫做質數)。如果從rand讀取時出錯,或者bits<2會返回錯誤
(3)func read(b []byte) (n int, err error)
本函式是一個使用io.readfull呼叫reader.read的輔助性函式。當且僅當err == nil時,返回值n == len(b)
2.2.2.2 應用場景
(1)生成隨機加密串
2.3 hpb區塊鏈系統的隨機數介紹
2.3.1 hpb 隨機數生成器
hpb 隨機數生成器是架構在區塊鏈的一種基礎服務。隨機數的實際實生產者為所有高效能節點(礦機)。隨機數服務的產生依賴與區塊鏈提供的共識服務和資料同步服務。如下圖 1 所示,hpb隨機數生成器有三層架構:隨機數種子生成層,隨機數計算層(驗證層)和隨機數呼叫層。
1. 隨機數種子層負責產生硬體隨機數種子,種子層一般有硬體擔任。
2. 隨機數計算層讀取硬體隨機數種子,將其寫入每一個區塊中,並收集之前區塊中的種子,在共識演算法的帶動下生成最終的隨機數。同時使用 vrf1可驗證函式輔助進行動態種子週期變換保證隨機數安全,以防止任意一個或者多個的隨機數生產者的攻擊。
3. 隨機數介面層提供了隨機數讀取介面,方便使用者使用。
2.3.2 hpb介面方式獲取隨機數
hpb區塊鏈系統可以透過rpc介面獲取歷史隨機數。
**1,介面定義 **
(1)透過rpc介面獲取歷史隨機數
介面名稱 :hpb_getrandom
引數 :塊號 ,整形數字或者字串”latest”
返回值:隨機數,string,
(2)使用“latest”查詢最新塊中的隨機數
呼叫示例:
curl -x post -h "content-type: application/json" --data
'{"jsonrpc":"2.0","method":"hpb_getrandom","params":["latest"],"id":1}' http://127.0.0.1:8545
返回示例:
{"jsonrpc":"2.0","id":1,"result":"0x45e5b62b748859b8eaf245406f5734244c5fef80d65f973b0a96407cf733db5
1"}
(3)查詢指定塊號的隨機數
呼叫示例:
curl -x post -h "content-type: application/json" --data
'{"jsonrpc":"2.0","method":"hpb_getrandom","params":["0x3f21"],"id":1}' http://127.0.0.1:8545
返回示例:
{"jsonrpc":"2.0","id":1,"result":"0x45e5b62b748859b8eaf245406f5734244c5fef80d65f973b0a96407cf733db5
1"}
2.3.3 hpb智慧合約方式獲取隨機數
hpb區塊鏈系統可以透過智慧合約使用最新隨機數;
在智慧合約中使用最新的隨機數,方式十分簡單,只需要呼叫block.random即可返回隨機數。
合約需要使用hpb官方的solidity編譯器進行編譯才能生效。
**合約示例 **
pragma solidity ^0.5.1;
contract mytest{
bytes32 random;
function getrandom()public {
random = block.random;
}
function print() view public returns(bytes32){
return random;
}
}
上述合約示例透過在hpb主網上部署後,執行getrandom函式,則將最新的隨機數寫入random變數。然後透過print函式列印隨機數。
3. 實現方案
3.1 隨機數演算法選擇
在生活中,抽獎搖號無所不在,涉及經濟、民生、教育、醫療、政務、住房、養老和娛樂等各個領域,如口罩預約搖號、彩票抽獎、車牌搖號、股票打新、入學搖號、新房搖號。參與大眾關心抽獎搖號系統的公平透明公正性,擔心這些系統是否因為中心化人為控制的原因,導致形成潛在的利益輸送,喪失抽獎搖號本身宣傳的公平透明公正的原則。
那麼,開發一款區塊鏈抽獎搖號系統,利用hpb區塊鏈真隨機數、時間可信、內容不可篡改、資料可追溯可查詢等特性,可以解決大眾的擔憂,實現真正的公平。
3.2 搖號的演算法流程
3.3 抽獎的演算法流程
原文連結:https://www.jianshu.com/p/517b0d497aa5
【“芯”球大戰-hpb芯鏈內容激勵計劃】
旨在鼓勵hpb芯鏈社羣的優秀創作者持續生產優質原創內容,讓社羣粉絲享受酣暢淋漓的內容體驗。歡迎hpb社羣的小夥伴積極參加【hpb芯鏈內容激勵計劃】,為hpb芯鏈社羣的繁榮貢獻自己的才華與力量!