Add Sub to R1CS; Add Dockerfile
Change CURVE to ALT_BN128 Remove 'Expression::' with import
This commit is contained in:
parent
6bcf021124
commit
f31e109413
10 changed files with 175 additions and 141 deletions
1
.dockerignore
Normal file
1
.dockerignore
Normal file
|
@ -0,0 +1 @@
|
|||
target
|
30
Dockerfile
Normal file
30
Dockerfile
Normal file
|
@ -0,0 +1,30 @@
|
|||
FROM ubuntu:14.04
|
||||
|
||||
MAINTAINER Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
|
||||
WORKDIR /root
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
wget unzip curl \
|
||||
build-essential git libgmp3-dev libprocps3-dev libgtest-dev python-markdown libboost-all-dev libssl-dev
|
||||
|
||||
RUN wget https://github.com/scipr-lab/libsnark/archive/master.zip \
|
||||
&& mv master.zip libsnark.zip \
|
||||
&& unzip libsnark.zip \
|
||||
&& cd libsnark-master \
|
||||
&& ./prepare-depends.sh
|
||||
|
||||
RUN curl https://sh.rustup.rs -sSf | \
|
||||
sh -s -- --default-toolchain nightly -y
|
||||
|
||||
ENV PATH=/root/.cargo/bin:$PATH
|
||||
|
||||
RUN cd libsnark-master \
|
||||
&& make install lib PREFIX=/usr/local \
|
||||
NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 CURVE=ALT_BN128 FEATUREFLAGS="-DBINARY_OUTPUT=1 -DMONTGOMERY_OUTPUT=1 -DNO_PT_COMPRESSION=1"
|
||||
|
||||
COPY . /root/VerifiableStatementCompiler
|
||||
|
||||
RUN cd VerifiableStatementCompiler \
|
||||
&& cargo build
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
libsnark has to be installed to: `lib/libsnark`
|
||||
|
||||
set `LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/lib/libsnark/lib`
|
||||
`export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib`
|
||||
|
|
9
build.rs
9
build.rs
|
@ -1,14 +1,13 @@
|
|||
extern crate gcc;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rustc-link-search=lib/libsnark/lib");
|
||||
println!("cargo:rustc-link-search=/usr/local/lib");
|
||||
gcc::Config::new()
|
||||
.cpp(true)
|
||||
.include("lib/libsnark/include")
|
||||
.include("lib/libsnark/include/libsnark")
|
||||
.include("/usr/local/include")
|
||||
.include("/usr/local/include/libsnark")
|
||||
.flag("-std=c++11")
|
||||
// .define("CURVE", Some("ALT_BN128"))
|
||||
.define("CURVE_BN128", None)
|
||||
.define("CURVE_ALT_BN128", None)
|
||||
.file("lib/wraplibsnark.cpp")
|
||||
.compile("libwraplibsnark.a");
|
||||
}
|
||||
|
|
|
@ -3,10 +3,8 @@
|
|||
// comment
|
||||
|
||||
def qeval(x):
|
||||
// comment in function
|
||||
// comment
|
||||
y = x**3
|
||||
//b = x**5
|
||||
//z = x + 3 - y + 7
|
||||
//a = z * y + 3 * y
|
||||
b = x**5
|
||||
return y + x + y
|
||||
// comment after function
|
||||
// comment
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// only using sub, no need to flatten
|
||||
def qeval(a):
|
||||
b = a - 5
|
||||
b = a + 100
|
||||
c = b + a + b
|
||||
d = b - a - 3 - a
|
||||
return d + c
|
||||
e = d + 3 - a
|
||||
return d + c + e
|
||||
|
|
|
@ -15,20 +15,20 @@ bool _run_libsnark(const int* A, const int* B, const int* C, const int* witness,
|
|||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,10 +120,10 @@ impl fmt::Display for Expression {
|
|||
match *self {
|
||||
Expression::NumberLiteral(ref i) => write!(f, "{}", i),
|
||||
Expression::VariableReference(ref var) => write!(f, "{}", var),
|
||||
Expression::Add(ref lhs, ref rhs) => write!(f, "{} + {}", lhs, rhs),
|
||||
Expression::Sub(ref lhs, ref rhs) => write!(f, "{} - {}", lhs, rhs),
|
||||
Expression::Mult(ref lhs, ref rhs) => write!(f, "{} * {}", lhs, rhs),
|
||||
Expression::Div(ref lhs, ref rhs) => write!(f, "{} / {}", lhs, rhs),
|
||||
Expression::Add(ref lhs, ref rhs) => write!(f, "({} + {})", lhs, rhs),
|
||||
Expression::Sub(ref lhs, ref rhs) => write!(f, "({} - {})", lhs, rhs),
|
||||
Expression::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs),
|
||||
Expression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
||||
Expression::Pow(ref lhs, ref rhs) => write!(f, "{}**{}", lhs, rhs),
|
||||
Expression::IfElse(ref condition, ref consequent, ref alternative) => write!(f, "{} ? {} : {}", condition, consequent, alternative),
|
||||
}
|
||||
|
|
129
src/parser.rs
129
src/parser.rs
|
@ -5,6 +5,7 @@ use std::io::prelude::*;
|
|||
use std::fs::File;
|
||||
use self::regex::Regex;
|
||||
use ast::*;
|
||||
use ast::Expression::*;
|
||||
|
||||
fn parse_expression_rhs(text: String) -> Expression {
|
||||
let op_regex = Regex::new(r"^((?P<lhs>[[:alnum:]]+)(?P<op>(\*\*|[\+\-\*/]))(?P<rhs>.+)|(?P<var>[[:alpha:]][[:alnum:]]*)|(?P<num>\d+))$").unwrap();
|
||||
|
@ -15,30 +16,30 @@ fn parse_expression_rhs(text: String) -> Expression {
|
|||
match op_regex.captures(&line) {
|
||||
Some(x) => {
|
||||
if let Some(var) = x.name("var") {
|
||||
Expression::VariableReference(var.as_str().to_string())
|
||||
VariableReference(var.as_str().to_string())
|
||||
} else if let Some(num) = x.name("num") {
|
||||
Expression::NumberLiteral(num.as_str().parse::<i32>().unwrap())
|
||||
NumberLiteral(num.as_str().parse::<i32>().unwrap())
|
||||
} else {
|
||||
let lhs = if variable_regex.is_match(&x["lhs"]) {
|
||||
Box::new(Expression::VariableReference(x["lhs"].to_string()))
|
||||
box VariableReference(x["lhs"].to_string())
|
||||
} else if number_regex.is_match(&x["lhs"]) {
|
||||
Box::new(Expression::NumberLiteral(x["lhs"].parse::<i32>().unwrap()))
|
||||
box NumberLiteral(x["lhs"].parse::<i32>().unwrap())
|
||||
} else {
|
||||
panic!("Could not read lhs: {:?}", &x["lhs"])
|
||||
};
|
||||
let rhs = if variable_regex.is_match(&x["rhs"]) {
|
||||
Box::new(Expression::VariableReference(x["rhs"].to_string()))
|
||||
box VariableReference(x["rhs"].to_string())
|
||||
} else if number_regex.is_match(&x["rhs"]) {
|
||||
Box::new(Expression::NumberLiteral(x["rhs"].parse::<i32>().unwrap()))
|
||||
Box::new(NumberLiteral(x["rhs"].parse::<i32>().unwrap()))
|
||||
} else {
|
||||
Box::new(parse_expression_rhs(x["rhs"].to_string()))
|
||||
box parse_expression_rhs(x["rhs"].to_string())
|
||||
};
|
||||
match &x["op"] {
|
||||
"+" => Expression::Add(lhs, rhs),
|
||||
"-" => Expression::Sub(lhs, rhs),
|
||||
"*" => Expression::Mult(lhs, rhs),
|
||||
"/" => Expression::Div(lhs, rhs),
|
||||
"**" if number_regex.is_match(&x["rhs"]) => Expression::Pow(lhs, rhs),
|
||||
"+" => Add(lhs, rhs),
|
||||
"-" => Sub(lhs, rhs),
|
||||
"*" => Mult(lhs, rhs),
|
||||
"/" => Div(lhs, rhs),
|
||||
"**" if number_regex.is_match(&x["rhs"]) => Pow(lhs, rhs),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +51,7 @@ fn parse_expression_rhs(text: String) -> Expression {
|
|||
"<" => Condition::Lt(parse_expression_rhs(x["condlhs"].to_string()), parse_expression_rhs(x["condrhs"].to_string())),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Expression::IfElse(box condition, box parse_expression_rhs(x["consequent"].to_string()), box parse_expression_rhs(x["alternative"].to_string()))
|
||||
IfElse(box condition, box parse_expression_rhs(x["consequent"].to_string()), box parse_expression_rhs(x["alternative"].to_string()))
|
||||
},
|
||||
None => panic!("Could not parse rhs of expression: {:?}", text),
|
||||
},
|
||||
|
@ -119,13 +120,13 @@ pub fn parse_program(file: File) -> Prog {
|
|||
|
||||
fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut i32, expr: Expression) -> Expression {
|
||||
match expr {
|
||||
x @ Expression::NumberLiteral(_) |
|
||||
x @ Expression::VariableReference(_) => x,
|
||||
ref x @ Expression::Add(..) |
|
||||
ref x @ Expression::Sub(..) |
|
||||
ref x @ Expression::Mult(..) |
|
||||
ref x @ Expression::Div(..) if x.is_flattened() => x.clone(),
|
||||
Expression::Add(box left, box right) => {
|
||||
x @ NumberLiteral(_) |
|
||||
x @ VariableReference(_) => x,
|
||||
ref x @ Add(..) |
|
||||
ref x @ Sub(..) |
|
||||
ref x @ Mult(..) |
|
||||
ref x @ Div(..) if x.is_flattened() => x.clone(),
|
||||
Add(box left, box right) => {
|
||||
let left_flattened = flatten_expression(defs_flattened, num_variables, left);
|
||||
let right_flattened = flatten_expression(defs_flattened, num_variables, right);
|
||||
let new_left = if left_flattened.is_linear() {
|
||||
|
@ -134,7 +135,7 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), left_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
let new_right = if right_flattened.is_linear() {
|
||||
right_flattened
|
||||
|
@ -142,11 +143,11 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), right_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
Expression::Add(box new_left, box new_right)
|
||||
Add(box new_left, box new_right)
|
||||
},
|
||||
Expression::Sub(box left, box right) => {
|
||||
Sub(box left, box right) => {
|
||||
let left_flattened = flatten_expression(defs_flattened, num_variables, left);
|
||||
let right_flattened = flatten_expression(defs_flattened, num_variables, right);
|
||||
let new_left = if left_flattened.is_linear() {
|
||||
|
@ -155,7 +156,7 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), left_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
let new_right = if right_flattened.is_linear() {
|
||||
right_flattened
|
||||
|
@ -163,11 +164,11 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), right_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
Expression::Sub(box new_left, box new_right)
|
||||
Sub(box new_left, box new_right)
|
||||
},
|
||||
Expression::Mult(box left, box right) => {
|
||||
Mult(box left, box right) => {
|
||||
let left_flattened = flatten_expression(defs_flattened, num_variables, left);
|
||||
let right_flattened = flatten_expression(defs_flattened, num_variables, right);
|
||||
let new_left = if left_flattened.is_linear() {
|
||||
|
@ -176,7 +177,7 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), left_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
let new_right = if right_flattened.is_linear() {
|
||||
right_flattened
|
||||
|
@ -184,11 +185,11 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), right_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
Expression::Mult(box new_left, box new_right)
|
||||
Mult(box new_left, box new_right)
|
||||
},
|
||||
Expression::Div(box left, box right) => {
|
||||
Div(box left, box right) => {
|
||||
let left_flattened = flatten_expression(defs_flattened, num_variables, left);
|
||||
let right_flattened = flatten_expression(defs_flattened, num_variables, right);
|
||||
let new_left = if left_flattened.is_linear() {
|
||||
|
@ -197,7 +198,7 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), left_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
let new_right = if right_flattened.is_linear() {
|
||||
right_flattened
|
||||
|
@ -205,23 +206,23 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
let new_name = format!("sym_{}", num_variables);
|
||||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(new_name.to_string(), right_flattened));
|
||||
Expression::VariableReference(new_name)
|
||||
VariableReference(new_name)
|
||||
};
|
||||
Expression::Div(box new_left, box new_right)
|
||||
Div(box new_left, box new_right)
|
||||
},
|
||||
Expression::Pow(base, exponent) => {
|
||||
Pow(base, exponent) => {
|
||||
// TODO currently assuming that base is number or variable
|
||||
match exponent {
|
||||
box Expression::NumberLiteral(x) if x > 1 => {
|
||||
box NumberLiteral(x) if x > 1 => {
|
||||
match base {
|
||||
box Expression::VariableReference(ref var) => {
|
||||
box VariableReference(ref var) => {
|
||||
let id = if x > 2 {
|
||||
let tmp_expression = flatten_expression(
|
||||
defs_flattened,
|
||||
num_variables,
|
||||
Expression::Pow(
|
||||
box Expression::VariableReference(var.to_string()),
|
||||
box Expression::NumberLiteral(x - 1)
|
||||
Pow(
|
||||
box VariableReference(var.to_string()),
|
||||
box NumberLiteral(x - 1)
|
||||
)
|
||||
);
|
||||
let new_name = format!("sym_{}", num_variables);
|
||||
|
@ -231,14 +232,14 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
} else {
|
||||
var.to_string()
|
||||
};
|
||||
Expression::Mult(
|
||||
box Expression::VariableReference(id.to_string()),
|
||||
box Expression::VariableReference(var.to_string())
|
||||
Mult(
|
||||
box VariableReference(id.to_string()),
|
||||
box VariableReference(var.to_string())
|
||||
)
|
||||
},
|
||||
box Expression::NumberLiteral(var) => Expression::Mult(
|
||||
box Expression::NumberLiteral(var),
|
||||
box Expression::NumberLiteral(var)
|
||||
box NumberLiteral(var) => Mult(
|
||||
box NumberLiteral(var),
|
||||
box NumberLiteral(var)
|
||||
),
|
||||
_ => panic!("Only variables and numbers allowed in pow base")
|
||||
}
|
||||
|
@ -246,17 +247,17 @@ fn flatten_expression(defs_flattened: &mut Vec<Definition>, num_variables: &mut
|
|||
_ => panic!("Expected number > 1 as pow exponent"),
|
||||
}
|
||||
},
|
||||
Expression::IfElse(box condition, consequent, alternative) => {
|
||||
IfElse(box condition, consequent, alternative) => {
|
||||
let condition_true = flatten_condition(defs_flattened, num_variables, condition);
|
||||
// condition_false = 1 - condition_true
|
||||
// (condition_true * consequent) + (condition_false * alternatuve)
|
||||
flatten_expression(
|
||||
defs_flattened,
|
||||
num_variables,
|
||||
Expression::Add(
|
||||
box Expression::Mult(box condition_true.clone(), consequent),
|
||||
box Expression::Mult(
|
||||
box Expression::Sub(box Expression::NumberLiteral(1), box condition_true),
|
||||
Add(
|
||||
box Mult(box condition_true.clone(), consequent),
|
||||
box Mult(
|
||||
box Sub(box NumberLiteral(1), box condition_true),
|
||||
alternative
|
||||
)
|
||||
)
|
||||
|
@ -282,9 +283,9 @@ fn flatten_condition(defs_flattened: &mut Vec<Definition>, num_variables: &mut i
|
|||
*num_variables += 1;
|
||||
defs_flattened.push(Definition::Definition(
|
||||
cond_result.to_string(),
|
||||
Expression::Sub(
|
||||
box Expression::VariableReference(lhs_name.to_string()),
|
||||
box Expression::VariableReference(rhs_name.to_string())
|
||||
Sub(
|
||||
box VariableReference(lhs_name.to_string()),
|
||||
box VariableReference(rhs_name.to_string())
|
||||
)
|
||||
));
|
||||
let bits = 8;
|
||||
|
@ -292,18 +293,18 @@ fn flatten_condition(defs_flattened: &mut Vec<Definition>, num_variables: &mut i
|
|||
let new_name = format!("{}_b{}", &cond_result, i);
|
||||
defs_flattened.push(Definition::Definition(
|
||||
new_name.to_string(),
|
||||
Expression::Mult(
|
||||
box Expression::VariableReference(new_name.to_string()),
|
||||
box Expression::VariableReference(new_name.to_string())
|
||||
Mult(
|
||||
box VariableReference(new_name.to_string()),
|
||||
box VariableReference(new_name.to_string())
|
||||
)
|
||||
));
|
||||
}
|
||||
let mut expr = Expression::VariableReference(format!("{}_b0", &cond_result)); // * 2^0
|
||||
let mut expr = VariableReference(format!("{}_b0", &cond_result)); // * 2^0
|
||||
for i in 1..bits {
|
||||
expr = Expression::Add(
|
||||
box Expression::Mult(
|
||||
box Expression::VariableReference(format!("{}_b{}", &cond_result, i)),
|
||||
box Expression::NumberLiteral(2i32.pow(i))
|
||||
expr = Add(
|
||||
box Mult(
|
||||
box VariableReference(format!("{}_b{}", &cond_result, i)),
|
||||
box NumberLiteral(2i32.pow(i))
|
||||
),
|
||||
box expr
|
||||
);
|
||||
|
@ -311,7 +312,7 @@ fn flatten_condition(defs_flattened: &mut Vec<Definition>, num_variables: &mut i
|
|||
defs_flattened.push(Definition::Definition(cond_result.to_string(), expr));
|
||||
|
||||
let cond_true = format!("{}_b{}", &cond_result, bits - 1);
|
||||
Expression::VariableReference(cond_true)
|
||||
VariableReference(cond_true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
116
src/r1cs.rs
116
src/r1cs.rs
|
@ -1,17 +1,20 @@
|
|||
use ast::*;
|
||||
use ast::Expression::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn count_variables_add(expr: Expression) -> HashMap<String, i32> {
|
||||
let mut count = HashMap::new();
|
||||
match expr {
|
||||
Expression::Add(box lhs, box rhs) => {
|
||||
NumberLiteral(x) => { count.insert("~one".to_string(), x); },
|
||||
VariableReference(var) => { count.insert(var, 1); },
|
||||
Add(box lhs, box rhs) => {
|
||||
match (lhs, rhs) {
|
||||
(Expression::NumberLiteral(x), Expression::NumberLiteral(y)) => {
|
||||
(NumberLiteral(x), NumberLiteral(y)) => {
|
||||
let num = count.entry("~one".to_string()).or_insert(0);
|
||||
*num += x + y;
|
||||
},
|
||||
(Expression::VariableReference(v), Expression::NumberLiteral(x)) |
|
||||
(Expression::NumberLiteral(x), Expression::VariableReference(v)) => {
|
||||
(VariableReference(v), NumberLiteral(x)) |
|
||||
(NumberLiteral(x), VariableReference(v)) => {
|
||||
{
|
||||
let num = count.entry("~one".to_string()).or_insert(0);
|
||||
*num += x;
|
||||
|
@ -19,7 +22,7 @@ fn count_variables_add(expr: Expression) -> HashMap<String, i32> {
|
|||
let var = count.entry(v).or_insert(0);
|
||||
*var += 1;
|
||||
},
|
||||
(Expression::VariableReference(v1), Expression::VariableReference(v2)) => {
|
||||
(VariableReference(v1), VariableReference(v2)) => {
|
||||
{
|
||||
let var1 = count.entry(v1).or_insert(0);
|
||||
*var1 += 1;
|
||||
|
@ -27,8 +30,8 @@ fn count_variables_add(expr: Expression) -> HashMap<String, i32> {
|
|||
let var2 = count.entry(v2).or_insert(0);
|
||||
*var2 += 1;
|
||||
},
|
||||
(Expression::NumberLiteral(x), e @ Expression::Add(..)) |
|
||||
(e @ Expression::Add(..), Expression::NumberLiteral(x)) => {
|
||||
(NumberLiteral(x), e @ Add(..)) |
|
||||
(e @ Add(..), NumberLiteral(x)) => {
|
||||
{
|
||||
let num = count.entry("~one".to_string()).or_insert(0);
|
||||
*num += x;
|
||||
|
@ -39,8 +42,8 @@ fn count_variables_add(expr: Expression) -> HashMap<String, i32> {
|
|||
*val += *value;
|
||||
}
|
||||
},
|
||||
(Expression::VariableReference(v), e @ Expression::Add(..)) |
|
||||
(e @ Expression::Add(..), Expression::VariableReference(v)) => {
|
||||
(VariableReference(v), e @ Add(..)) |
|
||||
(e @ Add(..), VariableReference(v)) => {
|
||||
{
|
||||
let var = count.entry(v).or_insert(0);
|
||||
*var += 1;
|
||||
|
@ -51,10 +54,10 @@ fn count_variables_add(expr: Expression) -> HashMap<String, i32> {
|
|||
*val += *value;
|
||||
}
|
||||
},
|
||||
(Expression::NumberLiteral(x), Expression::Mult(box Expression::NumberLiteral(n), box Expression::VariableReference(v))) |
|
||||
(Expression::NumberLiteral(x), Expression::Mult(box Expression::VariableReference(v), box Expression::NumberLiteral(n))) |
|
||||
(Expression::Mult(box Expression::NumberLiteral(n), box Expression::VariableReference(v)), Expression::NumberLiteral(x)) |
|
||||
(Expression::Mult(box Expression::VariableReference(v), box Expression::NumberLiteral(n)), Expression::NumberLiteral(x)) => {
|
||||
(NumberLiteral(x), Mult(box NumberLiteral(n), box VariableReference(v))) |
|
||||
(NumberLiteral(x), Mult(box VariableReference(v), box NumberLiteral(n))) |
|
||||
(Mult(box NumberLiteral(n), box VariableReference(v)), NumberLiteral(x)) |
|
||||
(Mult(box VariableReference(v), box NumberLiteral(n)), NumberLiteral(x)) => {
|
||||
{
|
||||
let num = count.entry("~one".to_string()).or_insert(0);
|
||||
*num += x;
|
||||
|
@ -70,78 +73,79 @@ fn count_variables_add(expr: Expression) -> HashMap<String, i32> {
|
|||
count
|
||||
}
|
||||
|
||||
// lhs = rhy
|
||||
fn swap_sub(lhs: &Expression, rhs: &Expression) -> (Expression, Expression) {
|
||||
match (lhs.clone(), rhs.clone()) {
|
||||
// TODO need all cases? need more?
|
||||
(v1 @ NumberLiteral(_), v2 @ NumberLiteral(_)) |
|
||||
(v1 @ VariableReference(_), v2 @ NumberLiteral(_)) |
|
||||
(v1 @ NumberLiteral(_), v2 @ VariableReference(_)) |
|
||||
(v1 @ VariableReference(_), v2 @ VariableReference(_)) => (v1, v2),
|
||||
(var @ VariableReference(_), Add(left, box right)) => {
|
||||
let (l, r) = swap_sub(&var, &right);
|
||||
(l, Add(left, box r))
|
||||
},
|
||||
(var @ VariableReference(_), Sub(box left, box right)) => {
|
||||
let (l, r) = swap_sub(&left, &right);
|
||||
(Add(box var, box r), l)
|
||||
}
|
||||
e @ _ => panic!("Unexpected input: {} = {}", e.0, e.1),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn r1cs_expression(idx: usize, expr: Expression, variables: &mut Vec<String>, a_row: &mut Vec<(usize, i32)>, b_row: &mut Vec<(usize, i32)>, c_row: &mut Vec<(usize, i32)>) {
|
||||
match expr {
|
||||
e @ Expression::Add(..) => {
|
||||
for (key, value) in count_variables_add(e) {
|
||||
e @ Add(..) |
|
||||
e @ Sub(..) => { // a - b = c --> b + c = a
|
||||
let (lhs, rhs) = swap_sub(&VariableReference(variables[idx].to_string()), &e);
|
||||
for (key, value) in count_variables_add(rhs) {
|
||||
a_row.push((variables.iter().position(|r| r == &key).unwrap(), value));
|
||||
}
|
||||
b_row.push((0, 1));
|
||||
c_row.push((idx, 1));
|
||||
},
|
||||
Expression::Sub(lhs, rhs) => { // a - b = c --> b + c = a
|
||||
for (key, value) in count_variables_add(Expression::Add(rhs, box Expression::VariableReference(variables[idx].to_string()))) {
|
||||
a_row.push((variables.iter().position(|r| r == &key).unwrap(), value));
|
||||
for (key, value) in count_variables_add(lhs) {
|
||||
c_row.push((variables.iter().position(|r| r == &key).unwrap(), value));
|
||||
}
|
||||
b_row.push((0, 1));
|
||||
match lhs {
|
||||
box Expression::NumberLiteral(x) => c_row.push((0, x)),
|
||||
box Expression::VariableReference(x) => c_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
e @ _ => panic!("unimplemented: {}", e),
|
||||
};
|
||||
|
||||
// a_row.push((idx, 1));
|
||||
// match lhs {
|
||||
// box Expression::NumberLiteral(x) => c_row.push((0, x)),
|
||||
// box Expression::VariableReference(x) => c_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
// _ => panic!("Not flattened!"),
|
||||
// };
|
||||
// match rhs {
|
||||
// box Expression::NumberLiteral(x) => b_row.push((0, x)),
|
||||
// box Expression::VariableReference(x) => b_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
// _ => panic!("Not flattened!"),
|
||||
// };
|
||||
},
|
||||
Expression::Mult(lhs, rhs) => {
|
||||
Mult(lhs, rhs) => {
|
||||
c_row.push((idx, 1));
|
||||
match lhs {
|
||||
box Expression::NumberLiteral(x) => a_row.push((0, x)),
|
||||
box Expression::VariableReference(x) => a_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
box e @ Expression::Add(..) => for (key, value) in count_variables_add(e) {
|
||||
box NumberLiteral(x) => a_row.push((0, x)),
|
||||
box VariableReference(x) => a_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
box e @ Add(..) => for (key, value) in count_variables_add(e) {
|
||||
a_row.push((variables.iter().position(|r| r == &key).unwrap(), value));
|
||||
},
|
||||
e @ _ => panic!("Not flattened: {}", e),
|
||||
};
|
||||
match rhs {
|
||||
box Expression::NumberLiteral(x) => b_row.push((0, x)),
|
||||
box Expression::VariableReference(x) => b_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
box e @ Expression::Add(..) => for (key, value) in count_variables_add(e) {
|
||||
box NumberLiteral(x) => b_row.push((0, x)),
|
||||
box VariableReference(x) => b_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
box e @ Add(..) => for (key, value) in count_variables_add(e) {
|
||||
b_row.push((variables.iter().position(|r| r == &key).unwrap(), value));
|
||||
},
|
||||
e @ _ => panic!("Not flattened: {}", e),
|
||||
};
|
||||
},
|
||||
Expression::Div(lhs, rhs) => { // a / b = c --> c * b = a
|
||||
Div(lhs, rhs) => { // a / b = c --> c * b = a
|
||||
a_row.push((idx, 1));
|
||||
match lhs {
|
||||
box Expression::NumberLiteral(x) => c_row.push((0, x)),
|
||||
box Expression::VariableReference(x) => c_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
_ => panic!("Not flattened!"),
|
||||
box NumberLiteral(x) => c_row.push((0, x)),
|
||||
box VariableReference(x) => c_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
match rhs {
|
||||
box Expression::NumberLiteral(x) => b_row.push((0, x)),
|
||||
box Expression::VariableReference(x) => b_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
_ => panic!("Not flattened!"),
|
||||
box NumberLiteral(x) => b_row.push((0, x)),
|
||||
box VariableReference(x) => b_row.push((variables.iter().position(|r| r == &x).unwrap(), 1)),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
},
|
||||
Expression::Pow(_, _) => panic!("Pow not flattened"),
|
||||
Expression::IfElse(_, _, _) => panic!("IfElse not flattened"),
|
||||
Expression::VariableReference(var) => {
|
||||
Pow(_, _) => panic!("Pow not flattened"),
|
||||
IfElse(_, _, _) => panic!("IfElse not flattened"),
|
||||
VariableReference(var) => {
|
||||
a_row.push((variables.iter().position(|r| r == &var).unwrap(), 1));
|
||||
b_row.push((0, 1));
|
||||
c_row.push((idx, 1));
|
||||
},
|
||||
Expression::NumberLiteral(x) => {
|
||||
NumberLiteral(x) => {
|
||||
a_row.push((0, x));
|
||||
b_row.push((0, 1));
|
||||
c_row.push((idx, 1));
|
||||
|
|
Loading…
Reference in a new issue