use new integer gadgets

This commit is contained in:
collin 2020-06-04 14:32:30 -07:00
parent ab6ed9cfe6
commit c3f17e4dc9
3 changed files with 498 additions and 206 deletions

View File

@ -58,7 +58,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_add(cs, num_1, num_2)?)
Ok(ConstrainedValue::Integer(num_1.add(cs, num_2)?))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
Ok(ConstrainedValue::Field(fe_1.add(cs, &fe_2)?))
@ -89,7 +89,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_sub(cs, num_1, num_2)?)
Ok(ConstrainedValue::Integer(num_1.sub(cs, num_2)?))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
Ok(ConstrainedValue::Field(fe_1.sub(cs, &fe_2)?))
@ -120,7 +120,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_mul(cs, num_1, num_2)?)
Ok(ConstrainedValue::Integer(num_1.mul(cs, num_2)?))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
Ok(ConstrainedValue::Field(fe_1.mul(cs, &fe_2)?))
@ -150,7 +150,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_div(cs, num_1, num_2)?)
Ok(ConstrainedValue::Integer(num_1.div(cs, num_2)?))
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
Ok(ConstrainedValue::Field(fe_1.div(cs, &fe_2)?))
@ -179,7 +179,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
match (left, right) {
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::enforce_integer_pow(cs, num_1, num_2)?)
Ok(ConstrainedValue::Integer(num_1.pow(cs, num_2)?))
}
(ConstrainedValue::Unresolved(string), val_2) => {
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
@ -206,9 +206,9 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
(ConstrainedValue::Boolean(bool_1), ConstrainedValue::Boolean(bool_2)) => {
Ok(Self::boolean_eq(bool_1, bool_2))
}
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Ok(Self::evaluate_integer_eq(num_1, num_2)?)
}
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => Ok(
ConstrainedValue::Boolean(Boolean::Constant(num_1.eq(&num_2))),
),
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
Ok(ConstrainedValue::Boolean(Boolean::Constant(fe_1.eq(&fe_2))))
}
@ -820,7 +820,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
),
// Values
Expression::Integer(integer) => Ok(Self::get_integer_constant(integer)),
Expression::Integer(integer) => Ok(ConstrainedValue::Integer(integer)),
Expression::Field(field) => Ok(ConstrainedValue::Field(FieldType::constant(field)?)),
Expression::Group(group_affine) => {
Ok(ConstrainedValue::Group(G::constant(group_affine)?))

View File

@ -13,9 +13,11 @@ use snarkos_models::{
gadgets::{
r1cs::ConstraintSystem,
utilities::{
alloc::AllocGadget,
boolean::Boolean,
eq::{ConditionalEqGadget, EqGadget},
select::CondSelectGadget,
uint::{UInt128, UInt16, UInt32, UInt64, UInt8},
uint::{UInt, UInt128, UInt16, UInt32, UInt64, UInt8},
},
},
};
@ -40,6 +42,428 @@ impl Integer {
Integer::U128(_u128) => IntegerType::U128,
}
}
pub(crate) fn add<F: Field + PrimeField, CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
other: Self,
) -> Result<Self, IntegerError> {
Ok(match (self, other) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
let result = UInt8::addmany(
cs.ns(|| {
format!(
"enforce {} + {}",
left_u8.value.unwrap(),
right_u8.value.unwrap()
)
}),
&[left_u8, right_u8],
)?;
Integer::U8(result)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
let result = UInt16::addmany(
cs.ns(|| {
format!(
"enforce {} + {}",
left_u16.value.unwrap(),
right_u16.value.unwrap()
)
}),
&[left_u16, right_u16],
)?;
Integer::U16(result)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
let result = UInt32::addmany(
cs.ns(|| {
format!(
"enforce {} + {}",
left_u32.value.unwrap(),
right_u32.value.unwrap()
)
}),
&[left_u32, right_u32],
)?;
Integer::U32(result)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
let result = UInt64::addmany(
cs.ns(|| {
format!(
"enforce {} + {}",
left_u64.value.unwrap(),
right_u64.value.unwrap()
)
}),
&[left_u64, right_u64],
)?;
Integer::U64(result)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
let result = UInt128::addmany(
cs.ns(|| {
format!(
"enforce {} + {}",
left_u128.value.unwrap(),
right_u128.value.unwrap()
)
}),
&[left_u128, right_u128],
)?;
Integer::U128(result)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} + {}", left, right)))
}
})
}
pub(crate) fn sub<F: Field + PrimeField, CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
other: Self,
) -> Result<Self, IntegerError> {
Ok(match (self, other) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
let result = left_u8.sub(
cs.ns(|| {
format!(
"enforce {} - {}",
left_u8.value.unwrap(),
right_u8.value.unwrap()
)
}),
&right_u8,
)?;
Integer::U8(result)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
let result = left_u16.sub(
cs.ns(|| {
format!(
"enforce {} - {}",
left_u16.value.unwrap(),
right_u16.value.unwrap()
)
}),
&right_u16,
)?;
Integer::U16(result)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
let result = left_u32.sub(
cs.ns(|| {
format!(
"enforce {} - {}",
left_u32.value.unwrap(),
right_u32.value.unwrap()
)
}),
&right_u32,
)?;
Integer::U32(result)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
let result = left_u64.sub(
cs.ns(|| {
format!(
"enforce {} - {}",
left_u64.value.unwrap(),
right_u64.value.unwrap()
)
}),
&right_u64,
)?;
Integer::U64(result)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
let result = left_u128.sub(
cs.ns(|| {
format!(
"enforce {} - {}",
left_u128.value.unwrap(),
right_u128.value.unwrap()
)
}),
&right_u128,
)?;
Integer::U128(result)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} - {}", left, right)))
}
})
}
pub(crate) fn mul<F: Field + PrimeField, CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
other: Self,
) -> Result<Self, IntegerError> {
Ok(match (self, other) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
let result = left_u8.mul(
cs.ns(|| {
format!(
"enforce {} * {}",
left_u8.value.unwrap(),
right_u8.value.unwrap()
)
}),
&right_u8,
)?;
Integer::U8(result)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
let result = left_u16.mul(
cs.ns(|| {
format!(
"enforce {} * {}",
left_u16.value.unwrap(),
right_u16.value.unwrap()
)
}),
&right_u16,
)?;
Integer::U16(result)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
let result = left_u32.mul(
cs.ns(|| {
format!(
"enforce {} * {}",
left_u32.value.unwrap(),
right_u32.value.unwrap()
)
}),
&right_u32,
)?;
Integer::U32(result)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
let result = left_u64.mul(
cs.ns(|| {
format!(
"enforce {} * {}",
left_u64.value.unwrap(),
right_u64.value.unwrap()
)
}),
&right_u64,
)?;
Integer::U64(result)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
let result = left_u128.mul(
cs.ns(|| {
format!(
"enforce {} * {}",
left_u128.value.unwrap(),
right_u128.value.unwrap()
)
}),
&right_u128,
)?;
Integer::U128(result)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} * {}", left, right)))
}
})
}
pub(crate) fn div<F: Field + PrimeField, CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
other: Self,
) -> Result<Self, IntegerError> {
Ok(match (self, other) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
let result = left_u8.div(
cs.ns(|| {
format!(
"enforce {} / {}",
left_u8.value.unwrap(),
right_u8.value.unwrap()
)
}),
&right_u8,
)?;
Integer::U8(result)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
let result = left_u16.div(
cs.ns(|| {
format!(
"enforce {} / {}",
left_u16.value.unwrap(),
right_u16.value.unwrap()
)
}),
&right_u16,
)?;
Integer::U16(result)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
let result = left_u32.div(
cs.ns(|| {
format!(
"enforce {} / {}",
left_u32.value.unwrap(),
right_u32.value.unwrap()
)
}),
&right_u32,
)?;
Integer::U32(result)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
let result = left_u64.div(
cs.ns(|| {
format!(
"enforce {} / {}",
left_u64.value.unwrap(),
right_u64.value.unwrap()
)
}),
&right_u64,
)?;
Integer::U64(result)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
let result = left_u128.div(
cs.ns(|| {
format!(
"enforce {} / {}",
left_u128.value.unwrap(),
right_u128.value.unwrap()
)
}),
&right_u128,
)?;
Integer::U128(result)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} / {}", left, right)))
}
})
}
pub(crate) fn pow<F: Field + PrimeField, CS: ConstraintSystem<F>>(
self,
cs: &mut CS,
other: Self,
) -> Result<Self, IntegerError> {
Ok(match (self, other) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
let result = left_u8.pow(
cs.ns(|| {
format!(
"enforce {} ** {}",
left_u8.value.unwrap(),
right_u8.value.unwrap()
)
}),
&right_u8,
)?;
Integer::U8(result)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
let result = left_u16.pow(
cs.ns(|| {
format!(
"enforce {} ** {}",
left_u16.value.unwrap(),
right_u16.value.unwrap()
)
}),
&right_u16,
)?;
Integer::U16(result)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
let result = left_u32.pow(
cs.ns(|| {
format!(
"enforce {} ** {}",
left_u32.value.unwrap(),
right_u32.value.unwrap()
)
}),
&right_u32,
)?;
Integer::U32(result)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
let result = left_u64.pow(
cs.ns(|| {
format!(
"enforce {} ** {}",
left_u64.value.unwrap(),
right_u64.value.unwrap()
)
}),
&right_u64,
)?;
Integer::U64(result)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
let result = left_u128.pow(
cs.ns(|| {
format!(
"enforce {} ** {}",
left_u128.value.unwrap(),
right_u128.value.unwrap()
)
}),
&right_u128,
)?;
Integer::U128(result)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!(
"{} ** {}",
left, right
)))
}
})
}
}
impl<F: Field + PrimeField> EqGadget<F> for Integer {}
impl<F: Field + PrimeField> ConditionalEqGadget<F> for Integer {
fn conditional_enforce_equal<CS: ConstraintSystem<F>>(
&self,
cs: CS,
other: &Self,
condition: &Boolean,
) -> Result<(), SynthesisError> {
match (self, other) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
left_u8.conditional_enforce_equal(cs, right_u8, condition)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
left_u16.conditional_enforce_equal(cs, right_u16, condition)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
left_u32.conditional_enforce_equal(cs, right_u32, condition)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
left_u64.conditional_enforce_equal(cs, right_u64, condition)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
left_u128.conditional_enforce_equal(cs, right_u128, condition)
}
(_, _) => Err(SynthesisError::AssignmentMissing),
}
}
fn cost() -> usize {
<UInt128 as ConditionalEqGadget<F>>::cost()
}
}
impl<F: Field + PrimeField> CondSelectGadget<F> for Integer {
@ -75,31 +499,6 @@ impl<F: Field + PrimeField> CondSelectGadget<F> for Integer {
}
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<F, G> {
ConstrainedValue::Integer(integer)
}
pub(crate) fn evaluate_integer_eq(
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F, G>, IntegerError> {
Ok(ConstrainedValue::Boolean(Boolean::Constant(
match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => left_u8.eq(&right_u8),
(Integer::U16(left_u16), Integer::U16(right_u16)) => left_u16.eq(&right_u16),
(Integer::U32(left_u32), Integer::U32(right_u32)) => left_u32.eq(&right_u32),
(Integer::U64(left_u64), Integer::U64(right_u64)) => left_u64.eq(&right_u64),
(Integer::U128(left_u128), Integer::U128(right_u128)) => left_u128.eq(&right_u128),
(left, right) => {
return Err(IntegerError::CannotEvaluate(format!(
"{} == {}",
left, right
)))
}
},
)))
}
pub(crate) fn integer_from_parameter(
&mut self,
cs: &mut CS,
@ -120,176 +519,69 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
None => None,
};
match integer_type {
IntegerType::U8 => self.u8_from_input(cs, name, private, integer_option),
IntegerType::U16 => self.u16_from_input(cs, name, private, integer_option),
IntegerType::U32 => self.u32_from_input(cs, name, private, integer_option),
IntegerType::U64 => self.u64_from_input(cs, name, private, integer_option),
IntegerType::U128 => self.u128_from_input(cs, name, private, integer_option),
}
}
let integer_result = match integer_type {
IntegerType::U8 => {
let u8_option = integer_option.map(|integer| integer as u8);
let u8_result = match private {
true => UInt8::alloc(cs.ns(|| name), || {
u8_option.ok_or(SynthesisError::AssignmentMissing)
})?,
false => UInt8::alloc_input(cs.ns(|| name), || {
u8_option.ok_or(SynthesisError::AssignmentMissing)
})?,
};
Integer::U8(u8_result)
}
IntegerType::U16 => {
let u16_option = integer_option.map(|integer| integer as u16);
let u16_result = match private {
true => UInt16::alloc(cs.ns(|| name), || {
u16_option.ok_or(SynthesisError::AssignmentMissing)
})?,
false => UInt16::alloc_input(cs.ns(|| name), || {
u16_option.ok_or(SynthesisError::AssignmentMissing)
})?,
};
Integer::U16(u16_result)
}
IntegerType::U32 => {
let u32_option = integer_option.map(|integer| integer as u32);
let u32_result = match private {
true => UInt32::alloc(cs.ns(|| name), || {
u32_option.ok_or(SynthesisError::AssignmentMissing)
})?,
false => UInt32::alloc_input(cs.ns(|| name), || {
u32_option.ok_or(SynthesisError::AssignmentMissing)
})?,
};
Integer::U32(u32_result)
}
IntegerType::U64 => {
let u64_option = integer_option.map(|integer| integer as u64);
let u64_result = match private {
true => UInt64::alloc(cs.ns(|| name), || {
u64_option.ok_or(SynthesisError::AssignmentMissing)
})?,
false => UInt64::alloc_input(cs.ns(|| name), || {
u64_option.ok_or(SynthesisError::AssignmentMissing)
})?,
};
Integer::U64(u64_result)
}
IntegerType::U128 => {
let u128_option = integer_option.map(|integer| integer as u128);
let u128_result = match private {
true => UInt128::alloc(cs.ns(|| name), || {
u128_option.ok_or(SynthesisError::AssignmentMissing)
})?,
false => UInt128::alloc_input(cs.ns(|| name), || {
u128_option.ok_or(SynthesisError::AssignmentMissing)
})?,
};
Integer::U128(u128_result)
}
};
pub(crate) fn enforce_integer_eq(
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<(), IntegerError> {
match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Self::enforce_u8_eq(cs, left_u8, right_u8)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
Self::enforce_u16_eq(cs, left_u16, right_u16)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
Self::enforce_u32_eq(cs, left_u32, right_u32)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
Self::enforce_u64_eq(cs, left_u64, right_u64)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
Self::enforce_u128_eq(cs, left_u128, right_u128)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!(
"{} == {}",
left, right
)))
}
}
}
pub(crate) fn enforce_integer_add(
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F, G>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_add(cs, left_u8, right_u8)?)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
Integer::U16(Self::enforce_u16_add(cs, left_u16, right_u16)?)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
Integer::U32(Self::enforce_u32_add(cs, left_u32, right_u32)?)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
Integer::U64(Self::enforce_u64_add(cs, left_u64, right_u64)?)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
Integer::U128(Self::enforce_u128_add(cs, left_u128, right_u128)?)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} + {}", left, right)))
}
}))
}
pub(crate) fn enforce_integer_sub(
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F, G>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_sub(cs, left_u8, right_u8)?)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
Integer::U16(Self::enforce_u16_sub(cs, left_u16, right_u16)?)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
Integer::U32(Self::enforce_u32_sub(cs, left_u32, right_u32)?)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
Integer::U64(Self::enforce_u64_sub(cs, left_u64, right_u64)?)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
Integer::U128(Self::enforce_u128_sub(cs, left_u128, right_u128)?)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} - {}", left, right)))
}
}))
}
pub(crate) fn enforce_integer_mul(
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F, G>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_mul(cs, left_u8, right_u8)?)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
Integer::U16(Self::enforce_u16_mul(cs, left_u16, right_u16)?)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
Integer::U32(Self::enforce_u32_mul(cs, left_u32, right_u32)?)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
Integer::U64(Self::enforce_u64_mul(cs, left_u64, right_u64)?)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
Integer::U128(Self::enforce_u128_mul(cs, left_u128, right_u128)?)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} * {}", left, right)))
}
}))
}
pub(crate) fn enforce_integer_div(
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F, G>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_div(cs, left_u8, right_u8)?)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
Integer::U16(Self::enforce_u16_div(cs, left_u16, right_u16)?)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
Integer::U32(Self::enforce_u32_div(cs, left_u32, right_u32)?)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
Integer::U64(Self::enforce_u64_div(cs, left_u64, right_u64)?)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
Integer::U128(Self::enforce_u128_div(cs, left_u128, right_u128)?)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!("{} / {}", left, right)))
}
}))
}
pub(crate) fn enforce_integer_pow(
cs: &mut CS,
left: Integer,
right: Integer,
) -> Result<ConstrainedValue<F, G>, IntegerError> {
Ok(ConstrainedValue::Integer(match (left, right) {
(Integer::U8(left_u8), Integer::U8(right_u8)) => {
Integer::U8(Self::enforce_u8_pow(cs, left_u8, right_u8)?)
}
(Integer::U16(left_u16), Integer::U16(right_u16)) => {
Integer::U16(Self::enforce_u16_pow(cs, left_u16, right_u16)?)
}
(Integer::U32(left_u32), Integer::U32(right_u32)) => {
Integer::U32(Self::enforce_u32_pow(cs, left_u32, right_u32)?)
}
(Integer::U64(left_u64), Integer::U64(right_u64)) => {
Integer::U64(Self::enforce_u64_pow(cs, left_u64, right_u64)?)
}
(Integer::U128(left_u128), Integer::U128(right_u128)) => {
Integer::U128(Self::enforce_u128_pow(cs, left_u128, right_u128)?)
}
(left, right) => {
return Err(IntegerError::CannotEnforce(format!(
"{} ** {}",
left, right
)))
}
}))
Ok(ConstrainedValue::Integer(integer_result))
}
}

View File

@ -414,7 +414,7 @@ impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> Constraine
self.enforce_boolean_eq(cs, bool_1, bool_2)?
}
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
Self::enforce_integer_eq(cs, num_1, num_2)?
num_1.enforce_equal(cs, &num_2)?
}
(ConstrainedValue::Field(fe_1), ConstrainedValue::Field(fe_2)) => {
fe_1.enforce_equal(cs, &fe_2)?