#![doc(
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://docs.rs/rand/0.5.4",
html_playground_url = "https://play.rust-lang.org/"
)]
mod encryption;
pub mod field;
pub mod groth16;
#[doc(hidden)]
pub use groth16::circuit::dummy_rep::DummyRep;
#[doc(hidden)]
pub use groth16::circuit::{ASTParser, TryParse};
#[doc(hidden)]
pub use groth16::circuit::{Circuit, CircuitInstance, WireId};
#[doc(hidden)]
pub use groth16::coefficient_poly::CoefficientPoly;
#[doc(hidden)]
pub use groth16::fr::FrLocal;
#[doc(hidden)]
pub use groth16::{Proof, SigmaG1, SigmaG2, QAP};
#[cfg(test)]
mod tests {
use super::field::z251::Z251;
use super::groth16::Random;
use super::*;
#[test]
fn simple_circuit_test() {
let code = &*::std::fs::read_to_string("test_programs/simple.zk").unwrap();
let qap: QAP<CoefficientPoly<FrLocal>> = ASTParser::try_parse(code).unwrap().into();
let assignments = &[
3.into(), 2.into(), 4.into(), ];
let weights = groth16::weights(code, assignments).unwrap();
let (sigmag1, sigmag2) = groth16::setup(&qap);
let proof = groth16::prove(&qap, (&sigmag1, &sigmag2), &weights);
assert!(groth16::verify(
&qap,
(sigmag1, sigmag2),
&vec![FrLocal::from(2), FrLocal::from(34)],
proof
));
let (sigmag1, sigmag2) = groth16::setup(&qap);
let proof = groth16::prove(&qap, (&sigmag1, &sigmag2), &weights);
assert!(!groth16::verify(
&qap,
(sigmag1, sigmag2),
&vec![FrLocal::from(2), FrLocal::from(25)],
proof
));
}
fn to_bits(mut n: u8) -> [u8; 8] {
let mut bits: [u8; 8] = [0; 8];
for i in 0..8 {
bits[i] = n % 2;
n = n >> 1;
}
bits
}
#[test]
fn comparator_8bit_test() {
let code = &*::std::fs::read_to_string("test_programs/8bit_comparator.zk").unwrap();
let qap: QAP<CoefficientPoly<Z251>> = ASTParser::try_parse(code).unwrap().into();
for _ in 0..1000 {
let (a, b) = (Z251::random_elem(), Z251::random_elem());
let (abits, bbits) = (to_bits(a.inner), to_bits(b.inner));
let assignments = abits
.iter()
.chain(bbits.iter())
.map(|&bit| Z251::from(bit as usize))
.collect::<Vec<_>>();
let weights = groth16::weights(code, &assignments).unwrap();
let (sigmag1, sigmag2) = groth16::setup(&qap);
let proof = groth16::prove(&qap, (&sigmag1, &sigmag2), &weights);
if a.inner > b.inner {
let mut inputs = vec![Z251::from(1)];
inputs.append(
&mut bbits
.iter()
.map(|&bit| Z251::from(bit as usize))
.collect::<Vec<_>>(),
);
assert!(groth16::verify(&qap, (sigmag1, sigmag2), &inputs, proof));
} else {
let mut inputs = vec![Z251::from(0)];
inputs.append(
&mut bbits
.iter()
.map(|&bit| Z251::from(bit as usize))
.collect::<Vec<_>>(),
);
assert!(groth16::verify(&qap, (sigmag1, sigmag2), &inputs, proof));
}
}
}
#[test]
fn circuit_builder_test() {
let mut circuit = Circuit::<FrLocal>::new();
let x = circuit.new_wire();
let x_checker = circuit.new_bit_checker(x);
let y = circuit.new_wire();
let y_checker = circuit.new_bit_checker(y);
let or = circuit.new_or(x, y);
let mut instance =
CircuitInstance::new(circuit, vec![x_checker, y_checker, or], vec![x, y], |w| {
FrLocal::from(w.inner_id() + 1)
});
let qap: QAP<CoefficientPoly<FrLocal>> = QAP::from(DummyRep::from(&instance));
let assignments = vec![FrLocal::from(0), FrLocal::from(1)];
let weights = instance.weights(assignments);
let (sigmag1, sigmag2) = groth16::setup(&qap);
let proof = groth16::prove(&qap, (&sigmag1, &sigmag2), &weights);
assert!(groth16::verify(
&qap,
(sigmag1, sigmag2),
&[FrLocal::from(0), FrLocal::from(0), FrLocal::from(1)],
proof
));
}
}