|
@ -4,8 +4,8 @@ |
|
|
use byteorder::{LittleEndian, ReadBytesExt};
|
|
|
use byteorder::{LittleEndian, ReadBytesExt};
|
|
|
use std::io::{Error, ErrorKind};
|
|
|
use std::io::{Error, ErrorKind};
|
|
|
|
|
|
|
|
|
use ark_ec::pairing::Pairing;
|
|
|
|
|
|
use ark_serialize::{CanonicalDeserialize, SerializationError, SerializationError::IoError};
|
|
|
|
|
|
|
|
|
use ark_ff::PrimeField;
|
|
|
|
|
|
use ark_serialize::{SerializationError, SerializationError::IoError};
|
|
|
use ark_std::io::{Read, Seek, SeekFrom};
|
|
|
use ark_std::io::{Read, Seek, SeekFrom};
|
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
use std::collections::HashMap;
|
|
@ -15,16 +15,16 @@ type IoResult = Result; |
|
|
use super::{ConstraintVec, Constraints};
|
|
|
use super::{ConstraintVec, Constraints};
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
#[derive(Clone, Debug)]
|
|
|
pub struct R1CS<E: Pairing> {
|
|
|
|
|
|
|
|
|
pub struct R1CS<F: PrimeField> {
|
|
|
pub num_inputs: usize,
|
|
|
pub num_inputs: usize,
|
|
|
pub num_aux: usize,
|
|
|
pub num_aux: usize,
|
|
|
pub num_variables: usize,
|
|
|
pub num_variables: usize,
|
|
|
pub constraints: Vec<Constraints<E>>,
|
|
|
|
|
|
|
|
|
pub constraints: Vec<Constraints<F>>,
|
|
|
pub wire_mapping: Option<Vec<usize>>,
|
|
|
pub wire_mapping: Option<Vec<usize>>,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl<E: Pairing> From<R1CSFile<E>> for R1CS<E> {
|
|
|
|
|
|
fn from(file: R1CSFile<E>) -> Self {
|
|
|
|
|
|
|
|
|
impl<F: PrimeField> From<R1CSFile<F>> for R1CS<F> {
|
|
|
|
|
|
fn from(file: R1CSFile<F>) -> Self {
|
|
|
let num_inputs = (1 + file.header.n_pub_in + file.header.n_pub_out) as usize;
|
|
|
let num_inputs = (1 + file.header.n_pub_in + file.header.n_pub_out) as usize;
|
|
|
let num_variables = file.header.n_wires as usize;
|
|
|
let num_variables = file.header.n_wires as usize;
|
|
|
let num_aux = num_variables - num_inputs;
|
|
|
let num_aux = num_variables - num_inputs;
|
|
@ -38,20 +38,20 @@ impl From> for R1CS { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
pub struct R1CSFile<E: Pairing> {
|
|
|
|
|
|
|
|
|
pub struct R1CSFile<F: PrimeField> {
|
|
|
pub version: u32,
|
|
|
pub version: u32,
|
|
|
pub header: Header,
|
|
|
pub header: Header,
|
|
|
pub constraints: Vec<Constraints<E>>,
|
|
|
|
|
|
|
|
|
pub constraints: Vec<Constraints<F>>,
|
|
|
pub wire_mapping: Vec<u64>,
|
|
|
pub wire_mapping: Vec<u64>,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl<E: Pairing> R1CSFile<E> {
|
|
|
|
|
|
|
|
|
impl<F: PrimeField> R1CSFile<F> {
|
|
|
/// reader must implement the Seek trait, for example with a Cursor
|
|
|
/// reader must implement the Seek trait, for example with a Cursor
|
|
|
///
|
|
|
///
|
|
|
/// ```rust,ignore
|
|
|
/// ```rust,ignore
|
|
|
/// let reader = BufReader::new(Cursor::new(&data[..]));
|
|
|
/// let reader = BufReader::new(Cursor::new(&data[..]));
|
|
|
/// ```
|
|
|
/// ```
|
|
|
pub fn new<R: Read + Seek>(mut reader: R) -> IoResult<R1CSFile<E>> {
|
|
|
|
|
|
|
|
|
pub fn new<R: Read + Seek>(mut reader: R) -> IoResult<R1CSFile<F>> {
|
|
|
let mut magic = [0u8; 4];
|
|
|
let mut magic = [0u8; 4];
|
|
|
reader.read_exact(&mut magic)?;
|
|
|
reader.read_exact(&mut magic)?;
|
|
|
if magic != [0x72, 0x31, 0x63, 0x73] {
|
|
|
if magic != [0x72, 0x31, 0x63, 0x73] {
|
|
@ -117,7 +117,7 @@ impl R1CSFile { |
|
|
|
|
|
|
|
|
reader.seek(SeekFrom::Start(*constraint_offset?))?;
|
|
|
reader.seek(SeekFrom::Start(*constraint_offset?))?;
|
|
|
|
|
|
|
|
|
let constraints = read_constraints::<&mut R, E>(&mut reader, &header)?;
|
|
|
|
|
|
|
|
|
let constraints = read_constraints::<&mut R, F>(&mut reader, &header)?;
|
|
|
|
|
|
|
|
|
let wire2label_offset = sec_offsets.get(&wire2label_type).ok_or_else(|| {
|
|
|
let wire2label_offset = sec_offsets.get(&wire2label_type).ok_or_else(|| {
|
|
|
Error::new(
|
|
|
Error::new(
|
|
@ -177,15 +177,16 @@ impl Header { |
|
|
let mut prime_size = vec![0u8; field_size as usize];
|
|
|
let mut prime_size = vec![0u8; field_size as usize];
|
|
|
reader.read_exact(&mut prime_size)?;
|
|
|
reader.read_exact(&mut prime_size)?;
|
|
|
|
|
|
|
|
|
if prime_size
|
|
|
|
|
|
!= hex::decode("010000f093f5e1439170b97948e833285d588181b64550b829a031e1724e6430")
|
|
|
|
|
|
.unwrap()
|
|
|
|
|
|
{
|
|
|
|
|
|
return Err(IoError(Error::new(
|
|
|
|
|
|
ErrorKind::InvalidData,
|
|
|
|
|
|
"This parser only supports bn256",
|
|
|
|
|
|
)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
// TODO WIP
|
|
|
|
|
|
// if prime_size
|
|
|
|
|
|
// != hex::decode("010000f093f5e1439170b97948e833285d588181b64550b829a031e1724e6430")
|
|
|
|
|
|
// .unwrap()
|
|
|
|
|
|
// {
|
|
|
|
|
|
// return Err(IoError(Error::new(
|
|
|
|
|
|
// ErrorKind::InvalidData,
|
|
|
|
|
|
// "This parser only supports bn256",
|
|
|
|
|
|
// )));
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
Ok(Header {
|
|
|
Ok(Header {
|
|
|
field_size,
|
|
|
field_size,
|
|
@ -200,29 +201,29 @@ impl Header { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn read_constraint_vec<R: Read, E: Pairing>(mut reader: R) -> IoResult<ConstraintVec<E>> {
|
|
|
|
|
|
|
|
|
fn read_constraint_vec<R: Read, F: PrimeField>(mut reader: R) -> IoResult<ConstraintVec<F>> {
|
|
|
let n_vec = reader.read_u32::<LittleEndian>()? as usize;
|
|
|
let n_vec = reader.read_u32::<LittleEndian>()? as usize;
|
|
|
let mut vec = Vec::with_capacity(n_vec);
|
|
|
let mut vec = Vec::with_capacity(n_vec);
|
|
|
for _ in 0..n_vec {
|
|
|
for _ in 0..n_vec {
|
|
|
vec.push((
|
|
|
vec.push((
|
|
|
reader.read_u32::<LittleEndian>()? as usize,
|
|
|
reader.read_u32::<LittleEndian>()? as usize,
|
|
|
E::ScalarField::deserialize_uncompressed(&mut reader)?,
|
|
|
|
|
|
|
|
|
F::deserialize_uncompressed(&mut reader)?,
|
|
|
));
|
|
|
));
|
|
|
}
|
|
|
}
|
|
|
Ok(vec)
|
|
|
Ok(vec)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
fn read_constraints<R: Read, E: Pairing>(
|
|
|
|
|
|
|
|
|
fn read_constraints<R: Read, F: PrimeField>(
|
|
|
mut reader: R,
|
|
|
mut reader: R,
|
|
|
header: &Header,
|
|
|
header: &Header,
|
|
|
) -> IoResult<Vec<Constraints<E>>> {
|
|
|
|
|
|
|
|
|
) -> IoResult<Vec<Constraints<F>>> {
|
|
|
// todo check section size
|
|
|
// todo check section size
|
|
|
let mut vec = Vec::with_capacity(header.n_constraints as usize);
|
|
|
let mut vec = Vec::with_capacity(header.n_constraints as usize);
|
|
|
for _ in 0..header.n_constraints {
|
|
|
for _ in 0..header.n_constraints {
|
|
|
vec.push((
|
|
|
vec.push((
|
|
|
read_constraint_vec::<&mut R, E>(&mut reader)?,
|
|
|
|
|
|
read_constraint_vec::<&mut R, E>(&mut reader)?,
|
|
|
|
|
|
read_constraint_vec::<&mut R, E>(&mut reader)?,
|
|
|
|
|
|
|
|
|
read_constraint_vec::<&mut R, F>(&mut reader)?,
|
|
|
|
|
|
read_constraint_vec::<&mut R, F>(&mut reader)?,
|
|
|
|
|
|
read_constraint_vec::<&mut R, F>(&mut reader)?,
|
|
|
));
|
|
|
));
|
|
|
}
|
|
|
}
|
|
|
Ok(vec)
|
|
|
Ok(vec)
|
|
@ -251,7 +252,7 @@ fn read_map(mut reader: R, size: u64, header: &Header) -> IoResult |
|
|
#[cfg(test)]
|
|
|
#[cfg(test)]
|
|
|
mod tests {
|
|
|
mod tests {
|
|
|
use super::*;
|
|
|
use super::*;
|
|
|
use ark_bn254::{Bn254, Fr};
|
|
|
|
|
|
|
|
|
use ark_bn254::Fr;
|
|
|
use ark_std::io::{BufReader, Cursor};
|
|
|
use ark_std::io::{BufReader, Cursor};
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
#[test]
|
|
@ -309,7 +310,7 @@ mod tests { |
|
|
);
|
|
|
);
|
|
|
|
|
|
|
|
|
let reader = BufReader::new(Cursor::new(&data[..]));
|
|
|
let reader = BufReader::new(Cursor::new(&data[..]));
|
|
|
let file = R1CSFile::<Bn254>::new(reader).unwrap();
|
|
|
|
|
|
|
|
|
let file = R1CSFile::<Fr>::new(reader).unwrap();
|
|
|
assert_eq!(file.version, 1);
|
|
|
assert_eq!(file.version, 1);
|
|
|
|
|
|
|
|
|
assert_eq!(file.header.field_size, 32);
|
|
|
assert_eq!(file.header.field_size, 32);
|
|
|