STARKs, Part II: Thank Goodness It’s FRI-day
我們談到了,如何能夠做出一些非常有意思且簡潔的計算證明,比如通過利用多項式複合和除法技術,證明你算出了第一百萬個斐波那契數。但是,它依託於一個非常重要的元素:給定一個集合,裡面有很多的點,你必須能夠證明集合裡的大部分點都在同一個低次多項式上(譯者注:本文所譯的多項式度數或次數,皆對應 degree 一詞)。這個叫做“低次測試”的問題,可能是協議中最為複雜的部分。
首先,再次回顧一下我們的問題。假設有一些點,你聲稱它們都在同一個多項式上,並且該多項式的度少於 D(也就是說,如果度小於 2,意味著這些點在同一直線。如果度小於 3,意味著它們在同一直線或拋物線,等等)。而你想建立一個簡潔的概率證明,證明的確如此。
如果你想要驗證,這些點 全部 都在同一個度小於 D 的多項式上,那麼實際上你將不得不對每一個點進行檢查,因為哪怕是僅僅漏掉一個點,也可能會出現差錯:漏掉的這個點剛好不在這個多項式上,而其他點恰好都在上面。不過,你可以做的是,在所有的這些點中,概率性地檢測至少有部分(比如 90%)點都在同一個多項式上。
左上:可能足夠接近於某一多項式;右上:不夠接近某一多項式;左下:同時接近於兩個多項式,但是又不足以接近任意一個;右下:顯然不夠接近任一多項式
如果你能夠檢查多項式上的每一個點,那麼問題非常簡單。但是,如果你只能夠檢查幾個點呢?——也就是說,你可以要求檢查任意幾個點,作為協議的一部分,證明者也有義務給你這些點,但是查詢次數總數是有所限制的?那麼問題來了,你需要檢查多少個點,才能在一定程度上進行確認?
顯然,D 個點是不夠的。因為 D 個點恰好可以唯一定義一個度小於 D 的多項式,所以你得到的 任意 的點集合,都只會與某個度小於 D 的多項式相關。從上圖可以看出,D+1 或更多的點,肯定 可以給我們帶來更多資訊。
給定一些值,通過 D+1 次查詢,檢測這些值是否在同一個度小於 D 的多項式上,其演算法其實並不十分複雜。首先,從 D 個點中隨機挑選一個子集,並用像拉格朗日插值法(在 這裡 搜尋 “Lagrange interpolation” 獲得更多介紹)來還原這個唯一的度小於 D 的多項式,並且該多項式能夠通過這些所有的點。然後,隨機再取樣一個點,檢測該點是否在同一個多項式上。
第一步:選 D 個點;第二步:還原度小於 D 的多項式;第三步:再檢查一個點
注意,這僅僅是一個臨近測試(proximity test),因為無可避免地會出現這樣一種情況,即雖然大部分點都在同一個低次多項式上,但卻有另外一些點不在該多項式上,而第 D+1 個取樣點恰好完全地錯過了這些點。不過,我們可以對結果進行派生,如果在同一個度小於 D 的多項式上的點低於 90%,那麼測試將很大可能失敗。具體來說,如果你進行 D+k 次查詢,有至少 p% 的點不在同一個多項式上,而其他點卻在上面,那麼通過測試的概率僅有 (1-p) ^k。
但是,如果像上一篇文章的例子那樣, D 非常大,而你想要在少於 D 次查詢的情況下,驗證一個多項式的度,那該怎麼辦呢?當然,這不太可能直接“對症下藥”, 因為上面已作出了簡單的論證(即,任意 k <= D 個點至少全部都在一個度小於 D 的多項式上)。但是,通過提供輔助資料,間接地進行驗證還是非常有可能的,並且能夠獲得大幅地效率提升。這就是像 FRI(“Fast RS IOPP”,RS=“Reed-Solomon”, IOPP = “Interactive Oracle Proofs of Proximity”) 這樣的新協議想要做的事情,它與早先叫做近似概率可檢驗性證明(probabilistically checkable proofs of proximity (PCPPs) )的設計相類似。
初識亞線性
為了證明這一切都是可行的,我們從一個相對簡單的協議開始,雖然有非常粗糙的折衷操作,但是仍然可以達到亞線性驗證複雜度的目的——也就是說,你可以通過少於 D 次查詢,近似證明一個度小於 D 的多項式(在這裡也就是,通過少於 O(D) 次計算來對證明進行驗證)=
思路如下。假設有 N 個點(比方說 N 等於 10 億),並且它們都在一個度小於 1,000,000 的多項式 f(x) 上。我們找到一個二元多項式(像 1 + x + xy + x5*y3 + x^12 + x*y^11 這樣的表示式),表示為 g(x, y),並且 g(x, x^1000) = f(x)。通過如下操作即可完成:對於 f(x) 中第 k 度項(比如,1744 * x^185423),我們將它分解為 x^(k % 1000) * y^floor(k / 1000)(在該例中,1744 * x^423 * y^185)。你可以看到,如果 y = x^1000,那麼 1744 * x^423 * y^185 等於 1744 * x^185423。
在證明的第一階段,證明者提交在整個正方形上 [1…N] x {x^1000: 1 <= x <= N} 上 g(x, y) 的值(也就是說,求一個 Merkle 樹)——也就是,列上的所有 10 億個 x 座標,以及所有 10 億個對應的行上 y 座標的一千次。正方形的對角線表示 g(x, y) 的值,其形式為 g(x, x^1000),因此關聯到 f(x) 的值。
然後,驗證者可能隨機選出幾十行和幾十列(如果我們想要一個非互動式的證明,可能使用 the Merkle root of the square as a source of pseudorandomness),對於所選的每一行或列,比如說,驗證者要求從行和列的 1010 個點中取樣一個點,以確保在每種情況下,要求的點都在對角線上。證明者必須對這些點作出迴應,通過 Merkle 分支,證明它們是給證明者提交原始資料的一部分。驗證者檢查 Merkle 分支的確相匹配,這表明證明者所提供的這些點確實與 1000 次多項式相關。
這給了驗證者一個統計證明:
大部分行主要被度小於 1000 的多項式上的點所填充
大部分列主要被度小於 1000 的多項式上的點所填充
對角線大部分都在這些多項式上
因而,這使得驗證者相信在對角線上的大部分點,確實與一個次數小於 1,000,000 的多項式相關。
如果我們選出 30 行和 30 行列,驗證者需要檢測總共 1010 個點 * 60 行+列 = 60600 個點,雖然少於原始的 1,000,000 個點,但仍是差強人意。就計算時間而言,儘管由於多項式插值可以變為次二次(subquadratic),但對度小於 1000 的多項式進行插值,也有其自身的開銷,從整體上看,演算法驗證仍是亞線性的。證明者的複雜度更高了:證明者需要計算並提交整個 N*N 長方形,這總共是 10^18 的計算成本(實際上還要更多一點,因為多項式求值仍然是超線性(superlinear)的)。在所有的這些演算法中,對計算進行證明,遠比單單執行該計算要複雜的多,但是我們將會看到,其實這些開銷並非需要如此地高。
模組化數學插曲
在深入到更復雜的協議之前,我們需要稍微偏離下主題,討論一下模組化數學(modular math)。通常,當面對代數表示式和多項式時,我們所面對的是使用的是 +,-,/(還有求冪,不過它實際只是重複的乘法而已)這樣操作符的常規數字和運算,這些都是我們在學校裡面就學會的知識:2 + 2 = 4, 72 / 5 = 14.4, 1001 * 1001 = 1002001 等等。但是,數學家們已經意識到,這些定義加法,乘法,減法和除法的方式,並不是唯一*定義這些操作符的自洽(self-consistent)方式。
定義這些操作符,另一種可替代也是最簡單的例子是,下面定義的模組化數學。% 操作符代表“取餘”,15 % 7 = 1, 53 % 10 = 3, 等等(注意答案始終是非負的,比如 -1 % 10 = 9)。對於任意指定的素數 p,我們可以重新定義:
x + y —> (x + y) % p
x * y —> (x * y) % p
x ^ y —> (x ^ y) % p
x - y —> (x - y) % p
x / y —> (x * y ^ (p-2)) % p
上面的例子都是自洽的。比如,如果 p = 7, 那麼:
5 + 3 = 1 (as 8 % 7 = 1)
1 – 3 = 5 (as -2 % 7 = 5)
2 * 5 = 3
3 / 5 = 2 (as (3 * 55) % 7 = 9375 % 7 = 2)
對於像分配律這樣更復雜的內容同樣成立: (2 + 4)3 和 2 * 3 + 4 * 3 都等於 4。在這種新的數學中,甚至像 (a2-b2)=(a-b)(a+b) 也仍然是成立的。除法是其中最困難的部分:我們無法使用常規除法,因為我們想要結果始終是整數,但是常規除法常常會得到非整數的結果(比如 3/5)。在上面的除法公式中,p-2 次冪是一個使用 費馬小定理 直面該問題的結果,它表示對於任意非零的 x < p,都有 x^(p-1)%p = 1.這表明 x^(p-2) 給出一個數,如果再乘以一個 x,得到 1,所以我們可以說 x^(p-2)(是一個整數)等於 1/x。對模組化除法操作符求值,一個有點更為複雜,但是更快的方式是 擴充套件歐幾里得演算法,其 Python 實現在 這裡。
由於數字“環繞”,模組化數學有時又叫“時鐘數學”
通過模組化數學,我們已經創立了一個全新的數學系統,因為它與傳統數學在各個方面都是自洽的,所以我們在模組化數學裡面討論各種同樣的結構,包括我們以“常規數學”論之的多項式。密碼學家喜歡用模組化數學(或者,更通俗一點,“有限域”),因為一個數字的大小有界,它可以作為任意一個模組化數學的計算結果——無論你做什麼,值都不會“跳出” {0, 1, 2 … p-1}的範圍。
費馬小定理還有另一個有趣的結論。如果 p-1 是某個數 k 的倍數,那麼函式 x -> x^k 有一個小的“像(image)”——也就是,這個函式只能夠給出 (p-1)/k + 1 個可能的結果。比如, x -> x^2 在 p=17 時,只有 9 個可能的結果。
指數越高,效果越明顯:比如,x -> x^8 在 p = 17 時,只有 3 個可能的結果。當然, x -> x^16 在 p=17 是隻有 2 個可能的結果。如果是 0,返回 0,其他任何都返回 1.
淺談效率
讓我們來繼續討論一個稍微複雜點的協議,它的目標在於,將證明者的複雜度從 10^18 降至 10^15,繼而降至 10^9。首先,我們並不是針對常規數字進行操作,而是使用模組化數學檢查多項式的近似程度。正如在上篇文章所述,在
STARKs 中,我們無論如何都要防止數字增長至 200,000 位。但是在這裡,我們將要利用確定的模冪(modular exponentiation)的“小像(small image)”屬性,並將其視作為一個副作用,來使得我們的協議更有效率。
具體來說,我們將選用 p = 1,000,005,001。之所以選擇這個係數(modulus),是因為:
它比 10 億大,因為我們需要它至少是 10 億,這樣才能檢測 10 億個點。
它是質數
p-1 是 1000 的偶數倍。
冪 x^1000 的像大小為 1,000,006 ——也就是說,這個冪只有 1,000,006 個可能的結果。
這意味著“對角線”(x, x^1000) 現在變成了一個被包著(with a wraparound)的對角線;因為 x^1000 只可以取 1,000,006 個可能值,所以我們僅需要 1,000,006 行。故而,g(x, x^1000) 的所有取值現在只有 ~10^15 個元素。
這表明,我們可以更進一步地:讓證明者僅提交在一個單列上 g 的值。關鍵技巧在於,原始資料本身已經包含了 1000 個點,而這些點在給定的任意行上,所以我們可以簡單取樣這些點,推匯出它們所在的度小於 1000 的多項式,然後檢查列上相關的點在同一個多項式上。再接著檢查列本身是一個小於 1000 的多項式。
雖然驗證者複雜度仍然是亞線性的,但是證明者複雜度已經降到了 10^9,並與查詢次數成線性關係(儘管在實踐中由於多項式求值的開銷,仍是超線性的)。
二談效率
雖然證明者複雜度現在已經無法再低了,但是我們仍然可以進一步地降低驗證者複雜度,即從二次降至對數。我們的方法是讓演算法遞迴。從上面談到的協議開始,但是並非試圖將一個多項式嵌入到一個 x 和 y 度相等的二維多項式中,我們將多項式嵌入到一個二維多項式中,該二維多項式的度 x 下界是一個小的常量值。簡單來說,我們甚至可以說就是 2 。也就是說,我們表示 f(x) = g(x, x^2),所以行檢驗僅需每個取樣行的 3 個點(2 個來自對角線,還有 1 個來自列)。
如果原始多項式的度小於 n,那麼行的度小於 2(也就是說,這些行是直線),列的度小於 n/2。因此,我們現在得到的是一個線性時間過程,它將證明一個度小於 n 的近似多項式問題轉變為證明度小於 n/2 的問題。進一步地,需要提交的點數,和證明者的計算複雜度,每次會減少 1/2(Eli BenSasson 喜歡將 FRI 的這一點與fast fourier transforms相比較,與 FFT 不同的關鍵在於,每一步遞迴都只進入一個新的子問題,而不是將問題一分為二
)。因此,我們可以簡單地繼續使用在上一輪協議所建立的列上的協議,直到列變得足夠小,小到我們可以簡單地直接檢查。整體複雜度大概是 n + n/2 + n/4 + … ~= 2n.
實際上,協議將需要被重複多次,因為仍有極大的可能,攻擊者會在協議的某一輪作弊。但是,只要證明不是太大,驗證複雜度在量級上仍然是對數級,儘管它會上升到 log^2(n) ,如果你把 Merkle 證明的大小也算進去的話。
“真正”的 FRI 協議也有一些其他的修改。比如,它使用一個二分的 Galois 域(另一種奇怪的有限域。本質上,與我在
這裡 討論的第 12 度擴充套件域是同樣的東西,不過素數模是 2
)。行所使用的指數通常是 4 而不是 2。這些修改提升了效率,並使系統更加友好,在上面更易構建 STARKs。但是,對於理解演算法的工作原理,這些修改並非十分必要。如果你真的想要理解演算法的話,利用這裡所述的基於模組化數學的 FRI,雖然簡單了一點,但是應付 STARKs 絕對是夠了。
可靠性
我必須要提醒 計算可靠性(calculating soundness) ——也就是,無論概率有多低,對於給定次數的檢查,一個經過優化後的假證明,仍可能會通過測試。——這依舊是這個領域中的“危險”地帶。可以簡單測試一下,取 1,000,000 + k 個點,有一個簡單的下界:如果一個給定的資料集有這樣一個屬性,對於任意多項式,資料集中至少有 p% 的點沒有在多項式上,那麼在該資料集通過測試的概率將至多是(1-p)^k。但是,即使下界很低——比如,不可能同時有超過 50% 的點接近兩個低次多項式,並且你首先選擇的點會是上面最多的點的概率相當低。對於一個成熟的 FRI 來說,仍會涉及各種特定型別攻擊的複雜度。
這裡 是 Ben-Sasson 等人最近的一篇文章,裡面在完整的 STARK fang’an背景下,介紹了 FRI 的可靠性屬性。總的來說,“好訊息”是,為了在 STARK 上通過 D(x) * Z(x) = C(P(x)) 檢查,一個無效方案的 D(x) 將需要是某種意義上的“最壞情況” – 他們需要最大化地遠離任意有效的多項式。這表明,我們不需要檢查那麼近的距離。雖然有已證明的下界,但是這些界限表明一個真正的 STARK 在大小上需要 ~1-3 MB;一個屬於推測尚未被證明的更嚴格界限,減少所需檢測次數的 1/4。
第三部分,將討論構建 STARKs 的最後一個主要的挑戰:如何構建約束檢查多項式(constraint checking polynomial),才能夠證明任意的計算語句,而不僅僅是幾個斐波那契數。
原文連結: https://vitalik.ca/general/2017/11/22/starks_part_2.html
作者: Vitalik Buterin
翻譯&校對: & Elisa
liuchengxu的簡書: https://www.jianshu.com/u/daf68451f175