mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
impl group alloc input
This commit is contained in:
parent
d1297fc60c
commit
ad2d9f1192
@ -4,6 +4,7 @@
|
||||
use crate::{
|
||||
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
|
||||
errors::{FunctionError, ImportError},
|
||||
group_from_input,
|
||||
types::{Expression, Function, Identifier, InputValue, Program, Type},
|
||||
GroupType,
|
||||
};
|
||||
@ -187,9 +188,7 @@ impl<
|
||||
Type::FieldElement => {
|
||||
Ok(self.field_element_from_input(cs, name, private, input_value)?)
|
||||
}
|
||||
// Type::Group => {
|
||||
// Ok(self.group_element_from_input(cs, name, private, input_value)?)
|
||||
// }
|
||||
Type::Group => Ok(group_from_input(cs, name, private, input_value)?),
|
||||
Type::Boolean => Ok(self.bool_from_input(cs, name, private, input_value)?),
|
||||
Type::Array(_type, dimensions) => {
|
||||
self.allocate_array(cs, name, private, *_type, dimensions, input_value)
|
||||
|
42
compiler/src/constraints/group.rs
Normal file
42
compiler/src/constraints/group.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use crate::errors::GroupError;
|
||||
use crate::{ConstrainedValue, GroupType, InputValue};
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||
|
||||
pub(crate) fn group_from_input<
|
||||
NativeF: Field,
|
||||
F: Field + PrimeField,
|
||||
GType: GroupType<NativeF, F>,
|
||||
CS: ConstraintSystem<F>,
|
||||
>(
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<NativeF, F, GType>, GroupError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let group_option = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Group(group_string) = input {
|
||||
Some(group_string)
|
||||
} else {
|
||||
return Err(GroupError::InvalidGroup(input.to_string()));
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Check visibility of parameter
|
||||
let group_value = if private {
|
||||
GType::alloc(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
} else {
|
||||
GType::alloc_input(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
};
|
||||
|
||||
Ok(ConstrainedValue::Group(group_value))
|
||||
}
|
@ -18,6 +18,9 @@ pub use integer::*;
|
||||
pub mod field_element;
|
||||
pub use field_element::*;
|
||||
|
||||
pub(crate) mod group;
|
||||
pub(crate) use group::*;
|
||||
|
||||
pub mod program;
|
||||
pub use program::*;
|
||||
|
||||
|
@ -8,8 +8,10 @@ use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||
use snarkos_models::curves::{AffineCurve, ModelParameters};
|
||||
use snarkos_models::gadgets::curves::{FpGadget, GroupGadget};
|
||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::alloc::AllocGadget;
|
||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||
use snarkos_models::gadgets::utilities::eq::{ConditionalEqGadget, EqGadget};
|
||||
use std::borrow::Borrow;
|
||||
use std::ops::Sub;
|
||||
use std::str::FromStr;
|
||||
|
||||
@ -21,16 +23,9 @@ pub enum EdwardsGroupType {
|
||||
|
||||
impl GroupType<<EdwardsParameters as ModelParameters>::BaseField, Fq> for EdwardsGroupType {
|
||||
fn constant(string: String) -> Result<Self, GroupError> {
|
||||
// 0 or (0, 1)
|
||||
let result =
|
||||
match Fq::from_str(&string).ok() {
|
||||
Some(x) => EdwardsAffine::get_point_from_x(x, false)
|
||||
.ok_or(GroupError::InvalidGroup(string))?,
|
||||
None => EdwardsAffine::from_str(&string)
|
||||
.map_err(|_| GroupError::InvalidGroup(string))?,
|
||||
};
|
||||
let value = Self::edwards_affine_from_str(string)?;
|
||||
|
||||
Ok(EdwardsGroupType::Constant(result))
|
||||
Ok(EdwardsGroupType::Constant(value))
|
||||
}
|
||||
|
||||
fn add<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self) -> Result<Self, GroupError> {
|
||||
@ -88,6 +83,67 @@ impl GroupType<<EdwardsParameters as ModelParameters>::BaseField, Fq> for Edward
|
||||
}
|
||||
}
|
||||
|
||||
impl EdwardsGroupType {
|
||||
pub fn edwards_affine_from_str(string: String) -> Result<EdwardsAffine, GroupError> {
|
||||
// 0 or (0, 1)
|
||||
match Fq::from_str(&string).ok() {
|
||||
Some(x) => {
|
||||
EdwardsAffine::get_point_from_x(x, false).ok_or(GroupError::InvalidGroup(string))
|
||||
}
|
||||
None => EdwardsAffine::from_str(&string).map_err(|_| GroupError::InvalidGroup(string)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_x_helper<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>>(
|
||||
value_gen: Fn,
|
||||
) -> Result<EdwardsAffine, SynthesisError> {
|
||||
let affine_string = match value_gen() {
|
||||
Ok(value) => {
|
||||
let string_value = value.borrow().clone();
|
||||
Ok(string_value)
|
||||
}
|
||||
_ => Err(SynthesisError::AssignmentMissing),
|
||||
}?;
|
||||
|
||||
Self::edwards_affine_from_str(affine_string).map_err(|_| SynthesisError::AssignmentMissing)
|
||||
}
|
||||
}
|
||||
|
||||
impl AllocGadget<String, Fq> for EdwardsGroupType {
|
||||
fn alloc<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<Fq>,
|
||||
>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(
|
||||
cs,
|
||||
|| Self::alloc_x_helper(value_gen),
|
||||
)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
}
|
||||
|
||||
fn alloc_input<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<Fq>,
|
||||
>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
let value =
|
||||
<EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc_input(
|
||||
cs,
|
||||
|| Self::alloc_x_helper(value_gen),
|
||||
)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for EdwardsGroupType {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
@ -166,3 +222,50 @@ impl ConditionalEqGadget<Fq> for EdwardsGroupType {
|
||||
2 * <EdwardsBlsGadget as ConditionalEqGadget<Fq>>::cost() //upper bound
|
||||
}
|
||||
}
|
||||
|
||||
// impl CondSelectGadget<Fq> for EdwardsGroupType {
|
||||
// fn conditionally_select<CS: ConstraintSystem<F>>(
|
||||
// mut cs: CS,
|
||||
// cond: &Boolean,
|
||||
// first: &Self,
|
||||
// second: &Self
|
||||
// ) -> Result<Self, SynthesisError> {
|
||||
// if let Boolean::Constant(cond) = *cond {
|
||||
// if cond { Ok(first.clone()) } else { Ok(second.clone()) }
|
||||
// } else {
|
||||
// let result = Self::a
|
||||
// // // c - c
|
||||
// // (EdwardsGroupType::Constant(first_value), EdwardsGroupType::Constant(other_value)) => {
|
||||
// // Ok(EdwardsGroupType::Constant(first_value.clone()))
|
||||
// // }
|
||||
// // // a - a
|
||||
// // (EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
// // return <EdwardsBlsGadget>::conditional_enforce_equal(
|
||||
// // self_value,
|
||||
// // cs,
|
||||
// // other_value,
|
||||
// // condition,
|
||||
// // )
|
||||
// // }
|
||||
// // // c - a = a - c
|
||||
// // (
|
||||
// // EdwardsGroupType::Constant(constant_value),
|
||||
// // EdwardsGroupType::Allocated(allocated_value),
|
||||
// // )
|
||||
// // | (
|
||||
// // EdwardsGroupType::Allocated(allocated_value),
|
||||
// // EdwardsGroupType::Constant(constant_value),
|
||||
// // ) => {
|
||||
// // let x = FpGadget::from(&mut cs, &constant_value.x);
|
||||
// // let y = FpGadget::from(&mut cs, &constant_value.y);
|
||||
// // let constant_gadget = EdwardsBlsGadget::new(x, y);
|
||||
// //
|
||||
// // constant_gadget.conditional_enforce_equal(cs, allocated_value, condition)
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fn cost() -> usize {
|
||||
// 2 * <EdwardsBlsGadget as CondSelectGadget<Fq>>::cost()
|
||||
// }
|
||||
// }
|
||||
|
@ -1,13 +1,15 @@
|
||||
use crate::errors::GroupError;
|
||||
use snarkos_models::curves::Field;
|
||||
use snarkos_models::gadgets::r1cs::ConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::alloc::AllocGadget;
|
||||
use snarkos_models::gadgets::utilities::eq::{ConditionalEqGadget, EqGadget};
|
||||
use std::fmt::Debug;
|
||||
// use snarkos_models::gadgets::utilities::select::CondSelectGadget;
|
||||
|
||||
pub mod edwards_bls12;
|
||||
|
||||
pub trait GroupType<NativeF: Field, F: Field>:
|
||||
Sized + Clone + Debug + EqGadget<F> + ConditionalEqGadget<F>
|
||||
Sized + Clone + Debug + EqGadget<F> + ConditionalEqGadget<F> + AllocGadget<String, F>
|
||||
{
|
||||
fn constant(string: String) -> Result<Self, GroupError>;
|
||||
|
||||
|
3
compiler/tests/group/input.leo
Normal file
3
compiler/tests/group/input.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(g: group) -> group {
|
||||
return g
|
||||
}
|
@ -1,12 +1,15 @@
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::group::edwards_bls12::EdwardsGroupType;
|
||||
use leo_compiler::ConstrainedValue;
|
||||
use leo_compiler::{ConstrainedValue, InputValue};
|
||||
|
||||
use snarkos_curves::edwards_bls12::EdwardsAffine;
|
||||
use snarkos_curves::edwards_bls12::{EdwardsAffine, Fq};
|
||||
use snarkos_models::curves::Group;
|
||||
|
||||
use crate::boolean::{output_false, output_true};
|
||||
use leo_compiler::errors::{CompilerError, FunctionError, StatementError};
|
||||
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::alloc::AllocGadget;
|
||||
use std::str::FromStr;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/group/";
|
||||
@ -14,7 +17,7 @@ const DIRECTORY_NAME: &str = "tests/group/";
|
||||
const TEST_POINT_1: &str = "(7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)";
|
||||
const TEST_POINT_2: &str = "(1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)";
|
||||
|
||||
fn output_expected(program: EdwardsTestCompiler, expected: EdwardsAffine) {
|
||||
fn output_expected_constant(program: EdwardsTestCompiler, expected: EdwardsAffine) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(EdwardsGroupType::Constant(
|
||||
@ -25,8 +28,19 @@ fn output_expected(program: EdwardsTestCompiler, expected: EdwardsAffine) {
|
||||
)
|
||||
}
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: EdwardsBlsGadget) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(
|
||||
EdwardsGroupType::Allocated(expected)
|
||||
)])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn output_zero(program: EdwardsTestCompiler) {
|
||||
output_expected(program, EdwardsAffine::zero())
|
||||
output_expected_constant(program, EdwardsAffine::zero())
|
||||
}
|
||||
|
||||
fn fail_enforce(program: EdwardsTestCompiler) {
|
||||
@ -48,7 +62,7 @@ fn test_zero() {
|
||||
fn test_point() {
|
||||
let point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let program = compile_program(DIRECTORY_NAME, "point.leo").unwrap();
|
||||
output_expected(program, point);
|
||||
output_expected_constant(program, point);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -61,7 +75,7 @@ fn test_add() {
|
||||
let sum = point_1.add(&point_2);
|
||||
|
||||
let program = compile_program(DIRECTORY_NAME, "add.leo").unwrap();
|
||||
output_expected(program, sum);
|
||||
output_expected_constant(program, sum);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -74,7 +88,7 @@ fn test_sub() {
|
||||
let sum = point_1.sub(&point_2);
|
||||
|
||||
let program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
|
||||
output_expected(program, sum);
|
||||
output_expected_constant(program, sum);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -100,3 +114,17 @@ fn test_assert_eq_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "assert_eq_false.leo").unwrap();
|
||||
fail_enforce(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
|
||||
program.set_inputs(vec![Some(InputValue::Group(TEST_POINT_1.into()))]);
|
||||
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let constant_point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let allocated_point =
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point))
|
||||
.unwrap();
|
||||
|
||||
output_expected_allocated(program, allocated_point)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user