mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-22 09:41:37 +03:00
public input booleans and integers
This commit is contained in:
parent
c6d3221289
commit
67b8a48fcf
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
/target
|
||||
/tmp/
|
||||
**.idea/
|
||||
outputs/
|
||||
*.DS_Store
|
||||
|
@ -16,6 +16,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use snarkos_models::curves::PairingEngine;
|
||||
use std::{fs, marker::PhantomData, path::PathBuf};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -58,7 +59,11 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
}
|
||||
|
||||
pub fn set_inputs(&mut self, program_inputs: Vec<Option<InputValue>>) {
|
||||
self.program_inputs.set_private_inputs(program_inputs);
|
||||
self.program_inputs.set_inputs(program_inputs);
|
||||
}
|
||||
|
||||
pub fn get_public_inputs<E: PairingEngine>(&self) -> Result<Vec<E::Fr>, CompilerError> {
|
||||
Ok(self.program_inputs.get_public_inputs::<E>()?)
|
||||
}
|
||||
|
||||
pub fn checksum(&self) -> Result<String, CompilerError> {
|
||||
@ -78,7 +83,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<ConstrainedValue<F, G>, CompilerError> {
|
||||
generate_constraints(cs, self.program, self.program_inputs.get_private_inputs())
|
||||
generate_constraints(cs, self.program, self.program_inputs.get_inputs())
|
||||
}
|
||||
|
||||
pub fn compile_test_constraints(self, cs: &mut TestConstraintSystem<F>) -> Result<(), CompilerError> {
|
||||
@ -99,7 +104,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
let package_name = self.package_name.clone();
|
||||
|
||||
self.program = Program::from(syntax_tree, package_name);
|
||||
self.program_inputs.set_private_inputs_size(self.program.num_parameters);
|
||||
self.program_inputs.set_inputs_size(self.program.num_parameters);
|
||||
|
||||
log::debug!("Program parsing complete\n{:#?}", self.program);
|
||||
|
||||
@ -116,7 +121,6 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
// println!("{:?}", syntax_tree);
|
||||
|
||||
// Check number of private parameters here
|
||||
|
||||
self.program_inputs = Inputs::from_inputs_file(syntax_tree)?;
|
||||
|
||||
Ok(())
|
||||
@ -125,8 +129,7 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
|
||||
let _result =
|
||||
generate_constraints::<_, G, _>(cs, self.program, self.program_inputs.get_private_inputs()).unwrap();
|
||||
let _result = generate_constraints::<_, G, _>(cs, self.program, self.program_inputs.get_inputs()).unwrap();
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
|
@ -5,6 +5,7 @@ use leo_compiler::{
|
||||
};
|
||||
use leo_types::{InputValue, Integer, IntegerError};
|
||||
|
||||
use leo_inputs::types::{IntegerType, U32Type};
|
||||
use snarkos_models::gadgets::utilities::uint::UInt32;
|
||||
|
||||
// [1, 1, 1]
|
||||
@ -52,6 +53,10 @@ fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn input_value_u32_one() -> InputValue {
|
||||
InputValue::Integer(IntegerType::U32Type(U32Type {}), 1)
|
||||
}
|
||||
|
||||
// Expressions
|
||||
|
||||
#[test]
|
||||
@ -101,7 +106,7 @@ fn test_input_array() {
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Array(vec![InputValue::Integer(1u128); 3]))]);
|
||||
program.set_inputs(vec![Some(InputValue::Array(vec![input_value_u32_one(); 3]))]);
|
||||
|
||||
output_ones(program)
|
||||
}
|
||||
@ -111,7 +116,7 @@ fn test_input_array_fail() {
|
||||
let bytes = include_bytes!("input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1u128))]);
|
||||
program.set_inputs(vec![Some(input_value_u32_one())]);
|
||||
|
||||
fail_array(program);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use leo_compiler::{
|
||||
};
|
||||
use leo_types::InputValue;
|
||||
|
||||
use crate::array::input_value_u32_one;
|
||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||
|
||||
pub fn output_expected_boolean(program: EdwardsTestCompiler, boolean: bool) {
|
||||
@ -76,7 +77,7 @@ fn test_input_bool_field() {
|
||||
let bytes = include_bytes!("input_bool.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1u128))]);
|
||||
program.set_inputs(vec![Some(input_value_u32_one())]);
|
||||
|
||||
fail_boolean(program);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use leo_compiler::{
|
||||
};
|
||||
use leo_types::{InputValue, Integer};
|
||||
|
||||
use crate::array::input_value_u32_one;
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint::UInt32};
|
||||
|
||||
@ -84,7 +85,7 @@ fn test_function_input() {
|
||||
let bytes = include_bytes!("function_input.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1))]);
|
||||
program.set_inputs(vec![Some(input_value_u32_one())]);
|
||||
mut_fail(program);
|
||||
}
|
||||
|
||||
@ -93,6 +94,6 @@ fn test_function_input_mut() {
|
||||
let bytes = include_bytes!("function_input_mut.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![Some(InputValue::Integer(1))]);
|
||||
program.set_inputs(vec![Some(input_value_u32_one())]);
|
||||
mut_success(program);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::ast::Rule;
|
||||
|
||||
use pest_ast::FromPest;
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::type_integer))]
|
||||
pub enum IntegerType {
|
||||
U8Type(U8Type),
|
||||
@ -12,22 +12,22 @@ pub enum IntegerType {
|
||||
U128Type(U128Type),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::type_u8))]
|
||||
pub struct U8Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::type_u16))]
|
||||
pub struct U16Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::type_u32))]
|
||||
pub struct U32Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::type_u64))]
|
||||
pub struct U64Type {}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[derive(Clone, Debug, FromPest, PartialEq, Eq)]
|
||||
#[pest_ast(rule(Rule::type_u128))]
|
||||
pub struct U128Type {}
|
||||
|
@ -10,7 +10,9 @@ use snarkos_algorithms::snark::{create_random_proof, Proof};
|
||||
use snarkos_curves::bls12_377::Bls12_377;
|
||||
|
||||
use clap::ArgMatches;
|
||||
use leo_compiler::{compiler::Compiler, edwards_bls12::EdwardsGroupType};
|
||||
use rand::thread_rng;
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use std::{convert::TryFrom, env::current_dir, time::Instant};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -18,7 +20,7 @@ pub struct ProveCommand;
|
||||
|
||||
impl CLI for ProveCommand {
|
||||
type Options = ();
|
||||
type Output = Proof<Bls12_377>;
|
||||
type Output = (Compiler<Fq, EdwardsGroupType>, Proof<Bls12_377>);
|
||||
|
||||
const ABOUT: AboutType = "Run the program and produce a proof";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
@ -42,16 +44,12 @@ impl CLI for ProveCommand {
|
||||
|
||||
// Fetch private inputs here
|
||||
program.parse_inputs(&path)?;
|
||||
// let _res = LeoInputsParser::get_private(&path).unwrap();
|
||||
// let inputs_path = path.clone().push("/inputs")
|
||||
// LeoInputsParser::load_file()
|
||||
// program.set_inputs();
|
||||
|
||||
// Start the timer
|
||||
let start = Instant::now();
|
||||
|
||||
let rng = &mut thread_rng();
|
||||
let program_proof = create_random_proof(program, ¶meters, rng).unwrap();
|
||||
let program_proof = create_random_proof(program.clone(), ¶meters, rng).unwrap();
|
||||
|
||||
log::info!("Prover completed in {:?} milliseconds", start.elapsed().as_millis());
|
||||
|
||||
@ -62,6 +60,6 @@ impl CLI for ProveCommand {
|
||||
|
||||
log::info!("Completed program proving");
|
||||
|
||||
Ok(program_proof)
|
||||
Ok((program, program_proof))
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use snarkos_algorithms::snark::verify_proof;
|
||||
use snarkos_curves::bls12_377::Bls12_377;
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::time::{Duration, Instant};
|
||||
@ -32,16 +33,16 @@ impl CLI for RunCommand {
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn output(options: Self::Options) -> Result<(), CLIError> {
|
||||
let (_program, _parameters, prepared_verifying_key) = SetupCommand::output(options)?;
|
||||
let proof = ProveCommand::output(options)?;
|
||||
let (program, proof) = ProveCommand::output(options)?;
|
||||
|
||||
let mut verifying = Duration::new(0, 0);
|
||||
|
||||
// fetch public inputs here
|
||||
// let _inputs: Vec<_> = [1u32; 1].to_vec();
|
||||
// fetch public inputs
|
||||
let inputs: Vec<_> = program.get_public_inputs::<Bls12_377>().unwrap();
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap();
|
||||
let is_success = verify_proof(&prepared_verifying_key, &proof, &inputs).unwrap();
|
||||
|
||||
verifying += start.elapsed();
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
[main]
|
||||
a: private bool[2] = [true; 2];
|
||||
a: public u128 = 120;
|
@ -1,4 +1,4 @@
|
||||
// The 'tmp' main function.
|
||||
function main(a: bool[2]) -> bool {
|
||||
return a[0]
|
||||
function main(a: public u128) -> u128 {
|
||||
return a
|
||||
}
|
||||
|
34
types/src/inputs/input_fields.rs
Normal file
34
types/src/inputs/input_fields.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use leo_inputs::{types::IntegerType, InputParserError};
|
||||
use snarkos_models::curves::{Field, PairingEngine};
|
||||
|
||||
pub struct InputFields<E: PairingEngine>(pub Vec<E::Fr>);
|
||||
|
||||
impl<E: PairingEngine> InputFields<E> {
|
||||
pub(crate) fn from_boolean(boolean: &bool) -> Self {
|
||||
if *boolean {
|
||||
Self(vec![E::Fr::one()])
|
||||
} else {
|
||||
Self(vec![E::Fr::zero()])
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_integer(type_: &IntegerType, integer: &u128) -> Result<Self, InputParserError> {
|
||||
let bits: usize = match type_ {
|
||||
IntegerType::U8Type(_) => 8,
|
||||
IntegerType::U16Type(_) => 16,
|
||||
IntegerType::U32Type(_) => 32,
|
||||
IntegerType::U64Type(_) => 64,
|
||||
IntegerType::U128Type(_) => 128,
|
||||
};
|
||||
let mut fields = vec![];
|
||||
|
||||
for i in 0..bits {
|
||||
let boolean = (integer.to_le() >> i) & 1 == 1;
|
||||
let mut boolean_fields = InputFields::<E>::from_boolean(&boolean);
|
||||
|
||||
fields.append(&mut boolean_fields.0);
|
||||
}
|
||||
|
||||
Ok(Self(fields))
|
||||
}
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
use crate::InputFields;
|
||||
use leo_inputs::{
|
||||
errors::InputParserError,
|
||||
expressions::{ArrayInitializerExpression, ArrayInlineExpression, Expression},
|
||||
types::{ArrayType, DataType, Type},
|
||||
types::{ArrayType, DataType, IntegerType, Type},
|
||||
values::{BooleanValue, FieldValue, GroupValue, NumberImplicitValue, NumberValue, Value},
|
||||
};
|
||||
use snarkos_models::curves::PairingEngine;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum InputValue {
|
||||
Integer(u128),
|
||||
Integer(IntegerType, u128),
|
||||
Field(String),
|
||||
Group(String),
|
||||
Boolean(bool),
|
||||
@ -21,9 +23,9 @@ impl<'ast> InputValue {
|
||||
Ok(InputValue::Boolean(boolean))
|
||||
}
|
||||
|
||||
fn from_number(number: NumberValue<'ast>) -> Result<Self, InputParserError> {
|
||||
fn from_number(integer_type: IntegerType, number: NumberValue<'ast>) -> Result<Self, InputParserError> {
|
||||
let integer = number.value.parse::<u128>()?;
|
||||
Ok(InputValue::Integer(integer))
|
||||
Ok(InputValue::Integer(integer_type, integer))
|
||||
}
|
||||
|
||||
fn from_group(group: GroupValue<'ast>) -> Self {
|
||||
@ -40,7 +42,7 @@ impl<'ast> InputValue {
|
||||
"bool".to_string(),
|
||||
"implicit number".to_string(),
|
||||
)),
|
||||
DataType::Integer(_) => InputValue::from_number(implicit.number),
|
||||
DataType::Integer(integer_type) => InputValue::from_number(integer_type, implicit.number),
|
||||
DataType::Group(_) => Ok(InputValue::Group(implicit.number.value)),
|
||||
DataType::Field(_) => Ok(InputValue::Field(implicit.number.value)),
|
||||
}
|
||||
@ -49,7 +51,9 @@ impl<'ast> InputValue {
|
||||
fn from_value(data_type: DataType, value: Value<'ast>) -> Result<Self, InputParserError> {
|
||||
match (data_type, value) {
|
||||
(DataType::Boolean(_), Value::Boolean(boolean)) => InputValue::from_boolean(boolean),
|
||||
(DataType::Integer(_), Value::Integer(integer)) => InputValue::from_number(integer.number),
|
||||
(DataType::Integer(integer_type), Value::Integer(integer)) => {
|
||||
InputValue::from_number(integer_type, integer.number)
|
||||
}
|
||||
(DataType::Group(_), Value::Group(group)) => Ok(InputValue::from_group(group)),
|
||||
(DataType::Field(_), Value::Field(field)) => Ok(InputValue::from_field(field)),
|
||||
(data_type, Value::Implicit(implicit)) => InputValue::from_implicit(data_type, implicit),
|
||||
@ -69,8 +73,8 @@ impl<'ast> InputValue {
|
||||
(Type::Array(array_type), Expression::ArrayInitializer(initializer)) => {
|
||||
InputValue::from_array_initializer(array_type, initializer)
|
||||
}
|
||||
(Type::Circuit(_), Expression::CircuitInline(_)) => unimplemented!("circuit input values not implemented"),
|
||||
(Type::Basic(_), Expression::Variable(_)) => unimplemented!("variable inputs not supported"),
|
||||
(Type::Circuit(_), Expression::CircuitInline(_)) => unimplemented!("circuit input values not supported"),
|
||||
(Type::Basic(_), Expression::Variable(_)) => unimplemented!("variable input values not supported"),
|
||||
(type_, value) => Err(InputParserError::IncompatibleTypes(
|
||||
type_.to_string(),
|
||||
value.to_string(),
|
||||
@ -146,15 +150,25 @@ impl<'ast> InputValue {
|
||||
|
||||
Ok(InputValue::Array(values))
|
||||
}
|
||||
|
||||
pub(crate) fn to_input_fields<E: PairingEngine>(&self) -> Result<InputFields<E>, InputParserError> {
|
||||
match self {
|
||||
InputValue::Boolean(boolean) => Ok(InputFields::from_boolean(boolean)),
|
||||
InputValue::Integer(type_, number) => InputFields::from_integer(type_, number),
|
||||
InputValue::Group(_) => unimplemented!(),
|
||||
InputValue::Field(_) => unimplemented!(),
|
||||
InputValue::Array(_) => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for InputValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
InputValue::Integer(ref integer) => write!(f, "{}", integer),
|
||||
InputValue::Field(ref field) => write!(f, "{}", field),
|
||||
InputValue::Boolean(ref boolean) => write!(f, "{}", boolean),
|
||||
InputValue::Integer(ref type_, ref number) => write!(f, "{}{:?}", number, type_),
|
||||
InputValue::Group(ref group) => write!(f, "{}", group),
|
||||
InputValue::Boolean(ref bool) => write!(f, "{}", bool),
|
||||
InputValue::Field(ref field) => write!(f, "{}", field),
|
||||
InputValue::Array(ref array) => {
|
||||
write!(f, "[")?;
|
||||
for (i, e) in array.iter().enumerate() {
|
||||
|
@ -1,48 +1,68 @@
|
||||
use crate::InputValue;
|
||||
use leo_inputs::{common::visibility::Visibility, files::File, InputParserError};
|
||||
use snarkos_models::curves::PairingEngine;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Inputs {
|
||||
private: Vec<Option<InputValue>>,
|
||||
//public: Vec<_>
|
||||
program_inputs: Vec<Option<InputValue>>,
|
||||
public: Vec<InputValue>,
|
||||
}
|
||||
|
||||
impl Inputs {
|
||||
pub fn new() -> Self {
|
||||
Self { private: vec![] }
|
||||
Self {
|
||||
program_inputs: vec![],
|
||||
public: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_private_inputs(&self) -> Vec<Option<InputValue>> {
|
||||
return self.private.clone();
|
||||
pub fn get_inputs(&self) -> Vec<Option<InputValue>> {
|
||||
self.program_inputs.clone()
|
||||
}
|
||||
|
||||
pub fn set_private_inputs(&mut self, inputs: Vec<Option<InputValue>>) {
|
||||
self.private = inputs;
|
||||
pub fn set_inputs(&mut self, inputs: Vec<Option<InputValue>>) {
|
||||
self.program_inputs = inputs;
|
||||
}
|
||||
|
||||
pub fn set_private_inputs_size(&mut self, size: usize) {
|
||||
self.private = vec![None; size];
|
||||
pub fn set_inputs_size(&mut self, size: usize) {
|
||||
self.program_inputs = vec![None; size];
|
||||
}
|
||||
|
||||
pub fn from_inputs_file(file: File) -> Result<Self, InputParserError> {
|
||||
let mut private = vec![];
|
||||
let mut public = vec![];
|
||||
|
||||
for section in file.sections.into_iter() {
|
||||
for assignment in section.assignments.into_iter() {
|
||||
let value = InputValue::from_expression(assignment.parameter.type_, assignment.expression)?;
|
||||
if let Some(Visibility::Public(_)) = assignment.parameter.visibility {
|
||||
// Collect public parameters here
|
||||
} else {
|
||||
// parameter is private by default
|
||||
// Collect public inputs here
|
||||
|
||||
// evaluate expression
|
||||
let value = InputValue::from_expression(assignment.parameter.type_, assignment.expression)?;
|
||||
|
||||
// push value to vector
|
||||
private.push(Some(value));
|
||||
public.push(value.clone());
|
||||
}
|
||||
|
||||
// push value to vector
|
||||
private.push(Some(value));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self { private })
|
||||
Ok(Self {
|
||||
program_inputs: private,
|
||||
public,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_public_inputs<E: PairingEngine>(&self) -> Result<Vec<E::Fr>, InputParserError> {
|
||||
let mut input_vec = vec![];
|
||||
|
||||
for input in self.public.iter() {
|
||||
// get fields
|
||||
let mut input_fields = input.to_input_fields::<E>()?;
|
||||
|
||||
// push fields to input_vec
|
||||
input_vec.append(&mut input_fields.0)
|
||||
}
|
||||
|
||||
Ok(input_vec)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
pub mod inputs;
|
||||
pub use inputs::*;
|
||||
|
||||
pub mod input_fields;
|
||||
pub use input_fields::*;
|
||||
|
||||
pub mod input_value;
|
||||
pub use input_value::*;
|
||||
|
@ -87,7 +87,7 @@ impl Integer {
|
||||
// Check that the input value is the correct type
|
||||
let integer_option = match integer_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Integer(integer) = input {
|
||||
if let InputValue::Integer(_type_, integer) = input {
|
||||
Some(integer)
|
||||
} else {
|
||||
return Err(IntegerError::InvalidInteger(input.to_string()));
|
||||
|
Loading…
Reference in New Issue
Block a user