mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
impl group cond_select
This commit is contained in:
parent
ad2d9f1192
commit
f144571530
@ -380,9 +380,11 @@ impl<
|
||||
Integer::conditionally_select(cs, &resolved_first, &integer_2, &integer_3)?;
|
||||
Ok(ConstrainedValue::Integer(result))
|
||||
}
|
||||
// (ConstrainedValue::GroupElement(group_2), ConstrainedValue::GroupElement(group_3)) => {
|
||||
// let result = Group
|
||||
// }
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
let result =
|
||||
GType::conditionally_select(cs, &resolved_first, &ge_1, &ge_2)?;
|
||||
Ok(ConstrainedValue::Group(result))
|
||||
}
|
||||
(_, _) => {
|
||||
unimplemented!("conditional select gadget not implemented between given types")
|
||||
}
|
||||
|
@ -7,10 +7,11 @@ use snarkos_errors::gadgets::SynthesisError;
|
||||
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::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 snarkos_models::gadgets::utilities::select::CondSelectGadget;
|
||||
use std::borrow::Borrow;
|
||||
use std::ops::Sub;
|
||||
use std::str::FromStr;
|
||||
@ -107,6 +108,19 @@ impl EdwardsGroupType {
|
||||
|
||||
Self::edwards_affine_from_str(affine_string).map_err(|_| SynthesisError::AssignmentMissing)
|
||||
}
|
||||
|
||||
pub fn allocated<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<EdwardsBlsGadget, SynthesisError> {
|
||||
match self {
|
||||
EdwardsGroupType::Constant(constant) => <EdwardsBlsGadget as AllocGadget<
|
||||
GroupAffine<EdwardsParameters>,
|
||||
Fq,
|
||||
>>::alloc(&mut cs.ns(|| format!("{:?}", constant)), || Ok(constant)),
|
||||
EdwardsGroupType::Allocated(allocated) => Ok(allocated.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AllocGadget<String, Fq> for EdwardsGroupType {
|
||||
@ -223,49 +237,30 @@ impl ConditionalEqGadget<Fq> for EdwardsGroupType {
|
||||
}
|
||||
}
|
||||
|
||||
// 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()
|
||||
// }
|
||||
// }
|
||||
impl CondSelectGadget<Fq> for EdwardsGroupType {
|
||||
fn conditionally_select<CS: ConstraintSystem<Fq>>(
|
||||
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 first_gadget = first.allocated(&mut cs)?;
|
||||
let second_gadget = second.allocated(&mut cs)?;
|
||||
let result =
|
||||
EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
}
|
||||
}
|
||||
|
||||
fn cost() -> usize {
|
||||
2 * <EdwardsBlsGadget as CondSelectGadget<Fq>>::cost()
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,20 @@ 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 snarkos_models::gadgets::utilities::select::CondSelectGadget;
|
||||
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> + AllocGadget<String, F>
|
||||
Sized
|
||||
+ Clone
|
||||
+ Debug
|
||||
+ EqGadget<F>
|
||||
+ ConditionalEqGadget<F>
|
||||
+ AllocGadget<String, F>
|
||||
+ CondSelectGadget<F>
|
||||
{
|
||||
fn constant(string: String) -> Result<Self, GroupError>;
|
||||
|
||||
|
@ -11,6 +11,7 @@ use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use snarkos_models::gadgets::utilities::alloc::AllocGadget;
|
||||
use std::str::FromStr;
|
||||
use snarkos_models::gadgets::curves::GroupGadget;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/group/";
|
||||
|
||||
@ -126,5 +127,49 @@ fn test_input() {
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point))
|
||||
.unwrap();
|
||||
|
||||
output_expected_allocated(program, allocated_point)
|
||||
output_expected_allocated(program, allocated_point);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ternary() {
|
||||
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();
|
||||
let mut program_2 = program_1.clone();
|
||||
|
||||
// true -> point_1
|
||||
program_1.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
|
||||
let point_1 = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let output_1 = get_output(program_1);
|
||||
let actual_1: EdwardsAffine = match output_1 {
|
||||
EdwardsConstrainedValue::Return(vec) => {
|
||||
match vec.as_slice() {
|
||||
[ConstrainedValue::Group(EdwardsGroupType::Allocated(edwards_gadget))] => {
|
||||
<EdwardsBlsGadget as GroupGadget<EdwardsAffine, Fq>>::get_value(edwards_gadget).unwrap()
|
||||
}
|
||||
_ => panic!("program output unknown return value")
|
||||
}
|
||||
},
|
||||
_ => panic!("program output unknown return value")
|
||||
};
|
||||
|
||||
assert_eq!(point_1, actual_1);
|
||||
|
||||
// false -> point_2
|
||||
program_2.set_inputs(vec![Some(InputValue::Boolean(false))]);
|
||||
|
||||
let point_2 = EdwardsAffine::from_str(TEST_POINT_2).unwrap();
|
||||
let output_2 = get_output(program_2);
|
||||
let actual_2: EdwardsAffine = match output_2 {
|
||||
EdwardsConstrainedValue::Return(vec) => {
|
||||
match vec.as_slice() {
|
||||
[ConstrainedValue::Group(EdwardsGroupType::Allocated(edwards_gadget))] => {
|
||||
<EdwardsBlsGadget as GroupGadget<EdwardsAffine, Fq>>::get_value(edwards_gadget).unwrap()
|
||||
}
|
||||
_ => panic!("program output unknown return value")
|
||||
}
|
||||
},
|
||||
_ => panic!("program output unknown return value")
|
||||
};
|
||||
|
||||
assert_eq!(point_2, actual_2);
|
||||
}
|
||||
|
6
compiler/tests/group/ternary.leo
Normal file
6
compiler/tests/group/ternary.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main (b: bool) -> group {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return if b ? point_1 : point_2
|
||||
}
|
Loading…
Reference in New Issue
Block a user