1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

Rust-side of libsnark integration adapted.

This commit is contained in:
Jacob Eberhardt 2017-03-16 17:34:57 +01:00
parent 697f10f39c
commit bdf96e2bbb
4 changed files with 64 additions and 22 deletions

View file

@ -14,27 +14,27 @@
using namespace std;
using namespace libsnark;
bool _run_libsnark(const int* A, const int* B, const int* C, const int* witness, int constraints, int variables){
bool _run_libsnark(const char* A, const char* B, const char* C, const char* witness, int constraints, int variables){
r1cs_constraint_system<Fr<default_r1cs_ppzksnark_pp> > cs;
cs.primary_input_size = variables - 1;
cs.auxiliary_input_size = 0;
cout << endl << "run_libsnark" << endl;
for (int row = 0; row < constraints; row++) {
// cout << "row " << row << endl;
cout << "row " << row << endl;
linear_combination<Fr<default_r1cs_ppzksnark_pp> > lin_comb_A, lin_comb_B, lin_comb_C;
for (int idx = 0; idx < variables; idx++) {
// using (constraints + 2) because of the representation of Rust's Vec<_>
if (A[row * (constraints + 2) + idx] != 0) {
// cout << "A(" << idx << ", " << A[row * (constraints + 2) + idx] << ")" << endl;
cout << "A(" << idx << ", " << A[row * (constraints + 2) + idx] << ")" << endl;
lin_comb_A.add_term(idx, A[row * (constraints + 2) + idx]);
}
if (B[row * (constraints + 2) + idx] != 0) {
// cout << "B(" << idx << ", " << B[row * (constraints + 2) + idx] << ")" << endl;
cout << "B(" << idx << ", " << B[row * (constraints + 2) + idx] << ")" << endl;
lin_comb_B.add_term(idx, B[row * (constraints + 2) + idx]);
}
if (C[row * (constraints + 2) + idx] != 0) {
// cout << "C(" << idx << ", " << C[row * (constraints + 2) + idx] << ")" << endl;
cout << "C(" << idx << ", " << C[row * (constraints + 2) + idx] << ")" << endl;
lin_comb_C.add_term(idx, C[row * (constraints + 2) + idx]);
}
}

View file

@ -10,10 +10,10 @@ extern "C" {
#include <stdbool.h>
bool _run_libsnark(const int* A,
const int* B,
const int* C,
const int* witness,
bool _run_libsnark(const char* A,
const char* B,
const char* C,
const char* witness,
int constraints,
int variables);

View file

@ -4,7 +4,7 @@
// @date 2017
use num::{Integer, Zero, One};
use num::bigint::{BigInt, ToBigInt};
use num::bigint::{BigInt, ToBigInt, Sign};
use std::convert::From;
use std::ops::{Add, Sub, Mul, Div};
use std::fmt;
@ -29,6 +29,8 @@ pub trait Field : From<i32> + From<u32> + From<usize> + for<'a> From<&'a str>
{
/// Returns a byte slice of this `Field`'s contents in decimal `String` representation.
fn into_dec_bytes(&self) -> Vec<u8>;
/// Returns this `Field`'s contents as big-endian byte vector
fn into_byte_vector(&self) -> Vec<u8>;
/// Returns the multiplicative inverse, i.e.: self * self.inverse_mul() = Self::one()
fn inverse_mul(&self) -> Self;
/// Returns the smallest value that can be represented by this field type.
@ -49,6 +51,13 @@ impl Field for FieldPrime {
fn into_dec_bytes(&self) -> Vec<u8> {
self.value.to_str_radix(10).to_string().into_bytes()
}
fn into_byte_vector(&self) -> Vec<u8> {
let (sign, val) = self.value.to_bytes_be();
assert!(sign!=Sign::Minus);
val
}
fn inverse_mul(&self) -> FieldPrime {
let (b, s, _) = extended_euclid(&self.value, &*P);
assert_eq!(b, BigInt::one());

View file

@ -6,33 +6,66 @@
extern crate libc;
use self::libc::c_int;
use self::libc::uint8_t;
use field::Field;
#[link(name = "snark")]
#[link(name = "supercop")]
#[link(name = "gmp")]
#[link(name = "gmpxx")]
extern {
fn _run_libsnark(A: *const c_int, B: *const c_int, C: *const c_int, witness: *const c_int, constraints: c_int, variables: c_int) -> bool;
fn _run_libsnark(A: *const uint8_t, B: *const uint8_t, C: *const uint8_t, witness: *const uint8_t, constraints: c_int, variables: c_int) -> bool;
}
pub fn run_libsnark(variables: Vec<String>, a: Vec<Vec<(usize, i32)>>, b: Vec<Vec<(usize, i32)>>, c: Vec<Vec<(usize, i32)>>, witness: Vec<i32>) -> bool {
// assumes that field elements can be represented with 32 bytes
pub fn run_libsnark<T: Field>(variables: Vec<String>, a: Vec<Vec<(usize, T)>>, b: Vec<Vec<(usize, T)>>, c: Vec<Vec<(usize, T)>>, witness: Vec<T>) -> bool {
let num_constraints = a.len();
let num_variables = variables.len();
let mut a_arr: Vec<i32> = vec![0; num_constraints * num_variables];
let mut b_arr: Vec<i32> = vec![0; num_constraints * num_variables];
let mut c_arr: Vec<i32> = vec![0; num_constraints * num_variables];
// let size_variables = T::get_required_bits;
//initialize matrix entries with 0s.
let mut a_arr: Vec<[u8;32]> = vec![[0u8;32]; num_constraints * num_variables];
let mut b_arr: Vec<[u8;32]> = vec![[0u8;32]; num_constraints * num_variables];
let mut c_arr: Vec<[u8;32]> = vec![[0u8;32]; num_constraints * num_variables];
let mut w_arr: Vec<[u8;32]> = vec![[0u8;32]; num_variables];
//before:
//let mut c_arr: Vec<i32> = vec![0; num_constraints * num_variables];
for row in 0..num_constraints {
for &(idx, val) in &a[row] {
a_arr[row * num_variables + idx] = val;
for &(idx, ref val) in &a[row] {
a_arr[row * num_variables + idx] = vec_as_u8_32_array(val.into_byte_vector());
}
for &(idx, val) in &b[row] {
b_arr[row * num_variables + idx] = val;
for &(idx, ref val) in &b[row] {
b_arr[row * num_variables + idx] = vec_as_u8_32_array(val.into_byte_vector());
}
for &(idx, val) in &c[row] {
c_arr[row * num_variables + idx] = val;
for &(idx, ref val) in &c[row] {
c_arr[row * num_variables + idx] = vec_as_u8_32_array(val.into_byte_vector());
}
}
//convert witness
for (index,value) in witness.into_iter().enumerate() {
w_arr[index] = vec_as_u8_32_array(value.into_byte_vector());
}
//debugging output
println!("debugging output:");
println!("a_arr {:?}", a_arr);
println!("b_arr {:?}", b_arr);
println!("c_arr {:?}", c_arr);
println!("w_arr {:?}", w_arr);
unsafe {
_run_libsnark(a_arr.as_ptr(), b_arr.as_ptr(), c_arr.as_ptr(), witness.as_ptr(), num_constraints as i32, num_variables as i32)
_run_libsnark(a_arr[0].as_ptr(),b_arr[0].as_ptr(), c_arr[0].as_ptr(), w_arr[0].as_ptr(), num_constraints as i32, num_variables as i32)
}
}
// utility function. Converts a Fields vector-based byte representation to fixed size array.
fn vec_as_u8_32_array(vec: Vec<u8>) -> [u8;32]{
assert!(vec.len()<=32);
let mut array = [0u8;32];
for (index,byte) in vec.into_iter().enumerate() {
array[31-index] = byte;
}
array
}