上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

密码协议形式化分析与可证明安全实验——Cricom实验

guduadmin493月前

环境安装

 环境:WIN10 x64

criom是基于Rust开发的,因此主机需要配有Rust环境。

snarkjs需要node环境。

rust安装及配置

安装及配置参考 作者:荔枝味汽水 windows安装rust详细教程

windows安装rust详细教程 - 知乎 (zhihu.com)

注意:本人的cargo换国内源选择的 清华源

再进行配置时,最后一步在.cargo文件中新建的config文件中的配置为:

[source.crates-io]

replace-with = 'tuna' 

[source.tuna]

registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"

否则在使用cargo build时会出现以下问题:

密码协议形式化分析与可证明安全实验——Cricom实验,第1张

node.js安装及配置

安装及环境配置参考 作者:WHF__ 的Node.js下载安装及环境配置教程【超详细】

Node.js下载安装及环境配置教程【超详细】_nodejs下载-CSDN博客

安装cricom

在此我选择将Cricom下载到 C盘

git clone https://github.com/iden3/circom.git

进入criom目录

cargo build --release

 等待编译完成

密码协议形式化分析与可证明安全实验——Cricom实验,第2张

 编译完成后执行安装命令

cargo install --path circom

密码协议形式化分析与可证明安全实验——Cricom实验,第3张

等待安装完毕,使用 --help查看criom 版本

密码协议形式化分析与可证明安全实验——Cricom实验,第4张

安装snarkjs

npm install -g snarkjs@latest

密码协议形式化分析与可证明安全实验——Cricom实验,第5张

构建电路与证明

准备工作 -电路部分

首先在circom目录下创建一个电路文件,文件命名为:circuit.circom,具体内容如下

pragma circom 2.1.4; 
template Multiplier() { 
    signal input a; 
    signal input b; 
    signal output c; 
    c <== a*b; 
} 
component main = Multiplier();

 第一行表示指定编译该电路用到的circom版本为2.1.4

电路包含三个变量,其中a,b为输入,输出为c,该电路可以证明Prover知道两个数字a和b,其乘积为c 这里第5行的 <== 符号有两个含义:将值与变量 c 相关联,然后是施加约束 a*b 之后是将该电路声明为Multiplier模板,并用main组件将该模板实例化

circom在编译电路时必须要有一个main组件

之后执行下列命令编译电路

circom circuit.circom --r1cs --wasm --sym

 编译完成后结果:

密码协议形式化分析与可证明安全实验——Cricom实验,第6张

这里的三个参数:

  • r1cs:生成基于R1CS约束系统的电路,得到一个.r1cs的二进制文件
  • wasm:生成一个基于circuit_js的目录(目录明取决于电路名),目录内包含一个wasm文件和其他用于生成witness的相关文件
  • sym:生成一个.sym的符号文件,用于调试和打印约束系统

    circom目录中会多出俩个文件:分别是文件circuit.rics , 文件circuit.sym 和文件夹circuit_js

    密码协议形式化分析与可证明安全实验——Cricom实验,第7张

    密码协议形式化分析与可证明安全实验——Cricom实验,第8张

    如果还加了 --c 参数,则还会生成一个 _cpp 目录,里面包含了相关的.cpp,.dat,MakeFile等等文件, 这些文件将用于编译C代码以生成witness文件

    此外可以采用 -o 参数来指定生成的目录名(如果不加这个参数,则默认目录名为 circname_js ,这里 circname是你的.circom电路文件的名字

    编译电路后,可以用snarkjs的相关命令来查看电路,先看一下snarkjs的帮助文件

    r1cs info                   Print statistiscs of a circuit
        Usage: snarkjs ri [circuit.r1cs]
    r1cs print                  Print the constraints of a circuit
        Usage: snarkjs rp [circuit.r1cs] [circuit.sym]

     这里用ri参数可以查看电路信息(或者用r1cs info也可以)

    snarkjs ri circuit.r1cs

    密码协议形式化分析与可证明安全实验——Cricom实验,第9张

     输出表示电路采用的曲线为bn-128,包含4个导线,其中2个私有输入,一个输出,输入输出之间包含一 个约束关系

    或者使用rp参数查看电路中的约束(或者用print r1cs也可以)

    snarkjs rp circuit.r1cs

    密码协议形式化分析与可证明安全实验——Cricom实验,第10张

    这里忽略掉前面的系数,得到的约束就是 到此为止,电路就编译好了,接下来需要给电路特定的输入,也就是构建witness,这里就需要用到前面 生成的wasm文件

    snarkjs采用json文件的方式将witness输入电路,需要准备一个 input.js 文件,如下

    {"a": "3", "b": "11"}

    • 注意这里的输入均为字符串,因为JS无法处理大于 的整数,所以转换为字符串形式处理

       将这个json文件放到刚刚生成的circuit_js下面,此时目录里面应该有四个文件,分别是:

      密码协议形式化分析与可证明安全实验——Cricom实验,第11张

      然后在该目录下执行下列命令

      node generate_witness.js circuit.wasm input.json witness.wtns

      密码协议形式化分析与可证明安全实验——Cricom实验,第12张

      这样就得到了 witness.wtns 的证据文件,之后将利用这个文件来生成对应的snark证明

      密码协议形式化分析与可证明安全实验——Cricom实验,第13张

      如果说前面使用了 --c 参数,则可以进入到对应的cpp目录中,同时将对应的input.json文件放到该目录 下,在该cpp目录下执行make命令即可

      准备工作-可信设置部分

      证明生成需要两个文件,一个是前面构造电路时生成的r1cs文件 circuit.r1cs ,另一个是证据文件 witness.wtns

      接下来以Groth16为例来生成证明 Groth16需要为每个电路都执行一次可信设置,因此在证明生成之前还需要针对电路完成一些准备工 作,Plonk和FFlonk无需为每个电路都执行可信设置,Plonk和FFlonk的生成过程可以看

      Groth16的可信设置由两部分组成

      • 密码协议形式化分析与可证明安全实验——Cricom实验,\tau,第14张的幂次:这一部分与电路无关
      • phase 2:这一部分取决于电路

        首先来生成 的幂次,命令如下

        snarkjs powersoftau new bn128 12 pot12_0000.ptau -v

        利用 new 命令创建密码协议形式化分析与可证明安全实验——Cricom实验,\tau,第14张的幂次,这里有几个参数说明一下

        • 第一个参数为指定需要的曲线,snarkjs支持bn128和bls12-381两种曲线
        • 第二个参数为约束参数,表示可信设置所支持的最大约束的数量,这里的12表示可信设置最多支持 密码协议形式化分析与可证明安全实验——Cricom实验,2^{12} = 4096,第16张个约束,这个参数的最大值为28,也即snarkjs可以生成具有至多密码协议形式化分析与可证明安全实验——Cricom实验,2^{28}\approx 2.68*10^{8},第17张个约束的电路

          生成之后会在目录下得到一个 pot12_0000.ptau 文件

          密码协议形式化分析与可证明安全实验——Cricom实验,第18张

          接下来需要用 contribute 命令,使用新的贡献来创建一个ptau文件

          snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v

          这里会提示输入一些随机文本来为贡献提供额外的熵源,这里随便输就行,比如输入contribution" -v

          contribute命令会将截止至现在的所有ptau文件作为输入(截止至目前为止的ptau文件为上面新建的 pot12_0000.ptau ),同时输出一个新的ptau文件 pot12_0001.ptau ,该文件中包含新贡献者执行的计算

          密码协议形式化分析与可证明安全实验——Cricom实验,第19张

          contribute的过程还可以使用第三方软件来更新,比如下面这样(这里用的是这个库的bn-256曲线构建)

          snarkjs powersoftau export challenge pot12_0001.ptau challenge_0003
          snarkjs powersoftau challenge contribute bn128 challenge_0003 response_0003 - e="some random text"
          snarkjs powersoftau import response pot12_0001.ptau response_0003 pot12_0002.ptau -n="Third contribution name"

          密码协议形式化分析与可证明安全实验——Cricom实验,第20张

          •  密码协议形式化分析与可证明安全实验——Cricom实验,第21张

            更新完成之后,用 verify 命令验证截止至目前为止的ptau(只执行了一次更新,所以验证0001这个 ptau文件)

             snarkjs powersoftau verify pot12_0001.ptau

            密码协议形式化分析与可证明安全实验——Cricom实验,第22张

            这里只是生成 的幂,还没有执行phase 2的命令,因此此时运行后系统会输出[WARN]提示

            不过验证通过了,就没什么问题

            这里注意一点,每当新的zk-snark需要执行可信设置时,只需要对最新的ptau文件执行verify命令,即可 验证截止到目前为止的整个挑战和相应链

            接下来是利用beacon命令创建一个ptau文件,这个ptau文件会以随机beacon的形式对ptau文件完成贡 献,可信设置的第一阶段需要对其应用一个随机beacon

            引入beacon的命令如下

            snarkjs powersoftau beacon pot12_0001.ptau pot12_beacon.ptau1cbf6603d6ff9ba4e1d15d0fd83be3a80bca470b6a43a7f9055204e860298f99 10 -n="Final Beacon"

            密码协议形式化分析与可证明安全实验——Cricom实验,第23张

            这里利用了以太坊第16668892个区块的Hash值作为beacon值,后面的参数10表示以该beacon值作为输入,计算密码协议形式化分析与可证明安全实验——Cricom实验,2^{10},第24张次Hash

            接下来是可信设置的第二部分,也即phase 2

            phase 2用到的命令为 prepare phase2 ,该命令会用到前面输出的 pot12_beacon.ptau 文件,并基于 该文件计算基于密码协议形式化分析与可证明安全实验——Cricom实验,\tau ,\alpha *\tau ,\beta *\tau,第25张 的拉氏插值多项式,命令如下

            snarkjs powersoftau prepare phase2 pot12_beacon.ptau pot12_final.ptau -v

            输入命令之后,电脑会算一阵子,计算的时间取决于曲线、第一阶段中允许的约束数量(约束数量越 大,计算时间越长)

            生成完最终ptau文件后,别忘了用 verify 命令验证一下

            snarkjs powersoftau verify pot12_final.ptau

            密码协议形式化分析与可证明安全实验——Cricom实验,第26张

            密钥生成

            准备完毕之后,接下来是根据电路构建证明与验证密钥

            首先将circuit.r1cs文件复制到C:\circom\circuit_js目录下

            用电路和上面的最终ptau文件生成一个zkey文件,该文件是一个零知识密钥文件,包含phase 2的所有贡献,以及用于证明和验证的密钥,利用这个zkey文件可以验证其是否属于特定的电路

            snarkjs groth16 setup circuit.r1cs pot12_final.ptau circuit_0000.zkey

            密码协议形式化分析与可证明安全实验——Cricom实验,第27张

            密码协议形式化分析与可证明安全实验——Cricom实验,第28张

            这里得到的 circuit_0000.zkey 文件不包含任何贡献,不能用于最终电路的证明,因此需要执行前面 的贡献更新步骤

            接下来使用 zkey 命令来对zkey文件进行贡献更新(前面用的是 powersoftau 命令,基本流程是一样 的)

            snarkjs zkey contribute circuit_0000.zkey circuit_0001.zkey --name="First Contributor Name" -v #这里依然输入之前输入的值
            snarkjs zkey contribute circuit_0001.zkey circuit_0002.zkey --name="Second contribution Name" -v -e="Another random entropy"
            snarkjs zkey verify circuit.r1cs pot12_final.ptau circuit_0002.zkey # 更新完贡献记得验证一下

            然后引入随机beacon值并验证

            snarkjs zkey beacon circuit_0002.zkey circuit_final.zkey
            1cbf6603d6ff9ba4e1d15d0fd83be3a80bca470b6a43a7f9055204e860298f99 10 -n="Final Beacon phase2"
            snarkjs zkey verify circuit.r1cs pot12_final.ptau circuit_final.zkey #同样引入beacon后验证一下

            之后基于该zkey文件,导出一个验证密钥,导出的密钥为json格式

            snarkjs zkey export verificationkey circuit_final.zkey verification_key.json

            密码协议形式化分析与可证明安全实验——Cricom实验,第29张

            证明生成

            接下来利用电路和证明密钥来构建证明

            snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json

            命令执行完毕后,可以得到两个json文件:

            • 一个是 public.json 
            • 另一个是 proof.json 

              密码协议形式化分析与可证明安全实验——Cricom实验,第30张

              public.json文件中是33,我们前面给的witness分别是3和11,因此密码协议形式化分析与可证明安全实验——Cricom实验,3*11=33,第31张 正确

              密码协议形式化分析与可证明安全实验——Cricom实验,第32张

              proof.josn里面包含用于验证的元素

              密码协议形式化分析与可证明安全实验——Cricom实验,第33张

              上面三个就是Groth16中三个用于配对的元素

              这里官方给了一个一步到位的方式,可以在一条命令里面同时构建witness文件和证明,如下 

              # Groth16
              snarkjs groth16 fullprove input.json circuit.wasm circuit_final.zkey 
              proof.json public.json
              # Plonk
              snarkjs plonk fullprove witness.json circuit.wasm circuit_final.zkey 
              proof.json public.json
              # FFlonk
              snarkjs fflonk fullprove witness.json circuit.wasm circuit_final.zkey
              proof.json public.json

              验证

              利用上述两个json文件可以验证证明

              snarkjs groth16 verify verification_key.json public.json proof.json

               如果输出下列信息说明验证通过了

              密码协议形式化分析与可证明安全实验——Cricom实验,第34张

              现在把 把public.json里面的33改成32

              密码协议形式化分析与可证明安全实验——Cricom实验,第35张

              再执行一次验证命令,此时会输出验证失败 

              密码协议形式化分析与可证明安全实验——Cricom实验,第36张

               模拟执行

              最后是将验证密钥导出为Solidity智能合约,就可以将这个合约发布到链上了

              snarkjs zkey export solidityverifier circuit_final.zkey verifier.sol

              密码协议形式化分析与可证明安全实验——Cricom实验,第37张

              密码协议形式化分析与可证明安全实验——Cricom实验,第38张

              snarkjs给了一个模拟验证执行的命令,利用上面的两个json文件可以模拟Verifier在remix中的验证过程

              snarkjs zkey export soliditycalldata public.json proof.json

               输出是三个群元素和公共输入,均编码为HEX形式

               密码协议形式化分析与可证明安全实验——Cricom实验,第39张

              ["0x1d0bde1fa11154e30fe2f4cf390f13e44ded5892b89704fc67286548b72a84b9", "0x24bdfd9600cd3305d33d22eb772f4a931e155b523a12a24d84454594e6006d43"],
              [["0x2c48929cc2f3f143b445bcc9228423a7afb765007cf823892c259259e9b20567", "0x13f538fbcf2d881da5af31297e6085bbcd4bcf7f36b8761eeaa6c2feebcca626"],["0x1be7d0cd25b1cb6bd5b0c465b95581291289b547600b4a2e7bc404b24d0f4238", "0x2d960f51e9918d0479d5ef4fe3351ef654277af3c5a82d956a50542e0b4db0cf"]],
              ["0x2ed9cd3e86df53ded6d6f402f5a5cfa390d9d35292e3f3ffb3e34c5432a3d30d", "0x1f9f04d096b7638ec149a9ac8ceb06acc268716f60ab8f4b5c1f7881498fb3cd"],
              ["0x0000000000000000000000000000000000000000000000000000000000000020"]

              这里Verifier会调用verifyProof函数来对上述这堆东西进行验证,这里可以把上面的那个智能合约导入到 remix来模拟一下,这里给一个网址:http://remix.ethereum.org/

              进去之后,右上角切换中文

              密码协议形式化分析与可证明安全实验——Cricom实验,第40张

              打开本地文件->上传verifier.sol文件(地址:C:\circom\circuit_js)

              密码协议形式化分析与可证明安全实验——Cricom实验,第41张

               进入SOLIDITY模块

              密码协议形式化分析与可证明安全实验——Cricom实验,第42张

              编译verifier.sol文件

              密码协议形式化分析与可证明安全实验——Cricom实验,第43张

              之后点左侧第四个部署并运行智能合约,这里选择Verifier的合约

              然后下面有一个已部署的智能合约,把上面得到的那一串数字粘贴到verifyProof里面,点一下call

              密码协议形式化分析与可证明安全实验——Cricom实验,第44张

              右侧主界面可以看到正在调用,如果验证通过的话decode output这里会输出true

网友评论

搜索
最新文章
热门文章
热门标签
 
 测字算命  梦见洗头发什么预兆  梦到找鞋穿