generate r1cs in cli, make curve generic, section size issue
This commit is contained in:
parent
3e9d2fa683
commit
a250b0b107
5 changed files with 63 additions and 14 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2888,6 +2888,7 @@ dependencies = [
|
|||
"tempdir",
|
||||
"typed-arena",
|
||||
"zokrates_abi",
|
||||
"zokrates_circom",
|
||||
"zokrates_common",
|
||||
"zokrates_core",
|
||||
"zokrates_field",
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue