所谓零知识证明,指的是在不泄露秘密的前提下,证明我知道这个秘密。
例子网上有很多, 具体要做到这一点,需要引入一个概念,叫做同态隐藏。
已知两个数 x x x和 y y y,需要在不泄露这两个数的前提下,证明 x + y = 5 x+y=5 x+y=5
要实现这一点,我们需要引入一个同态隐藏函数 E ( x ) E(x) E(x),该函数满足下面3个条件:
这个同态隐藏函数,用普通的加减乘除运算是没法实现的,我们需要引入2个新的运算。
p可以是任意整数,不过为了获得一些特殊性质,p一般取一个素数,比如7。
所谓模p加法,就是加完之后对p取模(除以p取余数)。比如下面的例子:
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
$(x+1) | _{mod7} $ | 1 | 2 | 3 | 4 | 5 |
我们把集合 { 0 , 1 , . . . , p − 1 } \{0,1,...,p-1\} {0,1,...,p−1}跟模p加法运算一起称为一个有限群。
集合的元素个数称为有限群的阶,所以上面是一个7阶有限群。
和模p加法类似,模p乘法就是相乘之再对p取模。比如下面的例子:
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
$(x*2) | _{mod7} $ | 1 | 2 | 3 | 4 | 5 |
显然,这也是一个7阶有限群。
另外还有一个有趣的现象,如果让集合 { 1 , . . . , p − 1 } \{ 1 ,..., p − 1 \} {1,...,p−1} 中的每个元素对自身不断地做模p乘法(即乘方),观察我标红的那两行:
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
$1^x | _{mod7} $ | 1 | 2 | 3 | 4 | 5 | |
$2^x | _{mod7} $ | 1 | 2 | 3 | 4 | 5 | |
$3^x | _{mod7} $ | 1 | 2 | 3 | 4 | 5 | |
$4^x | _{mod7} $ | 1 | 2 | 3 | 4 | 5 | |
$5^x | _{mod7} $ | 1 | 2 | 3 | 4 | 5 | |
$6^x | _{mod7} $ | 1 | 2 | 3 | 4 | 5 |
有没有发现,集合 { 1 , . . . , p − 1 } \{ 1 ,..., p − 1 \} {1,...,p−1}中的每个元素都可以被生成出来(只不过顺序被打乱了)?这种群被称为循环群,元素3或者5称为一个生成元。实际上,所有素数阶的有限群都是循环群。
有了上面这些背景知识,我们就可以来寻找同态隐藏函数 E ( x ) E(x) E(x)了。
在上面的例子里,生成元 g ∈ { 3 , 5 } g \in \{3,5 \} g∈{3,5}。假设我们取3, 定义 E ( x ) = g x ∣ m o d p = 3 x ∣ m o d 7 E(x) = g^x|_{modp} = 3^x|_{mod7} E(x)=gx∣modp=3x∣mod7
这个 E ( x ) E(x) E(x)函数是不是真的满足之前提到的3个条件呢? 我们来确认一下:
上面的公式 应用了费马小定理_百度百科 (baidu.com)
好了,现在我们有同态隐藏函数了,接下来通过实际的例子加深理解。
我们要保护的秘密是 x = 2 , y = 3 x=2,y=3 x=2,y=3我们计算出 E ( x ) E(x) E(x)和 E ( y ) E(y) E(y),把他们的值提供给验证者:
E ( x ) = E ( 2 ) = 3 2 ∣ m o d 7 = 9 ∣ m o d 7 = 2 E(x)=E(2) = 3^2|_{mod7} = 9|_{mod7} = 2 E(x)=E(2)=32∣mod7=9∣mod7=2
E ( y ) = E ( 3 ) = 3 3 ∣ m o d 7 = 27 ∣ m o d 7 = 6 E(y)=E(3) = 3^3|_{mod7} = 27|_{mod7} = 6 E(y)=E(3)=33∣mod7=27∣mod7=6
验证者验证 E ( x + y ) E(x+y) E(x+y)是否等于 E ( 5 ) E(5) E(5)
E ( x + y ) = E ( x ) ⋅ E ( y ) = 2 ⋅ 6 m o d 7 = 12 ∣ m o d 7 = 5 E(x+y)=E(x)·E(y) = 2·6_{mod7} = 12|_{mod7} = 5 E(x+y)=E(x)⋅E(y)=2⋅6mod7=12∣mod7=5
E ( 5 ) = 3 5 ∣ m o d 7 = 243 ∣ m o d 7 = 5 E(5) = 3^5|_{mod7} = 243|_{mod7} = 5 E(5)=35∣mod7=243∣mod7=5
验证成功! 现在验证者可以确认我知道 x x x跟 y y y的值, 并且 x + y = 5 x+y = 5 x+y=5,但是,他并不知道 x x x和 y y y的具体值是多少,我们目的达到了.
总结一下:同态隐藏就是通过一种特殊的映射函数,打乱原始数据的顺序。根据映射值不能反推出原始值,但是映射值之间的关系可以反映原始值之间的关系。
我们知道了同态隐藏. 假设取 E ( x ) = g x E(x) = g^x E(x)=gx,则 E ( x + y ) E(x+y) E(x+y)可以通过 E ( x ) E(x) E(x)和 E ( y ) E(y) E(y)计算出来 E ( x + y ) = E ( x ) ⋅ E ( y ) E(x+y)=E(x)⋅E(y) E(x+y)=E(x)⋅E(y)
实际上,不仅仅支持加法,支持所有"线性组合"的同态隐藏,比如 E ( a x + b y ) E(ax+by) E(ax+by):
E ( a x + b y ) = g a x + b y = g a x ⋅ g b y = ( g x ) a ⋅ ( g y ) b = E ( x ) a ⋅ E ( y ) b E(ax+by) = g^{ax+by}= g^{ax}·g^{by}= (g^x)^a·(g^y)^b = E(x)^a⋅E(y)^b E(ax+by)=gax+by=gax⋅gby=(gx)a⋅(gy)b=E(x)a⋅E(y)b
需要注意的是,上面的加法和乘法运算都是模p运算。
假设现在有一个d次多项式 P ( X ) = a 0 + a 1 ⋅ X + a 2 ⋅ X 2 + . . . + a d ⋅ X d P(X) = a_0 +a_1·X + a_2 · X^2 + ... + a_d · X^d P(X)=a0+a1⋅X+a2⋅X2+...+ad⋅Xd,其中系数 a 0 , . . . , a d ∈ { 0 , . . . , p − 1 } a_0,...,a_d \in \{0,...,p-1\} a0,...,ad∈{0,...,p−1}是Alice需要保护的密码.根据上面的特性,我们可以计算出 E ( P ( X ) ) E(P(X)) E(P(X)):
E ( P ( X ) ) = E ( 1 ) a 0 ⋅ E ( X ) a 1 ⋅ E ( X 2 ) a 2 ⋅ . . . ⋅ E ( X d ) a d E(P(X)) = E(1)^{a_0} ·E(X)^{a_1}· E(X^2)^{a_2}·...· E(X_d)^{a_d} E(P(X))=E(1)a0⋅E(X)a1⋅E(X2)a2⋅...⋅E(Xd)ad
现在Bob想来验证Alice是不是真的知道这些秘密,于是他决定随机指定一个数 s s s,要求Alice计算 E ( P ( X ) ) E(P(X)) E(P(X))等于多少。但是,Bob不想直接把 s s s的值告诉Alice,也就是说,这个 s s s是Bob的秘密。显然,这又需要一次同态隐藏,也就是说,Bob把下面这些值提供给Alice:
$ E(s), E(s^2), E(s^3),…, E(s^d)$
然后Alice就可以根据上面的公式计算 E ( P ( s ) ) E(P(s)) E(P(s))的值
E ( P ( s ) ) = E ( 1 ) a 0 ⋅ E ( s ) a 1 ⋅ E ( s 2 ) a 2 ⋅ . . . ⋅ E ( s d ) a d E(P(s)) = E(1)^{a_0} ·E(s)^{a_1}· E(s^2)^{a_2}·...· E(s_d)^{a_d} E(P(s))=E(1)a0⋅E(s)a1⋅E(s2)a2⋅...⋅E(sd)ad
最终的效果是:在Bob不知道P(X)中的系数是多少,而Alice也不知道s等于多少的情况下,完成多项式的验证。这就是所谓的"多项式盲计算"。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8VpF15Ue-1641909734691)(https://xgihytg6nh.feishu.cn/space/api/box/stream/download/asynccode/?code=YzI2YTU0OGZiNmRkZTQwZjc0NGI5MTExYjU4YmQyNTFfTHhja3F3R1l2SHAycGZIVHdRNHoxV3I2eFFmb2RsY3JfVG9rZW46Ym94Y25NMUxBUzdLRks2bnpacWZzSFhoVDJmXzE2NDE5MDk1Njk6MTY0MTkxMzE2OV9WNA)]
下面举个例子来加深理解, 假设 P ( X ) = 1 + 2 X + 3 X 2 , E ( X ) = 3 x , p = 7 P(X) = 1 + 2X+3X^2, E(X) = 3^x,p=7 P(X)=1+2X+3X2,E(X)=3x,p=7
Bob想验证 s = 2 s=2 s=2 这一点上的 E ( P ( s ) ) E(P(s)) E(P(s))的值,那么他需要提供这2个值,: E ( s ) = 2 , E ( s 2 ) = 4 E(s) =2, E(s^2) =4 E(s)=2,E(s2)=4
然后Alice根据这3个值计算 E(P(s)) 的值返回给Bob:
E ( P ( s ) ) = E ( 1 ) 1 ⋅ E ( s ) 2 ⋅ E ( s 2 ) 3 = 3 ⋅ 4 ⋅ 64 ∣ m o d 7 = 768 ∣ m o d 7 = 5 E(P(s) ) = E(1)^1 · E(s)^2 · E(s^2)^3 = 3 · 4 · 64 |_{mod7} = 768 |_{mod7} = 5 E(P(s))=E(1)1⋅E(s)2⋅E(s2)3=3⋅4⋅64∣mod7=768∣mod7=5
最后,我们来看一下 E ( P ( 2 ) ) E(P(2)) E(P(2)) 是不是真的等于5:
E ( P ( 2 ) ) = E ( 1 + 2 ⋅ 2 1 + 3 ⋅ 2 2 ) = E ( 17 ∣ m o d 6 ) = E ( 5 ) = 3 5 ∣ m o d 7 = 243 ∣ m o d 7 = 5 E(P(2) ) =E(1 + 2· 2^1 + 3·2^2)= E(17|_{mod6}) = E(5) = 3^5|_{mod7} = 243|_{mod7} = 5 E(P(2))=E(1+2⋅21+3⋅22)=E(17∣mod6)=E(5)=35∣mod7=243∣mod7=5
实际上,这背后依赖的理论基础是Schwartz-Zippel引理:在一个很大的集合中随机选择一组数,满足某个多项式取值的概率几乎为0。因此,随机选一个点,然后在Alice不知道该点的值的情况下,提供多项式的值以供Bob验证。
随机算法 (2): Schwartz–Zippel引理与完美匹配 - 知乎 (zhihu.com)
那么问题来了:Bob怎么验证Alice提供的 E ( P ( s ) ) E(P(s)) E(P(s))的值对不对呢?
要实现这一目标,需要先介绍一个概念:α对。
在有限循环群G中,如果 $ \alpha , \beta ≠ 0 且 b = \alpha · a 那 么 就 称 那么就称 那么就称(a,b)$为一个α对。
也就是说,b是a的α倍(模p)。有了这个概念,就可以进行一项"系数知识测试":
乍一看有点迷糊,既然$b = \alpha · a $,那么Alice不就可以反推出α等于多少了吗? ?请注意:这里的乘法是模p乘法。举个例子就清楚了:
假设Bob选定 $a=2, α=4, 那么 b = α · a = 4·2 |_{mod7} = 1 $所以最终生成的α对是(2,1),Alice没法反推出α的值是多少(在p非常大的情况下,这是一个离散对数难题)。
既然Alice不知道α,那么她就只有一种方法可以生成新的α对:给a和b各乘上同一个系数γ
举个例子,假设Alice秘密选定γ = 5,那么新生成的α对:
( a ′ , b ′ ) = ( γ ⋅ a , γ ⋅ b ) = ( 5 ⋅ 2 ∣ m o d 7 , 5 ⋅ 1 ∣ m o d 7 ) = ( 3 , 5 ) (a',b')=(\gamma · a, \gamma · b )= (5·2| _{mod7},5·1|_{mod7}) = (3,5) (a′,b′)=(γ⋅a,γ⋅b)=(5⋅2∣mod7,5⋅1∣mod7)=(3,5)
Bob收到这个新的α对 ( a ′ , b ′ ) (a',b') (a′,b′) 之后,验证 α ⋅ a = 4 ⋅ 3 ∣ m o d 7 = 12 ∣ m o d 7 = 5 = b ′ α·a = 4·3 |_{mod7} = 12|_{mod7} = 5 = b' α⋅a=4⋅3∣mod7=12∣mod7=5=b′接受该回复。
也就是说,Alice秘密持有 γ,Bob秘密持有 α. 跟上一篇文章中的图拼到一起:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-66jtCOCk-1641909734692)(https://xgihytg6nh.feishu.cn/space/api/box/stream/download/asynccode/?code=OTU1Mzk4YTMxOGVmMzMxN2VmMDk0NjJhMWJjNjUyMjlfWnFkcDQwMTNQSHY4VFB5VlYxT0xNNXlXQVJDM1NyTnBfVG9rZW46Ym94Y25aV2U4ZlV5TlAyTWw2bGs4U2tWRXliXzE2NDE5MDk1Njk6MTY0MTkxMzE2OV9WNA)]
这就是所谓的"系数知识假设",英文是"Knowledge of Coefficient Assumption",简称KCA。一句话概括:所谓KCA,指的是如果Alice成功回复了一个α对,那么她一定持有某个 γ \gamma γ使得 a ′ = γ ⋅ a a' = \gamma · a a′=γ⋅a
这篇文章正式介绍一下Bob如何验证Alice发过来的 E ( P ( s ) ) E(P(s)) E(P(s)) 的值是否正确. 实际上,我们想要实现的目的:
要实现第2个目标,需要用到上一篇文章里介绍的α对和KCA的概念。
上一篇文章里的KCA只用到了一个α对,我们可以扩展一下,让Bob给Alice发送多个α对(使用同一个α):
( a 1 , b 1 ) , ( a 2 , b 2 ) , . . . . , , ( a d , b d ) (a_1,b_1),(a_2,b_2),....,,(a_d,b_d) (a1,b1),(a2,b2),....,,(ad,bd)
Alice需要回复一个α对,根据之前介绍的方法,她可以从上面的α对中随机挑选一个 ( a i , b i ) (a_i,b_i) (ai,bi)然后各自乘以一个系数: ( a ′ , b ′ ) = ( c ⋅ a i , c ⋅ b i ) (a',b')= (c·a_i,c·b_i) (a′,b′)=(c⋅ai,c⋅bi)那么,除此之外,还有没有其他方法生成新的α对呢?答案是肯定的,我们可以通过"线性组合"来生成。
举个例子,随机选2个系数 c 1 , c 2 c_1,c_2 c1,c2,生成新的α对 ( a ′ , b ′ ) = ( c 1 ⋅ a 1 + c 2 ⋅ a 2 , c 1 ⋅ b 1 + c 2 ⋅ b 2 ) (a',b')= (c_1·a_1+c_2·a_2,c_1·b_1+c_2·b_2) (a′,b′)=(c1⋅a1+c2⋅a2,c1⋅b1+c2⋅b2)
我们来证明一下:
b ′ = c 1 ⋅ b 1 + c 2 ⋅ b 2 = c 1 ⋅ α ⋅ a 1 + c 2 ⋅ α ⋅ a 2 = α ⋅ ( c 1 ⋅ a 1 + c 2 ⋅ a 2 ) = α ⋅ a ′ b' = c_1 · b_1 + c_2 ·b_2 = c_1 · α ·a_1 + c_2 · α · a_2 = α ·(c_1 ·a_1 + c_2 ·a_2) = α · a' b′=c1⋅b1+c2⋅b2=c1⋅α⋅a1+c2⋅α⋅a2=α⋅(c1⋅a1+c2⋅a2)=α⋅a′
可以发现,确实是一个α对。我们可以通过求和符号写出新α对的一般形式:
( a ′ , b ′ ) = ( ∑ i = 1 d c i a i , ∑ i = 1 d c i b i ) (a',b') = (\sum_{i=1}^{d}{c_ia_i},\sum_{i=1}^{d}{c_ib_i}) (a′,b′)=(∑i=1dciai,∑i=1dcibi)
根据上面的分析,可以引出一个**“d阶系数知识假设”,简称d-KCA**:
假设G是一个有限循环群,g是它的一个生成元。Bob选取一个α和一个s,然后把下面这些α对发送给Alice:
( g , α , g ) , ( s ⋅ g , α s , g ) , . . . , ( s d ⋅ g , α s d , g ) (g,α,g), (s·g,α_s,g),..., (s^d·g,αs^d,g) (g,α,g),(s⋅g,αs,g),...,(sd⋅g,αsd,g)
如果Alice成功回复了一个新的α对,那么Alice一定持有一组 c 0 , c 1 , . . . , c d c_0,c_1,...,c_d c0,c1,...,cd使得$ a’ = \sum_{i=1}^{d}{c_i·s_i}$
可以发现,Bob发的这组α对不是随便给出来的,对应d次多项式的每一项。
有了d-KCA的保证,我们就可以来验证Alice给出的盲计算结果了:
假设G是一个有限循环群,g是它的一个生成元
选择同态隐藏函数$ E(x) = x·g$
Bob随机选择一个α和一个s,把生成的α对发送给Alice:
( a 0 , b 0 ) = ( E ( 1 ) , α ⋅ E ( 1 ) ) (a_0,b_0) = (E(1),α·E(1)) (a0,b0)=(E(1),α⋅E(1))
( a 1 , b 1 ) = ( E ( s ) , α ⋅ E ( s ) ) (a_1,b_1) = (E(s),α·E(s)) (a1,b1)=(E(s),α⋅E(s))
. . . ... ...
( a d , b d ) = ( E ( s d ) , α ⋅ E ( s d ) ) (a_d,b_d) = (E(s^d),α·E(s^d)) (ad,bd)=(E(sd),α⋅E(sd))
Alice需要保守的秘密是P(X) 的系数 P ( X ) = a 0 + a 1 ⋅ X + a 2 ⋅ X 2 + . . . + a d ⋅ X d P(X) = a_0 +a_1·X + a_2 · X^2 + ... + a_d · X^d P(X)=a0+a1⋅X+a2⋅X2+...+ad⋅Xd
Alice 计算新的α对:
$ a’ = P(s)·g = c_0·g + c_1·s·g +…+ = c_d·s^d·g =c_0·a_0 + c_1·a_1+…c_d·a_d =\sum_{i=0}^{d}{c_ia_i}$
b ′ = α ⋅ a ′ = ∑ i = 0 d c i ⋅ α ⋅ a i = ∑ i = 0 d c i ⋅ b i b' = α ·a' =\sum_{i=0}^{d}{c_i·α·a_i} = \sum_{i=0}^{d}{c_i·b_i} b′=α⋅a′=∑i=0dci⋅α⋅ai=∑i=0dci⋅bi
然后把 ( a ′ , b ′ ) (a',b') (a′,b′)发送给Bob
经过这一过程,Bob就可以确认Alice确实知道这组系数了(根据d-KCA)。因此,我们把上一篇文章中的图改一下,让Alice知道的2个秘密合二为一,就可以得到下面这张图了:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QKnNZaqt-1641909734694)(https://xgihytg6nh.feishu.cn/space/api/box/stream/download/asynccode/?code=N2RjYjE5YmFjYWUxMmRkNTAwMmJhMTQ1OGYzNzk0YzVfTGpyd2ZwWDhkS2RLc2RTTkt4ZjZmZ1lhSW9uVWp0cmVfVG9rZW46Ym94Y25hTnE0R2ZJUEVUWmJiaHlhZFNRTGZoXzE2NDE5MDk1Njk6MTY0MTkxMzE2OV9WNA)]
最终的效果是:在Bob不知道P(X)中的系数,Alice也不知道α跟s的情况下,确认了Alice的确知道这组多项式系数。
还是举个简单的实例,
假设 g = 3 , d = 2 , p = 7 , E ( x ) = x ∗ g g=3,d=2,p=7,E(x) = x * g g=3,d=2,p=7,E(x)=x∗g
Bob随机选择一组系数 s = 2 , α = 4 s=2,α = 4 s=2,α=4 然后把3个α对发送给Alice
( a 0 , b 0 ) = ( E ( 1 ) , α ⋅ E ( 1 ) ) = ( 3 , 4 ⋅ 3 ∣ m o d 7 ) = ( 3 , 5 ) (a_0,b_0) = (E(1),α·E(1)) = (3,4·3|_{mod7}) = (3,5) (a0,b0)=(E(1),α⋅E(1))=(3,4⋅3∣mod7)=(3,5)
( a 1 , b 1 ) = ( E ( s ) , α ⋅ E ( s ) ) = ( 2 ⋅ 3 ∣ m o d 7 , 4 ⋅ 2 ⋅ 3 ∣ m o d 7 ) = ( 6 , 3 ) (a_1,b_1) = (E(s),α·E(s)) = (2·3|_{mod7},4·2·3|_{mod7}) = (6,3) (a1,b1)=(E(s),α⋅E(s))=(2⋅3∣mod7,4⋅2⋅3∣mod7)=(6,3)
( a 2 , b 2 ) = ( E ( s 2 ) , α ⋅ E ( s 2 ) ) = ( 2 2 ⋅ 3 ∣ m o d 7 , 4 ⋅ 2 2 ⋅ 3 ∣ m o d 7 ) = ( 5 , 6 ) (a_2,b_2) = (E(s^2),α·E(s^2)) = (2^2·3|_{mod7},4·2^2·3|_{mod7}) = (5,6) (a2,b2)=(E(s2),α⋅E(s2))=(22⋅3∣mod7,4⋅22⋅3∣mod7)=(5,6)
假设Alice持有的多项式为 P ( X ) = 1 + 2 X + 3 X 2 P(X) = 1 + 2X+3X^2 P(X)=1+2X+3X2在收到Bob的α对之后,计算新的α对:
$ a’ =\sum_{i=0}^{2}{c_i·a_i} = 1 · a_0 +2 · a_1 + 3 · a_2 = 1 · 3 +2 ·6+3·5 |{mod7} = 30|{mod7} = 2$
b ′ = ∑ i = 0 2 c i ⋅ b i = 1 ⋅ b 0 + 2 ⋅ b 1 + 3 ⋅ b 2 = 1 ⋅ 5 + 2 ⋅ 3 + 3 ⋅ 6 ∣ m o d 7 = 30 ∣ m o d 7 = 2 b' =\sum_{i=0}^{2}{c_i·b_i} = 1 · b_0 +2 · b_1 + 3 · b_2 = 1 · 5 +2 ·3+3·6 |_{mod7} = 30|_{mod7} = 2 b′=∑i=02ci⋅bi=1⋅b0+2⋅b1+3⋅b2=1⋅5+2⋅3+3⋅6∣mod7=30∣mod7=2
Bob接收到Alice的回复之后,验证其是否为α对:
α ⋅ a ′ = 4 ⋅ 2 ∣ m o d 7 = 8 ∣ m o d 7 = 1 = b ′ α·a' = 4 ·2|_{mod7} = 8|_{mod7} = 1 = b' α⋅a′=4⋅2∣mod7=8∣mod7=1=b′
验证成功!至此,Bob确信Alice确实知道P(X)的这组系数。
至于验证过程每一步的意义欢迎评论讨论!
Zcash - 深入浅出Pedersen Hash/Commitment计算_飞久-CSDN博客
Zcash - 各种密钥和签名,你懂吗?_飞久-CSDN博客
转载于TurkeyCock的博客
零知识证明|1.什么是同态隐藏?_飞久-CSDN博客_同态隐藏
零知识证明|2.什么是多项式盲计算?_飞久-CSDN博客
零知识证明|3.什么是KCA系数知识假设?_飞久-CSDN博客
零知识证明|4.如何验证多项式盲计算的值?_飞久-CSDN博客_多项式盲验证
Zcash - 深入浅出Pedersen Hash/Commitment计算_飞久-CSDN博客
Zcash - 各种密钥和签名,你懂吗?_飞久-CSDN博客