零知识证明 – R1CS导入导出

玩过zkSNARK的小伙伴都知道,R1CS是目前描述电路的一种语言。目前实现zkSNARK电路的框架有libsnark(C++),bellman (Rust),ZoKrates(DSL),Circom(js)等等。有的时候,需要将一个框架中生成的电路,导入其他框架。网络上研究了一下,发现两个有意思的项目。

1. J-R1CS

J-R1CS提出了一个导出RICS的格式标准。用一个json文件表述一个电路需要的所有信息。

https://www.sikoba.com/docs/SKOR_GD_R1CS_Format.pdf

一个电路的R1CS主要由三部分组成:

1)电路的属性描述

{

“r1cs”:{

“version”:”1.0″,

“field_characteristic”:”133581199851807797997178235848527563401″,

“extension_degree”:1,

“instances”:3,

“witnesses”:5,

“constraints”:2000,

“optimized”:true

} }

描述了J-R1CS的版本,椭圆曲线的属性,电路的公开/隐私输入的个数以及R1CS的约束个数。

2)输入描述

{

“inputs”:[“0″,”1″,”0″,”1″,”3″,”8”, …],

“witnesses”: [“1″,”1”,,”243202698575991946913848952725080

8343172040488935114927077578242952867610624″, …]

}

输入分成两种,一种是公开(public input)输入,一种是隐私(private input)输入。inputs代表公开输入,witnesses代表隐私输入。

3)约束描述

{

{

“A”: [[0,”2″],[-1,”6″],[5,”4″],….],

“B”: [[0,”5″],[-6,”3″],[3,”4″],….],

“C”: [[0,”3″],[-1,”2″],[-2,”7″],[3,”4″],[4,”1″]…]

}

}

一个约束由A/B/C三个数组组成。每个数组中的元素是一个二元组:输入的index以及输入的系数。输入的index是负数的话,代表的是公开输入;输入的index是整数的话,代表的是隐私输入。

2. zkInterface

zkInterface更进一步,提供了多种框架下的电路的转换。zkInterface作为“中间”接口,可以将”Frontend”的电路格式,导出到”Backend”的证明框架中。

https://github.com/QED-it/zkinterface

目前,zkInterface已经实现了如下的导入导出能力: