zk-SNARKs

探讨了零知识证明中的同态隐藏与多项式盲计算技术,通过具体实例解释了如何利用同态隐藏进行安全验证,同时保持信息的私密性。

对零知识证明的一些整理(未完待续)

1,同态隐藏(Homomorphic Hidings)

  • 给定E(x),很难反推出x的值
  • 若x != y, 则E(x) != E(y)
  • 若已知 E(x)E(y),则可计算出E(x+y)

举例说明同态隐藏在零知识证明中的作用:
假设Alice知道 xy的值使得 x+y=7,利用同态隐藏,Alice可以在不泄露xy具体值的情况下像Bob证明她的确知道xy的值,过程如下:

  • Alice将 E(x)E(y) 发送给Bob
  • Bob通过 E(x)E(y)计算出E(x+y),同时计算一下E(7)
  • Bob检验E(x+y)是否等于E(7)

上面的验证过程保留了Alice的秘密,同时又能让Bob信服,那么问题是,什么样的E(x)才满足我们的期望呢? E(x) = x^2 这种普通的加减乘除的函数肯定不行。。。。

取模运算mod
7mod4=37 mod4 = 37mod4=3,或者 7∣∣mod4=37||_{mod4} = 37mod4=3有时我们也会把mod写在右边,记为 7=3(mod4)7 = 3 (mod4)7=3mod4
本文我们统一用第二种。

模p乘方(p为质数,此处取5)
对于整数集合{1…p-1},对集合中任意元素求乘方后取模

x1234
1x∥mod51^x∥ _{mod5}1xmod51111
2x∥mod52^x∥ _{mod5}2xmod52431
3x∥mod53^x∥ _{mod5}3xmod53431
4x∥mod54^x∥ _{mod5}4xmod54141

我们把集合{1…p-1}与在集合上的求乘方后取模合称为 群ZpZ_pZp,集合元素有限的群称之为有限群。当p取质数时,群ZpZ_pZp会出现一个特征-——循环群,以上表为例,2x∥mod52^x∥ _{mod5}2xmod5 这行,完美生成了集合中的每一个元素,这种群称之为循环群,2称之为这个群的生成元g。利用循环群的特性,我们可以构造一个符合要求的E(x)
E(x) = 2x∣∣mod52^x||_{mod5}2xmod5
我们检验**E(x)**是否满足同态隐藏的三个条件:

  1. 给定E(x)的值,很难反推x。(当p取5,g取2时当然不难,当p,g很大时,反推非常困难)
  2. 由于循环群的特性,x不同,E(x)也不同
  3. E(x+y) = 2x+y∣∣mod52^{x+y}||_{mod5}2x+ymod5 = (2x∣∣mod5∗2y∣∣mod5)∣∣mod5(2^x||_{mod5} * 2^y||_{mod5})||_{mod5}(2xmod52ymod5)mod5 = E(x)∗E(y)∣∣mod5E(x)*E(y)||_{mod5}E(x)E(y)mod5
    故上述E(x)能满足同态隐藏的特性。

此处假设Alice要想Bob证明她拥有x+y=4这个问题的答案(例如x=3, y=1), 不想泄露xy的具体值。于是可以这么干:

  • Alice将E(3) 的值3、E(1) 的值2发送给Bob
  • Bob计算E(x+y)=3∗2∣∣mod5=1=3*2||_{mod5}=1=32mod5=1
  • Bob计算E(4)的值, = 1,
  • 经过比较,Bob确信Alice确实知道x+y=4的答案。此过程中,Bob并不知道x,y的具体值,达到了隐藏的目的。

2,多项式盲计算

接下来,我们把要证明的问题变复杂点,假设Alice知道多项式P(x)=a0+a1x+a2x2...adxdP(x)=a_0+a_1x+a_2x^2...a_dx^dP(x)=a0+a1x+a2x2...adxd的系数,她要向Bob证明她有这样一组系数{a0,a1,...ada_0,a_1,...a_da0,a1,...ad},同时不泄露各项系数。我们假设Alice手中的P(x)=1+2x+3x2P(x)=1+2x+3x^2P(x)=1+2x+3x2E(x)=2x∣∣mod5E(x)=2^x||_{mod5}E(x)=2xmod5, p=5p=5p=5
那么问题来了,Alice如何证明自己呢?
我们先看这个问题比上面的x+y=4难在哪里

  • 前者是个等式,且右边是个已知的常量
  • 后者是个多项式
  • 假如Bob取一个验证点,例如令x=2, 发给Alice,Alice计算P(2)=1+4+12=17P(2)=1+4+12=17P(2)=1+4+12=17,然后将17发送给Bob,此时Bob并无从验证17是否是正确的。另外Bob也不想直接把x=2发给Alice——他更想让Alice在不知道x的取值的情况下,证明自己知道多项式的系数。

首先,Bob的想隐藏x=2这一点是容易实现的——再用一次同态隐藏即可:
E(a+bx+cx2)=2a+bx+cx2∣∣mod5=E(a)∗E(x)b∗E(x2)c∣∣mod5E(a+bx+cx^2)=2^{a+bx+cx^2}||_{mod5}=E(a)*E(x)^b*E(x^2)^c||_{mod5}E(a+bx+cx2)=2a+bx+cx2mod5=E(a)E(x)bE(x2)cmod5
于是,Bob仅需将E(x)E(x)E(x)E(x2)E(x^2)E(x2)在x=2时的值发给Alice即可做到隐藏x=2的目的,同时又不影响Alice的证明。
E(x)=22∣∣mod5=4E(x)=2^2||_{mod5}=4E(x)=22mod5=4 E(x2)=24∣∣mod5=1E(x^2)=2^4||_{mod5}=1E(x2)=24mod5=1
Alice拿到上述两个值,带入计算E(P(x))=21+2x+3x2∣∣mod5=E(1)∗E(x)2∗E(x2)3∣∣mod5E(P(x))=2^{1+2x+3x^2}||_{mod5}=E(1)*E(x)^2*E(x^2)^3||_{mod5}E(P(x))=21+2x+3x2mod5=E(1)E(x)2E(x2)3mod5

E(P(x))=2∗16∗1∣∣mod5=2E(P(x))=2*16*1||_{mod5}=2E(P(x))=2161mod5=2
最大的问题在于,当Alice计算出结果发送给Bob之后,Bob该如何验证呢?假如Bob知道P(x)=1+2x+3x2P(x)=1+2x+3x^2P(x)=1+2x+3x2,那验证是比较简单的E(P(2))=E(17)=2E(P(2))=E(17)=2E(P(2))=E(17)=2
但是,Bob不知道P(x),他该怎么去验证呢…

这个问题分两部分
zk-SNARKs最精彩的部分来了!!!!!

3,系数知识假设(KCA)

<think>好的,用户想了解zk-SNARKs的代码实现示例。首先,我需要回忆一下zk-SNARKs的基本概念,它属于零知识证明的一种,允许证明者在不透露信息的情况下验证某个声明的正确性。用户提到参考了几个引用,其中引用了libsnark库和GitHub上的代码,所以应该围绕这些资源展开。 接下来,用户的问题是关于代码实现的具体例子。我需要先确定哪些引用提到了具体的代码库。引用[1]提到Zcash使用了libsnark的一个分叉,并给出了GitHub链接。引用[2]提到了pequin项目,也是基于libsnark。引用[3]讨论了zkLedger的实现,但用户的问题可能更偏向zk-SNARKs本身,所以可能需要重点放在前两个引用上。 然后,我需要考虑如何组织回答。首先介绍libsnark作为主要的C++库,然后给出一个简单的示例,比如电路的定义和证明的生成。可能还需要提到Zcash和pequin项目的具体实现,以提供实际应用的例子。同时,需要确保代码示例符合用户提供的格式要求,比如使用正确的LaTeX格式,并且代码块用Python(如果可能的话)。不过注意到libsnark是C++库,所以可能需要用C++代码示例,但用户示例中的快速排序是Python,所以可能需要调整。不过根据引用中的信息,可能C++更合适。 另外,用户要求生成相关问题,我需要根据zk-SNARKs的实现细节、优化方法、应用场景等方面来提问,确保问题相关且有深度。同时,引用中的信息需要正确标注,比如引用[1]和[2]对应的内容。 还需要检查是否所有数学表达式都用$...$或$$...$$格式,比如电路中的约束条件可能需要用LaTeX表示。例如,一个简单的电路如$x^3 + x + 5 = 35$,需要用行内公式。同时,回答结构要清晰,分步骤说明如何实现,并确保引用正确。 最后,确认回答是否满足用户的所有要求,包括代码实现示例、相关引用标注、问题生成,以及使用中文回答等。如果有不确定的地方,比如具体的代码示例是否准确,可能需要参考提供的引用内容,确保信息正确无误。</think>关于zk-SNARKs的代码实现,以下是系统级的实现要点和示例: ### 1. 核心实现框架 zk-SNARKs的实现通常基于密码学库libsnark(C++),其核心包含三个组件: - **算术电路构建**:将待验证的计算转化为R1CS(Rank-1 Constraint System) $$ \langle A_i, z \rangle \cdot \langle B_i, z \rangle = \langle C_i, z \rangle \quad \forall i $$ - **可信设置阶段**:生成证明密钥(pk)和验证密钥(vk)[^1] - **证明生成/验证**:使用椭圆曲线配对实现零知识属性[^2] ### 2. 代码实现示例 ```cpp // 基于libsnark的简单电路实现 #include <libsnark/common/default_types/r1cs_gg_ppzksnark_pp.hpp> using namespace libsnark; protoboard<FieldT> pb; // 电路构建平台 // 定义电路变量 pb_variable<FieldT> x; x.allocate(pb, "x"); pb_variable<FieldT> y; y.allocate(pb, "y"); // 添加约束:x^3 + x + 5 == y pb.add_r1cs_constraint(r1cs_constraint<FieldT>(x, x, x)); // x^3 pb.add_r1cs_constraint(r1cs_constraint<FieldT>(x + 1, 1, y - 5)); // 生成密钥对 r1cs_gg_ppzksnark_keypair<default_r1cs_gg_ppzksnark_pp> keypair = r1cs_gg_ppzksnark_generator<default_r1cs_gg_ppzksnark_pp>(pb.get_constraint_system()); ``` ### 3. 实际应用案例 - Zcash使用改进版libsnark实现交易隐私保护[^1] - pepper-project实现可验证计算协议[^2] - zkLedger采用Go语言实现椭圆曲线运算和范围证明[^3] ### 4. 性能优化方向 - 椭圆曲线点压缩技术(如引用[3]所述) - 使用SHA256实例化随机预言机 - 并行化Groth16协议中的配对运算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值