1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00
This commit is contained in:
dark64 2021-06-07 13:13:21 +02:00
parent af7097bd14
commit 59f62d2ffa
9 changed files with 386 additions and 242 deletions

1
Cargo.lock generated
View file

@ -2409,6 +2409,7 @@ dependencies = [
"ark-std",
"bellman_ce",
"sapling-crypto_ce",
"zokrates_field",
]
[[package]]

View file

@ -7,17 +7,16 @@ use crate::typed_absy::types::{
ConcreteGenericsAssignment, Constant, DeclarationSignature, DeclarationType, GenericIdentifier,
};
use ark_bls12_377::Bls12_377;
use ark_bw6_761::BW6_761;
use std::collections::HashMap;
use zokrates_embed::ark::generate_verify_constraints;
use zokrates_embed::ark::{from_ark, generate_verify_constraints};
use zokrates_embed::bellman::from_bellman;
use zokrates_embed::Constraint;
use zokrates_field::{Bn128Field, Field};
cfg_if::cfg_if! {
if #[cfg(feature = "bellman")] {
use pairing_ce::bn256::Bn256;
use pairing_ce::ff::{PrimeField, PrimeFieldRepr};
use pairing_ce::Engine;
use zokrates_embed::{bellman::generate_sha256_round_constraints, Constraint};
use zokrates_embed::{bellman::generate_sha256_round_constraints};
}
}
@ -133,19 +132,19 @@ impl FlatEmbed {
.inputs(vec![
DeclarationType::array((
DeclarationType::FieldElement,
Some(Constant::Generic(GenericIdentifier {
name: "V",
index: 1,
})),
)), // 18 + (2 * n)
DeclarationType::array((
DeclarationType::FieldElement,
Some(Constant::Generic(GenericIdentifier {
GenericIdentifier {
name: "N",
index: 0,
})),
},
)), // inputs
DeclarationType::array((DeclarationType::FieldElement, 8)), // proof
DeclarationType::array((DeclarationType::FieldElement, 8usize)), // proof
DeclarationType::array((
DeclarationType::FieldElement,
GenericIdentifier {
name: "V",
index: 1,
},
)), // 18 + (2 * n) // vk
])
.outputs(vec![DeclarationType::Boolean]),
}
@ -191,7 +190,7 @@ impl FlatEmbed {
#[cfg(feature = "bellman")]
FlatEmbed::Sha256Round => sha256_round(),
#[cfg(feature = "ark")]
FlatEmbed::Verify => verify(),
FlatEmbed::Verify => verify(generics[0] as usize),
_ => unreachable!(),
}
}
@ -199,37 +198,33 @@ impl FlatEmbed {
// util to convert a vector of `(variable_id, coefficient)` to a flat_expression
// we build a binary tree of additions by splitting the vector recursively
#[cfg(feature = "bellman")]
fn flat_expression_from_vec<T: Field, E: Engine>(v: &[(usize, E::Fr)]) -> FlatExpression<T> {
fn flat_expression_from_vec<T: Field>(v: &[(usize, T)]) -> FlatExpression<T> {
match v.len() {
0 => FlatExpression::Number(T::zero()),
1 => {
let (key, val) = v[0];
let mut res: Vec<u8> = vec![];
val.into_repr().write_le(&mut res).unwrap();
let (key, val) = v[0].clone();
FlatExpression::Mult(
box FlatExpression::Number(T::from_byte_vector(res)),
box FlatExpression::Number(val),
box FlatExpression::Identifier(FlatVariable::new(key)),
)
}
n => {
let (u, v) = v.split_at(n / 2);
FlatExpression::Add(
box flat_expression_from_vec::<T, E>(u),
box flat_expression_from_vec::<T, E>(v),
box flat_expression_from_vec::<T>(u),
box flat_expression_from_vec::<T>(v),
)
}
}
}
#[cfg(feature = "bellman")]
fn flat_statement_from_constraint<T: Field, E: Engine>(c: Constraint<E::Fr>) -> FlatStatement<T> {
let rhs_a = flat_expression_from_vec::<T, E>(&c.a);
let rhs_b = flat_expression_from_vec::<T, E>(&c.b);
let lhs = flat_expression_from_vec::<T, E>(&c.c);
FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
}
// fn flat_statement_from_constraint<T: Field, F>(c: Constraint<F>) -> FlatStatement<T> {
// let rhs_a = flat_expression_from_vec::<T, F>(&c.a);
// let rhs_b = flat_expression_from_vec::<T, F>(&c.b);
// let lhs = flat_expression_from_vec::<T, F>(&c.c);
//
// FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
// }
/// Returns a flat function which computes a sha256 round
///
@ -288,10 +283,15 @@ pub fn sha256_round<T: Field>() -> FlatFunction<T> {
)
});
// insert flattened statements to represent constraints
let constraint_statements = r1cs
.constraints
.into_iter()
.map(|c| flat_statement_from_constraint::<T, Bn256>(c));
let constraint_statements = r1cs.constraints.into_iter().map(|c| {
let c = from_bellman::<T, Bn256>(c);
let rhs_a = flat_expression_from_vec::<T>(c.a.as_slice());
let rhs_b = flat_expression_from_vec::<T>(c.b.as_slice());
let lhs = flat_expression_from_vec::<T>(c.c.as_slice());
FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
});
// define which subset of the witness is returned
let outputs: Vec<FlatExpression<T>> = output_indices
.map(|o| FlatExpression::Identifier(FlatVariable::new(o)))
@ -323,114 +323,99 @@ pub fn sha256_round<T: Field>() -> FlatFunction<T> {
#[cfg(feature = "ark")]
pub fn verify<T: Field>(n: usize) -> FlatFunction<T> {
unreachable!();
//
// let (output_index, constraints) = generate_verify_constraints(n);
//
// let statements = constraints
// .into_iter()
// .map(|c| flat_statement_from_constraint::<T, BW6_761>(c))
// .collect();
//
// //indices of the arguments to the function
// // apply an offset of `variable_count` to get the index of our dummy `input` argument
// let input_argument_indices = input_indices
// .clone()
// .into_iter()
// .map(|i| i + variable_count);
//
// let proof_argument_indices = proof_indices
// .clone()
// .into_iter()
// .map(|i| i + variable_count);
//
// let vk_argument_indices = vk_indices.clone().into_iter().map(|i| i + variable_count);
//
// // define parameters to the function based on the variables
// let proof_arguments = proof_argument_indices.clone().map(|i| FlatParameter {
// id: FlatVariable::new(i),
// private: true,
// });
//
// let input_arguments = input_argument_indices.clone().map(|i| FlatParameter {
// id: FlatVariable::new(i),
// private: false,
// });
//
// let vk_arguments = vk_argument_indices.clone().map(|i| FlatParameter {
// id: FlatVariable::new(i),
// private: true,
// });
//
// let arguments = proof_arguments
// .clone()
// .chain(input_arguments)
// .chain(vk_arguments)
// .collect();
//
// let one_binding_statement = FlatStatement::Condition(
// FlatExpression::Identifier(FlatVariable::new(0)),
// FlatExpression::Number(T::from(1)),
// );
//
// let input_binding_statements: Vec<_> = proof_indices
// .clone()
// .chain(input_indices.clone())
// .chain(vk_indices.clone())
// .zip(
// proof_argument_indices
// .clone()
// .chain(input_argument_indices.clone())
// .chain(vk_argument_indices.clone()),
// )
// .map(|(cs_index, argument_index)| {
// FlatStatement::Condition(
// FlatVariable::new(cs_index).into(),
// FlatVariable::new(argument_index).into(),
// )
// })
// .collect();
//
// let directive_outputs: Vec<FlatVariable> = output_indices
// .clone()
// .map(|o| FlatVariable::new(o))
// .collect();
//
// let outputs: Vec<FlatExpression<T>> = directive_outputs
// .iter()
// .enumerate()
// .map(|(_, o)| FlatExpression::Identifier(o.clone()))
// .collect();
//
// // insert flattened statements to represent constraints
// let constraint_statements: Vec<FlatStatement<T>> =
// r1cs.constraints.into_iter().map(|c| to_fs(c)).collect();
// let return_statement = FlatStatement::Return(FlatExpressionList {
// expressions: outputs.clone(),
// });
//
// // insert a directive to set the witness based on the zexe gadget and inputs
// let directive_statement = FlatStatement::Directive(FlatDirective {
// outputs: cs_indices.map(|i| FlatVariable::new(i)).collect(),
// inputs: proof_argument_indices
// .chain(input_argument_indices.clone())
// .chain(vk_argument_indices.clone())
// .map(|i| FlatVariable::new(i).into())
// .collect(),
// solver: Solver::Verify(n),
// });
//
// let statements: Vec<_> = std::iter::once(directive_statement)
// .chain(std::iter::once(one_binding_statement))
// .chain(input_binding_statements)
// .chain(constraint_statements)
// .chain(std::iter::once(return_statement))
// .collect();
//
// FlatFunction {
// arguments,
// statements,
// }
let (out_index, input_indices, proof_indices, vk_indices, constraints, aux_count) =
generate_verify_constraints(n);
let variable_count = aux_count + 1; // aux + ~one
let cs_indices = 0..variable_count;
let input_indices = input_indices.into_iter();
let proof_indices = proof_indices.into_iter();
let vk_indices = vk_indices.into_iter();
// indices of the arguments to the function
let input_argument_indices = input_indices.clone().map(|i| i + variable_count);
let proof_argument_indices = proof_indices.clone().map(|i| i + variable_count);
let vk_argument_indices = vk_indices.clone().map(|i| i + variable_count);
let input_arguments = input_argument_indices
.clone()
.map(|i| FlatParameter::private(FlatVariable::new(i)));
let proof_arguments = proof_argument_indices
.clone()
.map(|i| FlatParameter::private(FlatVariable::new(i)));
let vk_arguments = vk_argument_indices
.clone()
.map(|i| FlatParameter::private(FlatVariable::new(i)));
let arguments = input_arguments
.chain(proof_arguments)
.chain(vk_arguments)
.collect();
let one_binding_statement = FlatStatement::Condition(
FlatExpression::Identifier(FlatVariable::new(0)),
FlatExpression::Number(T::from(1)),
);
let input_binding_statements: Vec<_> = input_indices
.chain(proof_indices)
.chain(vk_indices)
.zip(
input_argument_indices
.clone()
.chain(proof_argument_indices.clone())
.chain(vk_argument_indices.clone()),
)
.map(|(cs_index, argument_index)| {
FlatStatement::Condition(
FlatVariable::new(cs_index).into(),
FlatVariable::new(argument_index).into(),
)
})
.collect();
let constraint_statements: Vec<FlatStatement<T>> = constraints
.into_iter()
.map(|c| {
let c: Constraint<T> = from_ark::<T, Bls12_377>(c);
let rhs_a = flat_expression_from_vec::<T>(c.a.as_slice());
let rhs_b = flat_expression_from_vec::<T>(c.b.as_slice());
let lhs = flat_expression_from_vec::<T>(c.c.as_slice());
FlatStatement::Condition(lhs, FlatExpression::Mult(box rhs_a, box rhs_b))
})
.collect();
let return_statement = FlatStatement::Return(FlatExpressionList {
expressions: vec![FlatExpression::Identifier(FlatVariable::new(out_index))],
});
// insert a directive to set the witness
let directive_statement = FlatStatement::Directive(FlatDirective {
outputs: cs_indices.map(FlatVariable::new).collect(),
inputs: input_argument_indices
.chain(proof_argument_indices)
.chain(vk_argument_indices)
.map(|i| FlatVariable::new(i).into())
.collect(),
solver: Solver::Verify(n),
});
let statements: Vec<_> = std::iter::once(directive_statement)
.chain(std::iter::once(one_binding_statement))
.chain(input_binding_statements)
.chain(constraint_statements)
.chain(std::iter::once(return_statement))
.collect();
FlatFunction {
arguments,
statements,
}
}
fn use_variable(

View file

@ -156,6 +156,10 @@ impl Importer {
id: symbol.get_alias(),
symbol: Symbol::Flat(FlatEmbed::U8FromBits),
},
"verify" => SymbolDeclaration {
id: symbol.get_alias(),
symbol: Symbol::Flat(FlatEmbed::Verify),
},
s => {
return Err(CompileErrorInner::ImportError(
Error::new(format!("Embed {} not found", s)).with_pos(Some(pos)),

View file

@ -144,7 +144,7 @@ impl Interpreter {
inputs: &[T],
) -> Result<Vec<T>, String> {
let (expected_input_count, expected_output_count) = solver.get_signature();
assert!(inputs.len() == expected_input_count);
assert_eq!(inputs.len(), expected_input_count);
let res = match solver {
Solver::ConditionEq => match inputs[0].is_zero() {
@ -233,6 +233,10 @@ impl Interpreter {
})
.collect()
}
#[cfg(feature = "ark")]
Solver::Verify(_n) => {
todo!()
}
};
assert_eq!(res.len(), expected_output_count);

View file

@ -37,7 +37,7 @@ impl Solver {
#[cfg(feature = "bellman")]
Solver::Sha256Round => (768, 26935),
#[cfg(feature = "ark")]
Solver::Verify(n) => (26 + 3 * n, 56953 + 3078 * n), // TODO: update this
Solver::Verify(n) => (26 + 3 * n, 0), // TODO: update output count
}
}
}

View file

@ -549,6 +549,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> {
}
}
FlatEmbed::Sha256Round => None,
FlatEmbed::Verify => None,
};
match r {

View file

@ -10,6 +10,7 @@ wasm = ["bellman_ce/wasm", "sapling-crypto_ce/wasm"]
multicore = ["bellman_ce/multicore", "sapling-crypto_ce/multicore"]
[dependencies]
zokrates_field = { version = "0.4.0", path = "../zokrates_field", default-features = false }
bellman_ce = { version = "^0.3", default-features = false }
sapling-crypto_ce = { version = "^0.1", default-features = false }
ark-bls12-377 = { version = "^0.2.0", features = ["curve", "r1cs"], default-features = false }

View file

@ -1,54 +1,38 @@
use ark_bls12_377::{
constraints::PairingVar as BLS12PairingVar, Bls12_377 as BLS12PairingEngine, Fr as BLS12Fr,
constraints::PairingVar as BLS12PairingVar, Bls12_377 as BLS12PairingEngine, Fq as BLS12Fq,
};
use ark_bw6_761::Fr as BW6Fr;
use ark_ec::PairingEngine;
use ark_ff::{Field, UniformRand};
use ark_ff::{BigInteger, One, PrimeField};
use ark_r1cs_std::bits::boolean::Boolean;
use ark_relations::{
lc, ns,
ns,
r1cs::{ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, SynthesisError},
};
use ark_crypto_primitives::snark::constraints::SNARKGadget;
use ark_crypto_primitives::snark::{CircuitSpecificSetupSNARK, SNARK};
use ark_crypto_primitives::snark::{FromFieldElementsGadget, SNARK};
use ark_gm17::{constraints::GM17VerifierGadget, GM17};
use ark_r1cs_std::ToBitsGadget;
use ark_r1cs_std::ToConstraintFieldGadget;
use ark_r1cs_std::alloc::AllocVar;
use ark_std::test_rng;
use crate::Constraint;
use ark_r1cs_std::eq::EqGadget;
use ark_r1cs_std::fields::fp::FpVar;
use ark_relations::r1cs::Variable;
use ark_std::ops::MulAssign;
#[derive(Copy, Clone)]
struct DummyCircuit<F: Field> {
a: Option<F>,
b: Option<F>,
input_size: usize,
struct DefaultCircuit {
pub public_input_size: usize,
}
impl<ConstraintF: Field> ConstraintSynthesizer<ConstraintF> for DummyCircuit<ConstraintF> {
fn generate_constraints(
self,
cs: ConstraintSystemRef<ConstraintF>,
) -> Result<(), SynthesisError> {
let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?;
let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?;
for _ in 0..self.input_size {
let c = cs.new_input_variable(|| {
let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?;
let b = self.b.ok_or(SynthesisError::AssignmentMissing)?;
a.mul_assign(&b);
Ok(a)
})?;
cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?;
impl<F: PrimeField> ConstraintSynthesizer<F> for DefaultCircuit {
fn generate_constraints(self, cs: ConstraintSystemRef<F>) -> Result<(), SynthesisError> {
for _ in 0..self.public_input_size {
let _ = FpVar::<F>::new_input(ns!(cs, "alloc"), || Ok(F::one()))?;
// gadget.to_bits_le()?;
}
Ok(())
}
}
@ -56,49 +40,45 @@ impl<ConstraintF: Field> ConstraintSynthesizer<ConstraintF> for DummyCircuit<Con
type GM17Snark = GM17<BLS12PairingEngine>;
type VerifierGadget = GM17VerifierGadget<BLS12PairingEngine, BLS12PairingVar>;
// pub fn generate_verify_constraints(input_size: usize) -> (usize, Vec<Constraint<BW6Fr>>) {
#[test]
pub fn generate_verify_constraints() {
let input_size: usize = 1;
#[allow(clippy::type_complexity)]
pub fn generate_verify_constraints(
public_input_size: usize,
) -> (
usize,
Vec<usize>,
Vec<usize>,
Vec<usize>,
Vec<Constraint<BW6Fr>>,
usize,
) {
let mut rng = test_rng();
let a = BLS12Fr::rand(&mut rng);
let b = BLS12Fr::rand(&mut rng);
let mut c = a.clone();
c.mul_assign(&b);
let circuit = DefaultCircuit { public_input_size };
let circuit = DummyCircuit {
a: Some(a),
b: Some(b),
input_size,
};
let (pk, vk) = GM17Snark::setup(circuit.clone(), &mut rng).unwrap();
let (pk, vk) = GM17Snark::circuit_specific_setup(circuit, &mut rng).unwrap();
let proof = GM17Snark::prove(&pk, circuit, &mut rng).unwrap();
let cs_sys = ConstraintSystem::<BW6Fr>::new();
let cs = ConstraintSystemRef::new(cs_sys);
let input_gadget =
<VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::InputVar::new_input(ns!(cs, "alloc_inputs"), || Ok(vec![c; input_size]))
.unwrap();
let mut inputs = Vec::new();
for _ in 0..public_input_size {
inputs.push(FpVar::new_input(ns!(cs, "alloc_input"), || Ok(BLS12Fq::one())).unwrap());
}
let input_indices = input_gadget
.clone()
.into_iter()
.map(|f| {
f.iter()
.map(|b| match b {
Boolean::Is(x) => var_to_index(x.variable()),
Boolean::Not(x) => var_to_index(x.variable()),
_ => unreachable!(),
})
.collect()
let input_indices = inputs
.iter()
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<Vec<usize>>>();
.collect::<Vec<usize>>();
let input_gadget = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::InputVar::from_field_elements(&inputs)
.unwrap();
let proof_gadget = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
@ -107,35 +87,128 @@ pub fn generate_verify_constraints() {
>>::ProofVar::new_witness(ns!(cs, "alloc_proof"), || Ok(proof))
.unwrap();
let proof_indices = proof_gadget
.clone()
.a
.to_bits_le()
.unwrap()
.into_iter()
.map(|b| match b {
Boolean::Is(x) => var_to_index(x.variable()),
Boolean::Not(x) => var_to_index(x.variable()),
_ => unreachable!(),
})
.collect::<Vec<usize>>();
let proof_indices: Vec<usize> = vec![
proof_gadget
.a
.to_constraint_field()
.unwrap()
.iter()
.take(2) // [x, y, infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
proof_gadget
.b
.to_constraint_field()
.unwrap()
.iter()
.take(4) // [[x0, y0], [x1, y1], infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
proof_gadget
.c
.to_constraint_field()
.unwrap()
.iter()
.take(2) // [x, y, infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
]
.into_iter()
.flatten()
.collect();
let vk_gadget = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
<BLS12PairingEngine as PairingEngine>::Fq,
GM17Snark,
>>::VerifyingKeyVar::new_constant(ns!(cs, "alloc_vk"), vk.clone())
>>::VerifyingKeyVar::new_witness(ns!(cs, "alloc_vk"), || Ok(vk.clone()))
.unwrap();
// let vk_indices = vk_gadget
// .clone()
// .into_iter()
// .map(|f| f.iter().map(|b| match b {
// Boolean::Is(x) => var_to_index(x.variable()),
// Boolean::Not(x) => var_to_index(x.variable()),
// _ => unreachable!(),
// }).collect())
// .collect::<Vec<Vec<usize>>>();
let vk_indices: Vec<usize> = vec![
vk_gadget
.h_g2
.to_constraint_field()
.unwrap()
.iter()
.take(4) // [[x0, y0], [x1, y1], infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
vk_gadget
.g_alpha_g1
.to_constraint_field()
.unwrap()
.iter()
.take(2) // [x, y, infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
vk_gadget
.h_beta_g2
.to_constraint_field()
.unwrap()
.iter()
.take(4) // [[x0, y0], [x1, y1], infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
vk_gadget
.g_gamma_g1
.to_constraint_field()
.unwrap()
.iter()
.take(2) // [x, y, infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
vk_gadget
.h_gamma_g2
.to_constraint_field()
.unwrap()
.iter()
.take(4) // [[x0, y0], [x1, y1], infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>(),
vk_gadget
.query
.iter()
.map(|q| {
q.to_constraint_field()
.unwrap()
.iter()
.take(2) // [x, y, infinity] - infinity
.map(|f| match f {
FpVar::Var(fp) => var_to_index(&fp.variable),
_ => unreachable!(),
})
.collect::<Vec<usize>>()
})
.flatten()
.collect::<Vec<usize>>(),
]
.into_iter()
.flatten()
.collect::<Vec<usize>>();
let res = <VerifierGadget as SNARKGadget<
<BLS12PairingEngine as PairingEngine>::Fr,
@ -145,13 +218,12 @@ pub fn generate_verify_constraints() {
.unwrap();
let out_index = match &res {
Boolean::Is(x) => var_to_index(x.variable()),
Boolean::Not(x) => var_to_index(x.variable()),
Boolean::Is(x) => var_to_index(&x.variable()),
Boolean::Not(x) => var_to_index(&x.variable()),
_ => unreachable!(),
};
res.conditional_enforce_equal(&Boolean::constant(true), &Boolean::constant(true))
.unwrap();
// res.conditional_enforce_equal(&Boolean::TRUE, &Boolean::TRUE).unwrap();
cs.finalize();
let matrices = cs.to_matrices().unwrap();
@ -167,16 +239,62 @@ pub fn generate_verify_constraints() {
})
.collect();
assert!(cs.is_satisfied().unwrap());
// println!("input_indices: {:?}", input_indices);
// println!("proof_indices: {:?}", proof_indices);
// println!("vk_indices: {:?}", vk_indices);
// println!("out_index: {:?}", out_index);
println!("{}", input_indices.len());
println!("{}", proof_indices.len());
// println!("{}", vk_indices.len());
assert!(
cs.is_satisfied().unwrap(),
"Constraint not satisfied: {}",
cs.which_is_unsatisfied().unwrap().unwrap_or_default()
);
// (out_index, constraints)
(
out_index,
input_indices,
proof_indices,
vk_indices,
constraints,
cs.num_witness_variables(),
)
}
fn var_to_index(v: Variable) -> usize {
#[test]
fn generate_verify_constraints_test() {
let _ = generate_verify_constraints(2);
}
fn var_to_index(v: &Variable) -> usize {
v.get_index_unchecked(0)
.expect("Could not get variable index")
}
pub fn from_ark<T: zokrates_field::Field, E: PairingEngine>(c: Constraint<E::Fq>) -> Constraint<T> {
Constraint {
a: c.a
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
b: c.b
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
c: c.c
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
}
}

View file

@ -6,6 +6,7 @@ use bellman::{
pairing::{ff::Field, Engine},
ConstraintSystem, Index, LinearCombination, SynthesisError, Variable,
};
use sapling_crypto::bellman::pairing::ff::{PrimeField, PrimeFieldRepr};
use sapling_crypto::circuit::{
boolean::{AllocatedBit, Boolean},
sha256::sha256_compression_function,
@ -149,7 +150,7 @@ impl<E: Engine> ConstraintSystem<E> for R1CS<E::Fr> {
AR: Into<String>,
{
// we don't care about the value as we're only generating the CS
let index = self.aux_count.clone();
let index = self.aux_count;
let var = Variable::new_unchecked(Index::Aux(index));
self.aux_count += 1;
Ok(var)
@ -252,6 +253,35 @@ fn var_to_index(v: Variable) -> usize {
}
}
pub fn from_bellman<T: zokrates_field::Field, E: Engine>(c: Constraint<E::Fr>) -> Constraint<T> {
Constraint {
a: c.a
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
b: c.b
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
c: c.c
.into_iter()
.map(|(index, fq)| {
let mut res: Vec<u8> = vec![];
fq.into_repr().write_le(&mut res).unwrap();
(index, T::from_byte_vector(res))
})
.collect(),
}
}
#[cfg(test)]
mod tests {
use super::*;