是男人就掏出来看看



  • 原创: 汤强
    链接:https://mp.weixin.qq.com/s/GEpp28vBvV5qi3PqYMj_2g

    毕业十年,事业骄艳,成功男士光芒涂满同学聚会的觥筹交错间。

    你和女同学们聊得正欢,余光里杀出个男的敬你酒,你不喝,他红着鼻子醺你:不喝不是男人,你到底是不是?

    你说你是。他把酒杯往桌上一拍:是男人要么闷掉这杯,要么掏出来看看。

    怎么办?如果真掏,明早铁定头版头条;如果不掏,成功男士的光芒会被红尘笼罩。

    急中生力,你一咬牙拔出身份证往桌上一拍,酒鬼楞了一下,好像突然清醒,验货之后,自己把酒喝掉,转身又醉去。

    女同学们都夸你的宝贝好厉害,你却笑而不语,因为你明白,这并不是什么宝贝,而是区块链世界的一招:简明非交互零知识证明(zk-SNARK)。

    一、什么是简明非交互零知识证明?

    zk-SNARK:Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge

    明明生涩冗长,用两行才能装下,那它怎么好意思夸自己“简明”呢?掰开揉碎一步步来:

    零知识(Zero-Knowledge):你不出具真家伙,就能向酒鬼证明你的性别。

    简明(Succinct):证据简短且明文,验证方便。

    非交互(Non-Interactive)指双方不多嘴。证明者只向验证者发一次信息,极端复杂时,最多一个来回就能搞定验证。

    知识的验证(Arguments of Knowledge):别人无法伪造,可信度极高。

    所以,你看出来了,即使开篇的故事把比方打成这样,我们还是不到位,还是太温柔,还是没有扒开zk-SNARK的底裤:

    要证明你是男人,不靠喝、不靠掏、也不靠身份证,那些都是原子世界的思维定式。数字世界,你只要出示一口气息,就能证明你的性别。

    这口气息的名字叫zk-proof(零知识证据),它不仅简明,而且只需发射一次,就能摆平质疑。

    本文本该参阅zk-SNARK的经典三篇,因为作者是大神:以太坊创始人V神。可本文作者没翻两页就跪了,决定不拿V神文中27个新概念来为难你。

    于是,换个国产V神吧:Victor,麻省理工学院计算机科学博士,他有篇文章是连接入门者和zk-SNARK之间最好的纽带。于是,下文生扒了Victor《众目睽睽下隐身,zk-SNARK黑科技如何保护区块链隐私》的技术详解部分:

    首先明确两个角色:证明者和验证者。

    你是证明者,口袋里装着两个数字:3和4。你想证明自己有,但由于这两个数字重要得如地址、如私钥,所以不想被人看到。

    我是验证者,想验证你确有这两个数,但我不能伸手到你口袋里来掏。传统意义上,我们只认眼见为实,所以这事绝无可能办到。但在科技丛林里我们总能逮到新物种,而zk-SNARK就是其中活奔乱跳的一只。

    别人想看,你不能给,却非要证明你有,怎么办?

    下面我们打开弧光灯,用手术刀切开zk-SNARK的运转过程,一探究竟。

    二、理解这节内容你就合格:zk-SNARK基础过程

    你找出一个玻璃盒,罩在数字上,这个盒子能让数字发生折射,使它们看上去不是3和4,而是9和10。这个神奇玻璃盒就是同态隐藏函数E(x),它有三个特性:

    1、 光看表象数字9,猜不到内部数字3——虽然通透,但保密性好,通过E(x)无法推导出x。

    2、 包住3透出9,包住4透出10——不同的输入得到不同的输出,即:若x≠y,则E(x)≠E(y)。

    3、 我作为验证者,不知道你口袋里的具体数字,但玻璃盒表面数字具备玻璃盒内数字的特性:我只靠E(x)和E(y),经过复杂计算能得出E(x+y)的值。

    如果经过复杂运算得出E(x+y)的值等于玻璃盒表面两个数字之和E(x)+E(y),即通过zk-SNARKs验证。

    你手里的玻璃盒“同态隐藏函数”简直就是一只魔法水晶球:既能证明你有,又能滴水不漏。如果数学在天有灵,那我就必须无条件认你兜里的数字货真价实,即使我从来没见过。

    同态隐藏是一类加密函数,细分下去有两种:本例属于加法同态,即E(x)+E(y)= E(x+y);如果满足E(x)×E(y)= E(xy),就是乘法同态。

    读到这里,你的好奇心可能会隐隐作痛:如果我知道你口袋里的x+y=7,那难道我就不能去抱养一只矿机,暴力破解出x和y的正确答案么?

    你想对了,完全可以。

    所以,必须引入一个概念:随机偏移。

    你必须找到一个随机数t,使得你玻璃盒透射出的数字并不是E(x)和E(y)本身,而是E(x+t)和E(y-t),否则你的秘密就存在被我穷举的风险。

    也就是说,此时我从盒子上看到的就不再是9和10(E(x)和E(y)),而是26和47(E(x+t)和E(y-t))。

    注意,玻璃盒上的9、10、26和47 是杜撰出来的值,只为便于你理解,不必纠结过程。

    如果你励志读懂本文的数学原委,那我们可能要一起去搞两顶硕士帽戴戴,而且读到动情之处,躲在博士帽下的人都未必能醒悟。所以我们只要知道同态隐藏函数E(x)在数学上能实现就行。

    “E(x+t)、E(y-t)”和“E(x)、E(y)”一样,能通过复杂计算得出E(x+y)的值,这是基于同态隐藏函数的性质。所以,如果我发现E(x+y)最终等于E(x+t)+E(y-t),那么恭喜你,通过了我的验证。

    问题终于解决,你长出一口气。但是,每当我们认为春风得意到理所当然时,不妨多问自己一句:问题真的解决了么?

    答案为否。

    应付村里的小喽喽,上述方法早已足够。但挺进大都市,面对更复杂的场景,老办法就会掉队了。

    读到这里,如果你没有8分钟的专注时间,可以直接翻下读结语。因为下一节我们将冒着失去一半读者的风险解剖复杂场景下zk-SNARK的五脏六腑。

    而你有两个选择:

    第一, 用手指飞速划过本文第三部分1926个字难受的学习区,瞬间转移至舒适区:结语。

    第二, 迎难而上,留在学习区修行。感觉上会不好受,但总会有人选择正确的难受,不是么?

    三、直面复杂场景:zk-SNARK进阶过程

    我们已经理解,如何在不出示静态数字本身的情况下,证明你确实有这些数字。

    可如果你兜里放着的不是几粒数字或字符,而是动态数字——多项式,那你又该如何证明?

    什么是多项式?其实我们很熟悉,比如:

    0_1540405595295_d70749a7-6d99-479f-aa6c-11e448aad21f-image.png

    P(x)就是一个多项式。

    复杂场景指:你如何在不展示多项式本身的情况下,证明你有这个多项式?

    此时,光靠同态隐藏函数的玻璃盒已经不够用了。因为一个多项式中,x可能有无穷多个值。

    必须另辟蹊径。

    数学家给我们指了条明路:与其验证所有可能的解,不如我随口问你:x=2时,你的多项式等于几?

    即,验证者向证明者发射一个随机点s。证明者只要回复验证者P(s)的值,就能完成验证。

    你需要告诉我的仅仅是:当x=2时,你手里多项式的值就行,本例中P(2)=77。

    现在,我还不知道你手里多项式的模样,但我凭2和77两个值,就能验证你是否有这个多项式,理由是上文同态隐藏函数的第三条性质。

    但你可能已经发现,这个方法有两个问题:

    第一,我可能会拿你给我的蛛丝马迹,暴力破解你的秘密多项式,**所以你必须再找一个随机偏移多项式R(s)。**这个R(s)必须像眼药一样,使得我根本看不清P(s)的模样。

    你把P(s)与R(s)之和放进同态加密的玻璃盒,只让我瞄一眼表面数字:E(P(s)+R(s))的值,但这已足够我验证。

    于是,第一个问题解决。

    第二个问题是:我把随机点s=2发送给你,你完全可以找个值来唬弄我,因为P(x)的值可能有一箩筐,如果你并没有这个多项式,但你特别能猜,一猜就中,怎么办?

    最简单的方式是我把随机点s加密,再发送给你。

    但这样做的尴尬是:你无法计算出P(s)、R(s)以及加密函数值E(P(s)+R(s))。

    所以,为了让你能轻松算出E(P(s)+R(s)),我把E(1)、E(s)、E(s2)、E(s3) 全部发给你(s2和s3代表s的平方和立方,下文同)。

    根据加密函数第三条性质,你可以根据E(1)、E(s)、E(s2)、E(s3)计算出E(P(s)+R(s))。

    特别有价值的一点是,此时随机点s的具体数据没有暴露。换句话说,你并不知道我随口说的s值等于2,但你依然可以把有价值的信息发给我验证。

    所以,如果你并没有多项式,用“渺茫”形容你蒙对的可能性,那是在夸你,用“零”描述才贴切。

    但如果你的确没有多项式,可你就是中着彩票长大的,我作为验证者又该如何对抗你的手气呢?

    zk-SNARK的答案是继续灌入随机,稀释你的好运。

    我在生成随机数s的同时,再生成一个随机数k,接着向你发送关于s和k的信息,你只要给我两个数就行:

    第一,P(s)的加密值E(P(s))
    第二,kP(s)的加密值E(kP(s))

    回忆一下:加密就是套个神奇玻璃盒子,加密值就是我透过玻璃盒子能看到的数字。

    注意,k是一个只有我知道的秘密随机值,如果你可以告诉我P(s)和kP(s)的信息,就证明你不靠胡说八道过日子,你确实知道P(x)的样子。

    具体原因是一个概念:知识系数假说Knowledge of Coefficient Assumption。如果你有兴趣,可以去Google。本文不再铺开,因为再不收笔,我们专栏的另一半读者也没了。

    于是,zk-SNARK的终极方案是:

    我选取随机点s和随机系数k,向你发送两溜加密函数的值:
    E(1)、E(s)、E(s2)、E(s3);
    E(k)、E(ks)、E(ks2)、E(ks3);

    你产生一个随机偏移多项式R(x),根据我给你的值,分别计算:
    E(P(s)+R(s))
    E(kP(s)+kR(s))

    你算出上述两个值,丢给我验证就行啦,zk-SNARK会保证我们都不吃亏、都不上当。

    好,我们收起手术刀,关掉弧光灯,洗洗手,总结一下这场解剖,我们注意到最重要的一点:

    **验证者发送给证明者的信息不随验证内容变化。因此可以事先设置,不断复用。**这个可以事先设置的信息称为:共同参考字符串:CRS Common Reference String。

    但正是基于此,引出zk-SNARK的两根软肋:

    第一,如果验证一个复杂多项式,需要耗费极多计算资源,所以在烧gas的平台上运行会很贵,当前常用的解决方案是先预编译然后上链跑。所以,优化计算过程仍是一条艰辛漫长之路。

    第二,生成和保存随机信息的方式仍然很土。比如,使用zk-SNARK技术的Zcash中,CRS里存放的只是随机点s和随机系数k的加密值,而s和k的明文则由6个人私下保管。

    传说只要这6个人不同时变坏,这些随机数就不会被完整恢复,而且为让秘密永远秘密下去,这些人还模仿桃园结义拜过把子,但这恰好给我们人类下一场史诗级的思考开了一个小头:

    秘密的秘密,应该交给谁来保密?

    结语

    是骡子是马,再也不用拉出来遛了。

    我们都曾证明过一些鸡毛蒜皮,为此不得不丢弃隐私,付出“非简明”的代价,动不动逼你掏出来看的场景并非只局限于同学聚会。

    区块链世界的初始设置本是公开透明,但人性却渴求隐私。若不为得到公共服务的便利,没有谁愿意凭空抛洒自己的财产信息、医疗记录或地理位置数据。

    历史无数次证明:呵护隐私的不可能是道德,只能靠技术,而zk-SNARK和众多保密技术一样,负责给你的隐私涂上马赛克。

    比如,你能在不暴露准确位置的情况下,向人证明你在上海;如有必要,你还可以缩小范围证明你在浦东,而不必暴露你在陆家嘴的精准位置。

    zk-SNARK可能会演化成一个旋钮指针,供你在完全公开和绝对私密两头自主游移。让你在享受公共服务便利的同时,守住个人私密。它能防止你的隐私变成脱缰野马、绝尘而去。最终,让你在虚拟世界里全身放松、自然舒展。

    这是一种安排数学担任信任中介的手段,虽然zk-SNARK尚未解决计算量臃肿和随机数隐忧两大问题,但这样的星星早晚点亮黑科技的夜空。

    新技术可能不在天顶闪烁,但早已在我们脚下涌动,它们不会改变水的颜色或者空气的味道,但我们的世界必然会被这些光芒重新雕塑。

    0_1540406172722_4a63c441-4667-4138-b079-4a6907903917-image.png