Skip to content

Commit 3301dfa

Browse files
lispc0xmountaintop
andauthored
support r1cs created by circom2 (#122)
* support r1cs created by circom2 * upgrade version to 0.1.6 * fix * Update package.json Co-authored-by: HAOYUatHZ <[email protected]>
1 parent ae8faa6 commit 3301dfa

File tree

7 files changed

+46
-22
lines changed

7 files changed

+46
-22
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "plonkit"
3-
version = "0.1.5"
3+
version = "0.1.6"
44
authors = [ "Roman Semenov <[email protected]>", "Zhuo Zhang <[email protected]>", "Haoyu LIN <[email protected]>" ]
55
description = "Library for working with circom circuits in plonk proof system"
66
homepage = "https://github.com/fluidex/plonkit"

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
A zkSNARK toolkit to work with [circom](https://github.com/iden3/circom) zkSNARKs DSL in [plonk](https://eprint.iacr.org/2019/953) proof system. Based on [zkutil](https://github.com/poma/zkutil) and [bellman_ce](https://github.com/matter-labs/bellman).
66

77
## Prerequisites
8-
+ https://github.com/fluidex/snarkit
8+
9+
1. install [circom](https://docs.circom.io/getting-started/installation/) into $PATH
10+
2. install snarkit2 into $PATH: `npm install -g snarkit2`
911

1012
## Features
1113

@@ -75,7 +77,7 @@ circuit.circom input.json setup_2^20.key
7577

7678
# generate witness for this circuit
7779
# another option here is use the snarkjs/circom cli like contrib/process_circom_circuit.sh
78-
> npx snarkit check . --witness_type bin --backend wasm
80+
> snarkit2 check . --witness_type bin --backend wasm
7981

8082

8183
# Generate a snark proof using the universal setup monomial-form SRS

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "plonkit",
3-
"version": "0.1.5",
3+
"version": "0.1.6",
44
"description": "A zkSNARK toolkit to work with circom zkSNARKs DSL in plonk proof system",
55
"main": "index.js",
66
"scripts": {

src/bin/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use plonkit::recursive;
1818

1919
/// A zkSNARK toolkit to work with circom zkSNARKs DSL in plonk proof system
2020
#[derive(Clap)]
21-
#[clap(version = "0.0.4")]
21+
#[clap(version = "0.1.6")]
2222
struct Opts {
2323
#[clap(subcommand)]
2424
command: SubCommand,

src/r1cs_file.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ use crate::bellman_ce::pairing::{
77
};
88
use crate::circom_circuit::Constraint;
99
use byteorder::{LittleEndian, ReadBytesExt};
10-
use std::io::{Error, ErrorKind, Read, Result};
10+
use std::{
11+
collections::HashMap,
12+
io::{Error, ErrorKind, Read, Result, Seek, SeekFrom},
13+
};
1114

1215
// R1CSFile's header
16+
#[derive(Debug, Default)]
1317
pub struct Header {
1418
pub field_size: u32,
1519
pub prime_size: Vec<u8>,
@@ -22,6 +26,7 @@ pub struct Header {
2226
}
2327

2428
// R1CSFile parse result
29+
#[derive(Debug, Default)]
2530
pub struct R1CSFile<E: Engine> {
2631
pub version: u32,
2732
pub header: Header,
@@ -92,7 +97,7 @@ fn read_map<R: Read>(mut reader: R, size: u64, header: &Header) -> Result<Vec<u6
9297
Ok(vec)
9398
}
9499

95-
pub fn from_reader<R: Read>(mut reader: R) -> Result<R1CSFile<Bn256>> {
100+
pub fn from_reader<R: Read + Seek>(mut reader: R) -> Result<R1CSFile<Bn256>> {
96101
let mut magic = [0u8; 4];
97102
reader.read_exact(&mut magic)?;
98103
if magic != [0x72, 0x31, 0x63, 0x73] {
@@ -107,24 +112,38 @@ pub fn from_reader<R: Read>(mut reader: R) -> Result<R1CSFile<Bn256>> {
107112

108113
let num_sections = reader.read_u32::<LittleEndian>()?;
109114

110-
// todo: rewrite this to support different section order and unknown sections
111-
// todo: handle sec_size correctly
112-
let sec_type = reader.read_u32::<LittleEndian>()?;
113-
let sec_size = reader.read_u64::<LittleEndian>()?;
114-
let header = read_header(&mut reader, sec_size)?;
115+
// section type -> file offset
116+
let mut section_offsets = HashMap::<u32, u64>::new();
117+
let mut section_sizes = HashMap::<u32, u64>::new();
118+
119+
// get file offset of each section
120+
for _ in 0..num_sections {
121+
let section_type = reader.read_u32::<LittleEndian>()?;
122+
let section_size = reader.read_u64::<LittleEndian>()?;
123+
let offset = reader.seek(SeekFrom::Current(0))?;
124+
section_offsets.insert(section_type, offset);
125+
section_sizes.insert(section_type, section_size);
126+
reader.seek(SeekFrom::Current(section_size as i64))?;
127+
}
128+
129+
let header_type = 1;
130+
let constraint_type = 2;
131+
let wire2label_type = 3;
132+
133+
reader.seek(SeekFrom::Start(*section_offsets.get(&header_type).unwrap()))?;
134+
let header = read_header(&mut reader, *section_sizes.get(&header_type).unwrap())?;
115135
if header.field_size != 32 {
116136
return Err(Error::new(ErrorKind::InvalidData, "This parser only supports 32-byte fields"));
117137
}
118138
if header.prime_size != hex!("010000f093f5e1439170b97948e833285d588181b64550b829a031e1724e6430") {
119139
return Err(Error::new(ErrorKind::InvalidData, "This parser only supports bn256"));
120140
}
121-
let sec_type = reader.read_u32::<LittleEndian>()?;
122-
let sec_size = reader.read_u64::<LittleEndian>()?;
123-
let constraints = read_constraints::<&mut R, Bn256>(&mut reader, sec_size, &header)?;
124141

125-
let sec_type = reader.read_u32::<LittleEndian>()?;
126-
let sec_size = reader.read_u64::<LittleEndian>()?;
127-
let wire_mapping = read_map(&mut reader, sec_size, &header)?;
142+
reader.seek(SeekFrom::Start(*section_offsets.get(&constraint_type).unwrap()))?;
143+
let constraints = read_constraints::<&mut R, Bn256>(&mut reader, *section_sizes.get(&constraint_type).unwrap(), &header)?;
144+
145+
reader.seek(SeekFrom::Start(*section_offsets.get(&wire2label_type).unwrap()))?;
146+
let wire_mapping = read_map(&mut reader, *section_sizes.get(&wire2label_type).unwrap(), &header)?;
128147

129148
Ok(R1CSFile {
130149
version,
@@ -136,6 +155,8 @@ pub fn from_reader<R: Read>(mut reader: R) -> Result<R1CSFile<Bn256>> {
136155

137156
#[cfg(test)]
138157
mod tests {
158+
use std::io::{BufReader, Cursor};
159+
139160
use super::*;
140161

141162
#[test]
@@ -193,7 +214,8 @@ mod tests {
193214
);
194215

195216
use crate::bellman_ce::pairing::ff;
196-
let file = from_reader(&data[..]).unwrap();
217+
let reader = BufReader::new(Cursor::new(&data[..]));
218+
let file = from_reader(reader).unwrap();
197219
assert_eq!(file.version, 1);
198220

199221
assert_eq!(file.header.field_size, 32);

src/reader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use byteorder::{LittleEndian, ReadBytesExt};
33
use itertools::Itertools;
44
use std::collections::BTreeMap;
55
use std::fs::{File, OpenOptions};
6-
use std::io::{BufRead, BufReader, Read};
6+
use std::io::{BufRead, BufReader, Read, Seek};
77
use std::str;
88

99
use crate::bellman_ce::{
@@ -224,7 +224,7 @@ fn load_r1cs_from_bin_file(filename: &str) -> (R1CS<Bn256>, Vec<usize>) {
224224
}
225225

226226
/// load r1cs from bin by a reader
227-
fn load_r1cs_from_bin<R: Read>(reader: R) -> (R1CS<Bn256>, Vec<usize>) {
227+
fn load_r1cs_from_bin<R: Read + Seek>(reader: R) -> (R1CS<Bn256>, Vec<usize>) {
228228
let file = crate::r1cs_file::from_reader(reader).expect("unable to read.");
229229
let num_inputs = (1 + file.header.n_pub_in + file.header.n_pub_out) as usize;
230230
let num_variables = file.header.n_wires as usize;

0 commit comments

Comments
 (0)