*Actually* fix to_affine for SW points.

The prior PR (#9) multiplied by `self.z` instead of `self.z.inverse()`.
This commit is contained in:
Pratyush Mishra
2020-11-11 23:02:56 -08:00
parent ceec513f62
commit 6077f51c97

View File

@@ -156,12 +156,24 @@ where
let infinity = Boolean::constant(point.infinity);
Ok(AffineVar::new(x, y, infinity))
} else {
let cs = self.cs();
let infinity = self.is_zero()?;
let zero_x = F::zero();
let zero_y = F::one();
// Allocate a variable whose value is either `self.z.inverse()` if the inverse exists,
// and is zero otherwise.
let z_inv = F::new_witness(ark_relations::ns!(cs, "z_inverse"), || {
Ok(self.z.value()?.inverse().unwrap_or(P::BaseField::zero()))
})?;
// The inverse exists if `!self.is_zero()`.
// This means that `z_inv * self.z = 1` if `self.is_not_zero()`, and
// `z_inv * self.z = 0` if `self.is_zero()`.
//
// Thus, `z_inv * self.z = !self.is_zero()`.
z_inv.mul_equals(&self.z, &F::from(infinity.not()))?;
let non_zero_x = &self.x * &self.z;
let non_zero_y = &self.y * &self.z;
let non_zero_x = &self.x * &z_inv;
let non_zero_y = &self.y * &z_inv;
let x = infinity.select(&zero_x, &non_zero_x)?;
let y = infinity.select(&zero_y, &non_zero_y)?;