1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

generate r1cs in cli, make curve generic, section size issue

This commit is contained in:
schaeff 2022-04-27 15:12:32 +02:00
parent 3e9d2fa683
commit a250b0b107
5 changed files with 63 additions and 14 deletions

1
Cargo.lock generated
View file

@ -2888,6 +2888,7 @@ dependencies = [
"tempdir",
"typed-arena",
"zokrates_abi",
"zokrates_circom",
"zokrates_common",
"zokrates_core",
"zokrates_field",

View file

@ -1,8 +1,10 @@
use byteorder::{LittleEndian, WriteBytesExt};
use std::collections::HashSet;
use std::io::Result;
use std::{io::Write, ops::Add};
use zokrates_core::flat_absy::FlatVariable;
use zokrates_core::ir::{LinComb, Prog, Statement};
use zokrates_field::{Bn128Field, Field};
use zokrates_field::Field;
pub struct Header {
pub field_size: u32,
@ -28,11 +30,35 @@ fn write_header<W: Write>(writer: &mut W, header: Header) -> Result<()> {
Ok(())
}
pub fn write_r1cs<W: Write>(writer: &mut W, p: Prog<Bn128Field>) -> Result<()> {
pub fn write_r1cs<T: Field, W: Write>(writer: &mut W, p: Prog<T>) -> Result<()> {
let modulo_byte_count = T::max_value().to_biguint().add(1u32).to_bytes_le().len() as u32;
let n_wires = p
.statements
.iter()
.fold(
HashSet::default(),
|mut acc: HashSet<FlatVariable>, s| match s {
Statement::Constraint(q, l, _) => {
acc.extend(
q.left
.0
.iter()
.chain(q.right.0.iter())
.chain(l.0.iter())
.filter_map(|(v, _)| if v.id > 0 { Some(v) } else { None }),
);
acc
}
_ => acc,
},
)
.len();
let header = Header {
field_size: 32,
prime_size: Bn128Field::max_value().to_biguint().add(1u32).to_bytes_le(),
n_wires: 0, // TODO: count private variables
field_size: modulo_byte_count,
prime_size: T::max_value().to_biguint().add(1u32).to_bytes_le(),
n_wires: n_wires as u32,
n_pub_out: p.return_count as u32,
n_pub_in: p.arguments.iter().filter(|a| !a.private).count() as u32,
n_prv_in: p.arguments.iter().filter(|a| a.private).count() as u32,
@ -51,14 +77,15 @@ pub fn write_r1cs<W: Write>(writer: &mut W, p: Prog<Bn128Field>) -> Result<()> {
// section type: constraints
// type
writer.write_u32::<LittleEndian>(2u32)?;
writer.write_u32::<LittleEndian>(2)?;
// size: 4 per constraint + (32 + 4) per summand
let size = p
.statements
.iter()
.map(|s| match s {
Statement::Constraint(q, l, _) => {
((q.left.0.len() + q.right.0.len() + l.0.len()) * (32 + 4) + 4) as u64
((q.left.0.len() + q.right.0.len() + l.0.len()) * (modulo_byte_count as usize + 4)
+ 4) as u64
}
_ => 0,
})
@ -87,14 +114,14 @@ pub fn write_r1cs<W: Write>(writer: &mut W, p: Prog<Bn128Field>) -> Result<()> {
Ok(())
}
fn write_constraints<W: Write>(writer: &mut W, p: &Prog<Bn128Field>, shift: u32) -> Result<()> {
fn write_constraints<T: Field, W: Write>(writer: &mut W, p: &Prog<T>, shift: u32) -> Result<()> {
for s in &p.statements {
write_statement(writer, s, shift)?;
}
Ok(())
}
fn write_statement<W: Write>(writer: &mut W, s: &Statement<Bn128Field>, shift: u32) -> Result<()> {
fn write_statement<T: Field, W: Write>(writer: &mut W, s: &Statement<T>, shift: u32) -> Result<()> {
match s {
Statement::Constraint(quad, lin, _) => {
let left = &quad.left;
@ -108,7 +135,7 @@ fn write_statement<W: Write>(writer: &mut W, s: &Statement<Bn128Field>, shift: u
Ok(())
}
fn write_lincomb<W: Write>(writer: &mut W, l: &LinComb<Bn128Field>, shift: u32) -> Result<()> {
fn write_lincomb<T: Field, W: Write>(writer: &mut W, l: &LinComb<T>, shift: u32) -> Result<()> {
writer.write_u32::<LittleEndian>(l.0.len() as u32)?;
for (var, coeff) in &l.0 {
let shift = shift as isize;
@ -132,7 +159,7 @@ fn write_lincomb<W: Write>(writer: &mut W, l: &LinComb<Bn128Field>, shift: u32)
}
// for now we do not write any signal map
fn write_table<W>(_: &mut W, _: &Prog<Bn128Field>) -> Result<()> {
fn write_table<T: Field, W: Write>(_: &mut W, _: &Prog<T>) -> Result<()> {
Ok(())
}
@ -144,6 +171,7 @@ mod tests {
flat_absy::FlatVariable,
ir::{LinComb, Statement},
};
use zokrates_field::Bn128Field;
#[test]
fn empty() {

View file

@ -21,6 +21,7 @@ regex = "0.2"
zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false }
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
zokrates_core = { version = "0.6", path = "../zokrates_core", default-features = false }
zokrates_circom = { version = "0.1", path = "../zokrates_circom", default-features = false }
typed-arena = "1.4.1"
zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"}
zokrates_common = { version = "0.1", path = "../zokrates_common" }

View file

@ -1,6 +1,7 @@
use zokrates_common::constants::*;
pub const FLATTENED_CODE_DEFAULT_PATH: &str = "out";
pub const R1CS_DEFAULT_PATH: &str = "out.r1cs";
pub const ABI_SPEC_DEFAULT_PATH: &str = "abi.json";
pub const VERIFICATION_KEY_DEFAULT_PATH: &str = "verification.key";
pub const PROVING_KEY_DEFAULT_PATH: &str = "proving.key";

View file

@ -6,6 +6,7 @@ use std::fs::File;
use std::io::{BufReader, BufWriter, Read};
use std::path::{Path, PathBuf};
use typed_arena::Arena;
use zokrates_circom::write_r1cs;
use zokrates_common::constants::BN128;
use zokrates_common::helpers::CurveParameter;
use zokrates_core::compile::{compile, CompileConfig, CompileError};
@ -46,7 +47,15 @@ pub fn subcommand() -> App<'static, 'static> {
.takes_value(true)
.required(false)
.default_value(cli_constants::FLATTENED_CODE_DEFAULT_PATH)
).arg(Arg::with_name("curve")
).arg(Arg::with_name("r1cs")
.short("r1cs")
.long("r1cs")
.help("Path of the output r1cs file")
.value_name("FILE")
.takes_value(true)
.required(false)
.default_value(cli_constants::R1CS_DEFAULT_PATH)
).arg(Arg::with_name("curve")
.short("c")
.long("curve")
.help("Curve to be used in the compilation")
@ -75,6 +84,7 @@ fn cli_compile<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
println!("Compiling {}\n", sub_matches.value_of("input").unwrap());
let path = PathBuf::from(sub_matches.value_of("input").unwrap());
let bin_output_path = Path::new(sub_matches.value_of("output").unwrap());
let r1cs_output_path = Path::new(sub_matches.value_of("r1cs").unwrap());
let abi_spec_path = Path::new(sub_matches.value_of("abi-spec").unwrap());
log::debug!("Load entry point file {}", path.display());
@ -133,9 +143,17 @@ fn cli_compile<T: Field>(sub_matches: &ArgMatches) -> Result<(), String> {
let bin_output_file = File::create(&bin_output_path)
.map_err(|why| format!("Could not create {}: {}", bin_output_path.display(), why))?;
let mut writer = BufWriter::new(bin_output_file);
let r1cs_output_file = File::create(&r1cs_output_path)
.map_err(|why| format!("Could not create {}: {}", r1cs_output_path.display(), why))?;
match program_flattened.serialize(&mut writer) {
let mut bin_writer = BufWriter::new(bin_output_file);
let mut r1cs_writer = BufWriter::new(r1cs_output_file);
let program_flattened = program_flattened.collect();
write_r1cs(&mut r1cs_writer, program_flattened.clone()).unwrap();
match program_flattened.serialize(&mut bin_writer) {
Ok(constraint_count) => {
// serialize ABI spec and write to JSON file
log::debug!("Serialize ABI");