|
|
@ -22,6 +22,22 @@ impl FpGadget { |
|
|
|
pub fn from<CS: ConstraintSystem<F>>(mut cs: CS, value: &F) -> Self {
|
|
|
|
Self::alloc(cs.ns(|| "from"), || Ok(*value)).unwrap()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn is_constant(&self) -> bool {
|
|
|
|
match &self.variable {
|
|
|
|
// If you don't do alloc_constant, you are guaranteed to get a variable,
|
|
|
|
// hence we assume that all variables are not the constant variable.
|
|
|
|
// Technically this omits recognizing some constants.
|
|
|
|
// E.g. given variables w,x,y,z with constraints:
|
|
|
|
// w = x + 1
|
|
|
|
// y = -x + 1
|
|
|
|
// and then created the variable z = w + y,
|
|
|
|
// this would not recognize that z is in fact a constant.
|
|
|
|
// Since this is an edge case, this is left as a TODO.
|
|
|
|
Var(_v) => false,
|
|
|
|
LC(l) => l.is_constant(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<F: PrimeField> FieldGadget<F, F> for FpGadget<F> {
|
|
|
@ -145,6 +161,14 @@ impl FieldGadget for FpGadget { |
|
|
|
mut cs: CS,
|
|
|
|
other: &Self,
|
|
|
|
) -> Result<Self, SynthesisError> {
|
|
|
|
// Apply constant folding if it applies
|
|
|
|
// unwrap is used, because these values are guaranteed to exist.
|
|
|
|
if other.is_constant() {
|
|
|
|
return self.mul_by_constant(cs, &other.get_value().unwrap());
|
|
|
|
} else if self.is_constant() {
|
|
|
|
return other.mul_by_constant(cs, &self.get_value().unwrap());
|
|
|
|
}
|
|
|
|
|
|
|
|
let product = Self::alloc(cs.ns(|| "mul"), || {
|
|
|
|
Ok(self.value.get()? * &other.value.get()?)
|
|
|
|
})?;
|
|
|
|