Monero.門羅幣 隱匿交易的基礎介紹


今天要來簡單介紹一下,門羅幣是怎麼達到匿名交易的。本篇文章會牽涉到橢圓曲線的原理,如果不懂,可以先參考「加密技术核心算法之安全快捷的ECC算法」。簡單來說就是要知道這樣的關係: 
p = k*G , 
    p:公鑰    
    k:私鑰
    G:曲線上的基準點


門羅隱匿交易包含了三個技術:Ring Signature(環簽章)Ring Confidential Transactions (RingCT, 環保密交易)Stealth Address(隱匿位址)。在Digital Asset Research 的文章中這張圖解釋了各個技術所使用的地方,本篇文章,就是要介紹這三個技術。

source: https://medium.com/digitalassetresearch/monero-becomes-bulletproof-f98c6408babf


在介紹之前,先了解門羅鏈有些基本概念。在門羅中有兩把key(其實是4把,因為各有私鑰跟公鑰),一把是view key另一把是spend key。顧名思義,一把是拿來看的自己餘額的(在鏈上找隱匿位址),一把是拿來花的(做環簽章)。由spend key可以產生key image金鑰映像),用來做預防雙花的證明,有點像zcash的nullifier。


Ring Signature(環簽章)

環簽章有點像混幣,就是把好幾筆交易混在一起,不過還是有差異,可以參考「What are the technical advantages of Ring Signatures (CryptoNote) compared to CoinJoin?

那實際上怎麼做呢?! 假設一個初始值v,跟一串隨機數$(y_1, y_2, ..., y_n)$,然後把v跟隨機數經由$E_k$做加密,再把加密過的值跟下一個隨機數做運算(xor)再加密,如:$E_k(y_{n-1} {\oplus} E_k(y_n{\oplus}v))$,所以函數如下
$$C_{k,v}(y_1, y_2, ..., y_n) = E_k(y_1 \oplus E_k(y_2 \oplus ... E_k(y_n \oplus v)))$$
接著使 $C_{k,v}(y_1, y_2, ..., y_n) = v$,也就是v經過一連串的計算後,最後會等於自己,這就是環簽章的基本概念,如下圖形成一個環

實際應用場景會像這樣
m:訊息
$P_1, P_2, ..., P_n$:為任意的一組公鑰

1. 計算加密金鑰$k = Hash(m)$
2. 選擇隨機數v
3. 為所有的公鑰選擇隨機數 $(x_1, x_2, ..., x_n)$(不包含自己$x_s$),接著計算$y_i = g_i(x_i)$。
( $g_i = x_i^{P_i} mod N_i$ )
  * 也就是上述的隨機數 $y_i$,使用公鑰來產生
4. 藉由 $C_{k,v}(y_1, y_2, ..., y_n)$ 來求得自己的 $y_s$
5. 接著利用自己的私鑰算出 $x_s$,$x_s = g_s^{-1}(y_s)$
6. 最終,輸出環簽章 $σ = (x_1, x_2, ..., x_s, ..., x_n, v)$

驗證
1. 計算 $y_i = g_i(x_i)$, i = 1, 2, ..., n
2. 計算加密金鑰$k = Hash(m)$
3. 驗證 $C_{k,v}(y_1, y_2, ..., y_n) ?= v$

因為v跟$y_s$是相關的,而只有擁有私鑰的人才能從$y_s$算出$x_s$,因此其他人無法假造簽章。而環簽章有個特性,就是少了某一項,可以用其他項來算出少的那一項。因為簽章被混合過了,所以礦工無法直接驗證交易是否花過了,要怎麼確保雙花的問題?就要借助到金鑰映像(key image)的幫助,實際怎麼運作,後面的隱匿位址一起介紹。


Ring Confidential Transactions(環保密交易)

在RingCT(環保密交易)出現之前,因為環簽章的限制,混合環簽章的金額必須一樣,所以交易金額都必須被拆成固定面額,例如要交易12.5XMR,就需要拆成10, 2, 0.5三種面額,雖然發送方的資訊有環簽章做保護,但是交易的金額就暴露給所有人了。
環保密交易出現後(新版的環簽章"A Multi-layered Linkable Spontaneous Anonymous Group signature"所支援),金額將會被遮罩住,因此不必拆成已知面額,進而可以達到隱匿的作用。

Stealth Address(隱匿位址)

記得上面提到,每個人有兩把key(view key跟spend key)。假設Alice要轉錢給Bob,首先,Alice要利用Bob的public view key跟public spend key組成一次性的公鑰,計算如下
$$P = H(rA)G + B$$
r: Alice選的隨機數
A:Bob's public view key
B:Bob's public spend key
G:橢圓曲線中的基準點
H:hash function

然後計算 $R = rG$。接著把交易送到P所產生的位址,並將R值放入交易的內容。所以整個網路都會知道P跟R。
因為r是隨機數,每次產生出的一次性公鑰P都會是不同的,而由公鑰P產生出門羅的地址就叫做隱匿位址(stealth address)。Alice把交易送到隱匿地址後,Bob要怎麼知道這筆交易呢?

Bob有view key跟spend key對應的私鑰(a, b),Bob計算
$$P' = H(aR) + B$$
因為$aR = arG = rA$,所以可得$P' = H(aR) + B = H(rA) + B = P$
所以若$P' == P$就代表這筆交易是給自己的,而這個計算需要a: private view key,所以也就只有Bob可以計算得出來。Bob找到交易後可以算出對應的私鑰$x = H(aR) + b$,就可以動用這筆交易了!而這種方式,對於收款人來說是麻煩的,因為要隨時掃描鏈上的交易,才知道有沒有自己的。(有一種方式,是把自己的view key給第三方,由第三方幫你掃描,不過你的資產就會曝光,但是依然只有自己能動用)

回到雙花的問題上,上面有提到金鑰映像,先來看金鑰映像的算法
$$I = xH(P)$$
基本上是由一次性的公鑰P跟私鑰x組成,每一筆交易P只會對應到一把私鑰x,所以對於每筆交易P其金鑰映像I都是固定的,因此礦工只需要去驗證I是否有重複,就可以驗證是否雙花。


門羅的最新協議Bulletproof,是一種range proof,主要用於環保密交易(RingCT),藉由Bulletproof可以大大減少了驗證資料的大小,讓交易資料變小,而手續費得以減少,有機會再來深入探討Bulletproof。

擴展性(scalability)是門羅的一個大問題,主要是保密交易使用的rang proof的資料量龐大,使得交易的資料量很大,約是比特幣的10倍(使用bulletproof後),每次交易也都會有新的金鑰映像提供查詢,所有歷史交易的紀錄都需要保留,無法像比特幣有些技巧可以省略某些交易。這或許對門羅幣是個挑戰,但是另一派的說法,門羅幣的交易量不是重點,而是他提供的隱私性。各位覺得如何呢?

這是門羅非官方的台灣社群,裡面有很多門羅的介紹.技術文章跟最新進展等


若文章有誤或是解釋不清的,歡迎指正

reference:

留言

這個網誌中的熱門文章

What's New in Ethereum Serenity (2.0)

瑞士滑雪分享2 - 策馬特

動手實做零知識 - circom