remove xor, remove field dep, clean
This commit is contained in:
parent
9ad0040dec
commit
5b4da4c91c
6 changed files with 84 additions and 190 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1246,7 +1246,6 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bellman 0.2.0 (git+https://github.com/matterinc/bellman?tag=0.2.0)",
|
"bellman 0.2.0 (git+https://github.com/matterinc/bellman?tag=0.2.0)",
|
||||||
"sapling-crypto 0.0.4 (git+https://github.com/matterinc/sapling-crypto?tag=0.0.4)",
|
"sapling-crypto 0.0.4 (git+https://github.com/matterinc/sapling-crypto?tag=0.0.4)",
|
||||||
"zokrates_field 0.3.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -57,8 +57,13 @@ impl<T: Field> Executable<T> for RustHelper {
|
||||||
RustHelper::Sha256Round => {
|
RustHelper::Sha256Round => {
|
||||||
let i = &inputs[0..512];
|
let i = &inputs[0..512];
|
||||||
let h = &inputs[512..];
|
let h = &inputs[512..];
|
||||||
|
let i: Vec<_> = i.iter().map(|x| x.clone().into_bellman()).collect();
|
||||||
|
let h: Vec<_> = h.iter().map(|x| x.clone().into_bellman()).collect();
|
||||||
assert!(h.len() == 256);
|
assert!(h.len() == 256);
|
||||||
Ok(generate_sha256_round_witness(i, h))
|
Ok(generate_sha256_round_witness::<T::BellmanEngine>(&i, &h)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| T::from_bellman(x))
|
||||||
|
.collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ impl Importer {
|
||||||
for import in destination.imports.iter() {
|
for import in destination.imports.iter() {
|
||||||
let pos = import.pos();
|
let pos = import.pos();
|
||||||
let import = &import.value;
|
let import = &import.value;
|
||||||
// handle the case of special libsnark and packing imports
|
// handle the case of special bellman and packing imports
|
||||||
if import.source.starts_with("BELLMAN") {
|
if import.source.starts_with("BELLMAN") {
|
||||||
match import.source.as_ref() {
|
match import.source.as_ref() {
|
||||||
"BELLMAN/sha256round" => {
|
"BELLMAN/sha256round" => {
|
||||||
|
|
|
@ -3,16 +3,17 @@ use flat_absy::{FlatParameter, FlatVariable};
|
||||||
use helpers::{DirectiveStatement, Helper, RustHelper};
|
use helpers::{DirectiveStatement, Helper, RustHelper};
|
||||||
use reduce::Reduce;
|
use reduce::Reduce;
|
||||||
use types::{Signature, Type};
|
use types::{Signature, Type};
|
||||||
|
use zokrates_embed::{generate_sha256_round_constraints, BellmanConstraint};
|
||||||
use zokrates_field::field::Field;
|
use zokrates_field::field::Field;
|
||||||
|
|
||||||
impl<T: Field> From<zokrates_embed::Constraint<T>> for FlatStatement<T> {
|
impl<T: Field> From<BellmanConstraint<T::BellmanEngine>> for FlatStatement<T> {
|
||||||
fn from(c: zokrates_embed::Constraint<T>) -> FlatStatement<T> {
|
fn from(c: zokrates_embed::BellmanConstraint<T::BellmanEngine>) -> FlatStatement<T> {
|
||||||
let rhs_a = match c
|
let rhs_a = match c
|
||||||
.a
|
.a
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(key, val)| {
|
.map(|(key, val)| {
|
||||||
FlatExpression::Mult(
|
FlatExpression::Mult(
|
||||||
box FlatExpression::Number(val),
|
box FlatExpression::Number(T::from_bellman(val)),
|
||||||
box FlatExpression::Identifier(FlatVariable::new(key)),
|
box FlatExpression::Identifier(FlatVariable::new(key)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -30,7 +31,7 @@ impl<T: Field> From<zokrates_embed::Constraint<T>> for FlatStatement<T> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(key, val)| {
|
.map(|(key, val)| {
|
||||||
FlatExpression::Mult(
|
FlatExpression::Mult(
|
||||||
box FlatExpression::Number(val),
|
box FlatExpression::Number(T::from_bellman(val)),
|
||||||
box FlatExpression::Identifier(FlatVariable::new(key)),
|
box FlatExpression::Identifier(FlatVariable::new(key)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -48,7 +49,7 @@ impl<T: Field> From<zokrates_embed::Constraint<T>> for FlatStatement<T> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(key, val)| {
|
.map(|(key, val)| {
|
||||||
FlatExpression::Mult(
|
FlatExpression::Mult(
|
||||||
box FlatExpression::Number(val),
|
box FlatExpression::Number(T::from_bellman(val)),
|
||||||
box FlatExpression::Identifier(FlatVariable::new(key)),
|
box FlatExpression::Identifier(FlatVariable::new(key)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -66,7 +67,8 @@ impl<T: Field> From<zokrates_embed::Constraint<T>> for FlatStatement<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sha_round<T: Field>() -> FlatFunction<T> {
|
pub fn sha_round<T: Field>() -> FlatFunction<T> {
|
||||||
let (r1cs, input, current_hash, output) = zokrates_embed::generate_sha256_round_constraints();
|
let (r1cs, input, current_hash, output) =
|
||||||
|
generate_sha256_round_constraints::<T::BellmanEngine>();
|
||||||
|
|
||||||
let variable_count = r1cs.aux_count + 1; // auxiliary and ONE
|
let variable_count = r1cs.aux_count + 1; // auxiliary and ONE
|
||||||
|
|
||||||
|
@ -219,13 +221,6 @@ mod tests {
|
||||||
private: vec![true; 768],
|
private: vec![true; 768],
|
||||||
};
|
};
|
||||||
|
|
||||||
//use rand::Rng;
|
|
||||||
|
|
||||||
// let mut rng = rand::thread_rng();
|
|
||||||
// let input: Vec<_> = (0..768).map(|_| {
|
|
||||||
// rng.gen_range(0, 2)
|
|
||||||
// }).collect();
|
|
||||||
|
|
||||||
let input = (0..512).map(|_| 0).chain((0..256).map(|_| 1)).collect();
|
let input = (0..512).map(|_| 0).chain((0..256).map(|_| 1)).collect();
|
||||||
|
|
||||||
prog.execute(&input).unwrap();
|
prog.execute(&input).unwrap();
|
||||||
|
|
|
@ -6,5 +6,4 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sapling-crypto = { git = 'https://github.com/matterinc/sapling-crypto', tag = "0.0.4" }
|
sapling-crypto = { git = 'https://github.com/matterinc/sapling-crypto', tag = "0.0.4" }
|
||||||
bellman = { git = 'https://github.com/matterinc/bellman', tag = "0.2.0" }
|
bellman = { git = 'https://github.com/matterinc/bellman', tag = "0.2.0" }
|
||||||
zokrates_field = { path = "../zokrates_field" }
|
|
|
@ -1,15 +1,15 @@
|
||||||
|
use bellman::pairing::ff::Field;
|
||||||
use bellman::pairing::Engine;
|
use bellman::pairing::Engine;
|
||||||
use bellman::ConstraintSystem;
|
use bellman::ConstraintSystem;
|
||||||
use bellman::{Index, LinearCombination, SynthesisError, Variable};
|
use bellman::{Index, LinearCombination, SynthesisError, Variable};
|
||||||
use sapling_crypto::circuit::boolean::{AllocatedBit, Boolean};
|
use sapling_crypto::circuit::boolean::{AllocatedBit, Boolean};
|
||||||
use sapling_crypto::circuit::sha256::sha256_compression_function;
|
use sapling_crypto::circuit::sha256::sha256_compression_function;
|
||||||
use sapling_crypto::circuit::uint32::UInt32;
|
use sapling_crypto::circuit::uint32::UInt32;
|
||||||
use zokrates_field::field::Field;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BellmanR1CS<E: Engine> {
|
pub struct BellmanR1CS<E: Engine> {
|
||||||
aux_count: usize,
|
pub aux_count: usize,
|
||||||
constraints: Vec<BellmanConstraint<E>>,
|
pub constraints: Vec<BellmanConstraint<E>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> BellmanR1CS<E> {
|
impl<E: Engine> BellmanR1CS<E> {
|
||||||
|
@ -22,40 +22,29 @@ impl<E: Engine> BellmanR1CS<E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BellmanWitness<E: Engine> {
|
pub struct BellmanWitness<E: Engine> {
|
||||||
pub values: Vec<E::Fr>,
|
pub values: Vec<E::Fr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct BellmanConstraint<E: Engine> {
|
pub struct BellmanConstraint<E: Engine> {
|
||||||
pub a: Vec<(usize, E::Fr)>,
|
pub a: Vec<(usize, E::Fr)>,
|
||||||
pub b: Vec<(usize, E::Fr)>,
|
pub b: Vec<(usize, E::Fr)>,
|
||||||
pub c: Vec<(usize, E::Fr)>,
|
pub c: Vec<(usize, E::Fr)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
fn sha256_round<E: Engine, CS: ConstraintSystem<E>>(
|
||||||
pub struct Constraint<T: Field> {
|
|
||||||
pub a: Vec<(usize, T)>,
|
|
||||||
pub b: Vec<(usize, T)>,
|
|
||||||
pub c: Vec<(usize, T)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct R1CS<T: Field> {
|
|
||||||
pub aux_count: usize,
|
|
||||||
pub constraints: Vec<Constraint<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sha256_round<T: Field, CS: ConstraintSystem<T::BellmanEngine>>(
|
|
||||||
mut cs: CS,
|
mut cs: CS,
|
||||||
input: Option<&Vec<T>>,
|
input: &Vec<Option<E::Fr>>,
|
||||||
current_hash: Option<&Vec<T>>,
|
current_hash: &Vec<Option<E::Fr>>,
|
||||||
) -> Result<(Vec<usize>, Vec<usize>, Vec<usize>), SynthesisError> {
|
) -> Result<(Vec<usize>, Vec<usize>, Vec<usize>), SynthesisError> {
|
||||||
let input_bits = (0..512)
|
let input_bits = input
|
||||||
.map(|i| {
|
.iter()
|
||||||
AllocatedBit::alloc::<T::BellmanEngine, _>(
|
.enumerate()
|
||||||
&mut cs.namespace(|| format!("input_{}", i)),
|
.map(|(index, i)| {
|
||||||
Some(input.as_ref().unwrap()[i] == T::from(1)),
|
AllocatedBit::alloc::<E, _>(
|
||||||
|
&mut cs.namespace(|| format!("input_{}", index)),
|
||||||
|
Some(*i == Some(<E::Fr as Field>::one())),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
|
@ -66,11 +55,13 @@ fn sha256_round<T: Field, CS: ConstraintSystem<T::BellmanEngine>>(
|
||||||
.map(|i| Boolean::Is(i.clone()))
|
.map(|i| Boolean::Is(i.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let current_hash_bits = (0..256)
|
let current_hash_bits = current_hash
|
||||||
.map(|i| {
|
.iter()
|
||||||
AllocatedBit::alloc::<T::BellmanEngine, _>(
|
.enumerate()
|
||||||
&mut cs.namespace(|| format!("current_hash_{}", i)),
|
.map(|(index, i)| {
|
||||||
Some(current_hash.as_ref().unwrap()[i] == T::from(1)),
|
AllocatedBit::alloc::<E, _>(
|
||||||
|
&mut cs.namespace(|| format!("current_hash_{}", index)),
|
||||||
|
Some(*i == Some(<E::Fr as Field>::one())),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
|
@ -88,8 +79,7 @@ fn sha256_round<T: Field, CS: ConstraintSystem<T::BellmanEngine>>(
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let res =
|
let res = sha256_compression_function::<E, _>(&mut cs, &input, ¤t_hash).unwrap();
|
||||||
sha256_compression_function::<T::BellmanEngine, _>(&mut cs, &input, ¤t_hash).unwrap();
|
|
||||||
|
|
||||||
let output_bits = res
|
let output_bits = res
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -100,59 +90,23 @@ fn sha256_round<T: Field, CS: ConstraintSystem<T::BellmanEngine>>(
|
||||||
Ok((
|
Ok((
|
||||||
input_bits
|
input_bits
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|b| BellmanR1CS::<T::BellmanEngine>::var_to_index(b.get_variable()))
|
.map(|b| var_to_index(b.get_variable()))
|
||||||
.collect(),
|
.collect(),
|
||||||
current_hash_bits
|
current_hash_bits
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|b| BellmanR1CS::<T::BellmanEngine>::var_to_index(b.get_variable()))
|
.map(|b| var_to_index(b.get_variable()))
|
||||||
.collect(),
|
.collect(),
|
||||||
output_bits
|
output_bits
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|b| BellmanR1CS::<T::BellmanEngine>::var_to_index(b.get_variable()))
|
.map(|b| var_to_index(b.get_variable()))
|
||||||
.collect(),
|
.collect(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Field> R1CS<T> {
|
|
||||||
fn from_bellman(cs: BellmanR1CS<T::BellmanEngine>) -> Self {
|
|
||||||
R1CS {
|
|
||||||
aux_count: cs.aux_count,
|
|
||||||
constraints: cs
|
|
||||||
.constraints
|
|
||||||
.into_iter()
|
|
||||||
.map(|c| Constraint::from_bellman(c))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Field> Constraint<T> {
|
|
||||||
fn from_bellman(cs: BellmanConstraint<T::BellmanEngine>) -> Self {
|
|
||||||
let res = Constraint {
|
|
||||||
a: cs
|
|
||||||
.a
|
|
||||||
.into_iter()
|
|
||||||
.map(|(variable, coefficient)| (variable, T::from_bellman(coefficient)))
|
|
||||||
.collect(),
|
|
||||||
b: cs
|
|
||||||
.b
|
|
||||||
.into_iter()
|
|
||||||
.map(|(variable, coefficient)| (variable, T::from_bellman(coefficient)))
|
|
||||||
.collect(),
|
|
||||||
c: cs
|
|
||||||
.c
|
|
||||||
.into_iter()
|
|
||||||
.map(|(variable, coefficient)| (variable, T::from_bellman(coefficient)))
|
|
||||||
.collect(),
|
|
||||||
};
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
|
impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
|
||||||
type Root = Self;
|
type Root = Self;
|
||||||
|
|
||||||
fn alloc<F, A, AR>(&mut self, _annotation: A, f: F) -> Result<Variable, SynthesisError>
|
fn alloc<F, A, AR>(&mut self, _: A, f: F) -> Result<Variable, SynthesisError>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||||
A: FnOnce() -> AR,
|
A: FnOnce() -> AR,
|
||||||
|
@ -165,7 +119,7 @@ impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
|
||||||
Ok(var)
|
Ok(var)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_input<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
|
fn alloc_input<F, A, AR>(&mut self, _: A, _: F) -> Result<Variable, SynthesisError>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||||
A: FnOnce() -> AR,
|
A: FnOnce() -> AR,
|
||||||
|
@ -174,7 +128,7 @@ impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
|
||||||
unreachable!("Bellman helpers are not allowed to allocate public variables")
|
unreachable!("Bellman helpers are not allowed to allocate public variables")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enforce<A, AR, LA, LB, LC>(&mut self, _annotation: A, _a: LA, _b: LB, _c: LC)
|
fn enforce<A, AR, LA, LB, LC>(&mut self, _: A, _: LA, _: LB, _: LC)
|
||||||
where
|
where
|
||||||
A: FnOnce() -> AR,
|
A: FnOnce() -> AR,
|
||||||
AR: Into<String>,
|
AR: Into<String>,
|
||||||
|
@ -185,7 +139,7 @@ impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_namespace<NR, N>(&mut self, _name_fn: N)
|
fn push_namespace<NR, N>(&mut self, _: N)
|
||||||
where
|
where
|
||||||
NR: Into<String>,
|
NR: Into<String>,
|
||||||
N: FnOnce() -> NR,
|
N: FnOnce() -> NR,
|
||||||
|
@ -205,7 +159,7 @@ impl<E: Engine> ConstraintSystem<E> for BellmanWitness<E> {
|
||||||
impl<E: Engine> ConstraintSystem<E> for BellmanR1CS<E> {
|
impl<E: Engine> ConstraintSystem<E> for BellmanR1CS<E> {
|
||||||
type Root = Self;
|
type Root = Self;
|
||||||
|
|
||||||
fn alloc<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
|
fn alloc<F, A, AR>(&mut self, _: A, _: F) -> Result<Variable, SynthesisError>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||||
A: FnOnce() -> AR,
|
A: FnOnce() -> AR,
|
||||||
|
@ -218,7 +172,7 @@ impl<E: Engine> ConstraintSystem<E> for BellmanR1CS<E> {
|
||||||
Ok(var)
|
Ok(var)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_input<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
|
fn alloc_input<F, A, AR>(&mut self, _: A, _: F) -> Result<Variable, SynthesisError>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
F: FnOnce() -> Result<E::Fr, SynthesisError>,
|
||||||
A: FnOnce() -> AR,
|
A: FnOnce() -> AR,
|
||||||
|
@ -227,7 +181,7 @@ impl<E: Engine> ConstraintSystem<E> for BellmanR1CS<E> {
|
||||||
unreachable!("Bellman helpers are not allowed to allocate public variables")
|
unreachable!("Bellman helpers are not allowed to allocate public variables")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enforce<A, AR, LA, LB, LC>(&mut self, _annotation: A, a: LA, b: LB, c: LC)
|
fn enforce<A, AR, LA, LB, LC>(&mut self, _: A, a: LA, b: LB, c: LC)
|
||||||
where
|
where
|
||||||
A: FnOnce() -> AR,
|
A: FnOnce() -> AR,
|
||||||
AR: Into<String>,
|
AR: Into<String>,
|
||||||
|
@ -242,29 +196,23 @@ impl<E: Engine> ConstraintSystem<E> for BellmanR1CS<E> {
|
||||||
let a = a
|
let a = a
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(variable, coefficient)| {
|
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
|
||||||
(BellmanR1CS::<E>::var_to_index(*variable), *coefficient)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
let b = b
|
let b = b
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(variable, coefficient)| {
|
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
|
||||||
(BellmanR1CS::<E>::var_to_index(*variable), *coefficient)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
let c = c
|
let c = c
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(variable, coefficient)| {
|
.map(|(variable, coefficient)| (var_to_index(*variable), *coefficient))
|
||||||
(BellmanR1CS::<E>::var_to_index(*variable), *coefficient)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
self.constraints.push(BellmanConstraint { a, b, c });
|
self.constraints.push(BellmanConstraint { a, b, c });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_namespace<NR, N>(&mut self, _name_fn: N)
|
fn push_namespace<NR, N>(&mut self, _: N)
|
||||||
where
|
where
|
||||||
NR: Into<String>,
|
NR: Into<String>,
|
||||||
N: FnOnce() -> NR,
|
N: FnOnce() -> NR,
|
||||||
|
@ -281,83 +229,55 @@ impl<E: Engine> ConstraintSystem<E> for BellmanR1CS<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_xor_constraints<T: Field>() -> (R1CS<T>, usize) {
|
pub fn generate_sha256_round_constraints<E: Engine>(
|
||||||
|
) -> (BellmanR1CS<E>, Vec<usize>, Vec<usize>, Vec<usize>) {
|
||||||
let mut cs = BellmanR1CS::new();
|
let mut cs = BellmanR1CS::new();
|
||||||
|
|
||||||
let i0 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, None).unwrap());
|
let (input_bits, current_hash_bits, output_bits) =
|
||||||
let i1 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, None).unwrap());
|
sha256_round(&mut cs, &vec![None; 512], &vec![None; 256]).unwrap();
|
||||||
|
|
||||||
let res = Boolean::xor(&mut cs, &i0, &i1).unwrap();
|
|
||||||
let res =
|
|
||||||
BellmanR1CS::<T::BellmanEngine>::var_to_index(res.get_variable().unwrap().get_variable());
|
|
||||||
|
|
||||||
let cs = R1CS::from_bellman(cs);
|
|
||||||
|
|
||||||
(cs, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_xor_witness<T: Field>(i1: bool, i2: bool) -> Vec<T> {
|
|
||||||
let mut cs = BellmanWitness {
|
|
||||||
values: vec![T::from(1).into_bellman()],
|
|
||||||
};
|
|
||||||
|
|
||||||
let i0 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, Some(i1)).unwrap());
|
|
||||||
let i1 = Boolean::Is(AllocatedBit::alloc::<T::BellmanEngine, _>(&mut cs, Some(i2)).unwrap());
|
|
||||||
|
|
||||||
Boolean::xor(&mut cs, &i0, &i1).unwrap();
|
|
||||||
|
|
||||||
cs.values.into_iter().map(|v| T::from_bellman(v)).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_sha256_round_constraints<T: Field>() -> (R1CS<T>, Vec<usize>, Vec<usize>, Vec<usize>)
|
|
||||||
{
|
|
||||||
let mut cs = BellmanR1CS::new();
|
|
||||||
|
|
||||||
let (input_bits, current_hash_bits, output_bits) = sha256_round::<T, _>(
|
|
||||||
&mut cs,
|
|
||||||
Some(&vec![T::from(0); 512]),
|
|
||||||
Some(&vec![T::from(0); 256]),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// res is now the allocated bits for input, current_hash and sha256_output
|
// res is now the allocated bits for input, current_hash and sha256_output
|
||||||
|
|
||||||
let cs = R1CS::<T>::from_bellman(cs);
|
|
||||||
|
|
||||||
(cs, input_bits, current_hash_bits, output_bits)
|
(cs, input_bits, current_hash_bits, output_bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_sha256_round_witness<T: Field>(input: &[T], current_hash: &[T]) -> Vec<T> {
|
pub fn generate_sha256_round_witness<E: Engine>(
|
||||||
|
input: &[E::Fr],
|
||||||
|
current_hash: &[E::Fr],
|
||||||
|
) -> Vec<E::Fr> {
|
||||||
assert_eq!(input.len(), 512);
|
assert_eq!(input.len(), 512);
|
||||||
assert_eq!(current_hash.len(), 256);
|
assert_eq!(current_hash.len(), 256);
|
||||||
|
|
||||||
let mut cs = BellmanWitness {
|
let mut cs: BellmanWitness<E> = BellmanWitness {
|
||||||
values: vec![T::from(1).into_bellman()],
|
values: vec![<E::Fr as Field>::one()],
|
||||||
};
|
};
|
||||||
|
|
||||||
sha256_round(&mut cs, Some(&input.to_vec()), Some(¤t_hash.to_vec())).unwrap();
|
sha256_round(
|
||||||
|
&mut cs,
|
||||||
|
&input.iter().map(|x| Some(x.clone())).collect(),
|
||||||
|
¤t_hash.iter().map(|x| Some(x.clone())).collect(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
cs.values.into_iter().map(|v| T::from_bellman(v)).collect()
|
cs.values
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> BellmanR1CS<E> {
|
fn var_to_index(v: Variable) -> usize {
|
||||||
fn var_to_index(v: Variable) -> usize {
|
match v.get_unchecked() {
|
||||||
match v.get_unchecked() {
|
Index::Aux(i) => i + 1,
|
||||||
Index::Aux(i) => i + 1,
|
Index::Input(0) => 0,
|
||||||
Index::Input(0) => 0,
|
_ => unreachable!(),
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use zokrates_field::field::FieldPrime;
|
use bellman::pairing::bn256::{Bn256, Fr};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_constraints() {
|
fn generate_constraints() {
|
||||||
let (_c, input, current_hash, output) = generate_sha256_round_constraints::<FieldPrime>();
|
let (_c, input, current_hash, output) = generate_sha256_round_constraints::<Bn256>();
|
||||||
assert_eq!(input.len(), 512);
|
assert_eq!(input.len(), 512);
|
||||||
assert_eq!(current_hash.len(), 256);
|
assert_eq!(current_hash.len(), 256);
|
||||||
assert_eq!(output.len(), 256);
|
assert_eq!(output.len(), 256);
|
||||||
|
@ -365,45 +285,21 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_witness() {
|
fn generate_witness() {
|
||||||
let witness = generate_sha256_round_witness(
|
let witness =
|
||||||
&vec![FieldPrime::from(0); 512],
|
generate_sha256_round_witness::<Bn256>(&vec![Fr::one(); 512], &vec![Fr::zero(); 256]);
|
||||||
&vec![FieldPrime::from(0); 256],
|
|
||||||
);
|
|
||||||
assert_eq!(witness.len(), 26935);
|
assert_eq!(witness.len(), 26935);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn xor() {
|
|
||||||
let (_, indice) = generate_xor_constraints::<FieldPrime>();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
FieldPrime::from(0),
|
|
||||||
generate_xor_witness::<FieldPrime>(true, true)[indice]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
FieldPrime::from(1),
|
|
||||||
generate_xor_witness::<FieldPrime>(true, false)[indice]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
FieldPrime::from(1),
|
|
||||||
generate_xor_witness::<FieldPrime>(false, true)[indice]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
FieldPrime::from(0),
|
|
||||||
generate_xor_witness::<FieldPrime>(false, false)[indice]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cs() {
|
fn test_cs() {
|
||||||
use sapling_crypto::circuit::test::TestConstraintSystem;
|
use sapling_crypto::circuit::test::TestConstraintSystem;
|
||||||
|
|
||||||
let mut cs = TestConstraintSystem::new();
|
let mut cs: TestConstraintSystem<Bn256> = TestConstraintSystem::new();
|
||||||
|
|
||||||
let _ = sha256_round::<FieldPrime, _>(
|
let _ = sha256_round(
|
||||||
&mut cs,
|
&mut cs,
|
||||||
Some(&vec![FieldPrime::from(0); 512]),
|
&vec![Some(Fr::zero()); 512],
|
||||||
Some(&vec![FieldPrime::from(1); 256]),
|
&vec![Some(Fr::one()); 256],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue