Browse Source

*Actually* fix `to_affine` for SW points.

The prior PR (#9) multiplied by `self.z` instead of `self.z.inverse()`.
master
Pratyush Mishra 4 years ago
parent
commit
6077f51c97
1 changed files with 15 additions and 3 deletions
  1. +15
    -3
      src/groups/curves/short_weierstrass/mod.rs

+ 15
- 3
src/groups/curves/short_weierstrass/mod.rs

@ -156,12 +156,24 @@ where
let infinity = Boolean::constant(point.infinity); let infinity = Boolean::constant(point.infinity);
Ok(AffineVar::new(x, y, infinity)) Ok(AffineVar::new(x, y, infinity))
} else { } else {
let cs = self.cs();
let infinity = self.is_zero()?; let infinity = self.is_zero()?;
let zero_x = F::zero(); let zero_x = F::zero();
let zero_y = F::one(); let zero_y = F::one();
let non_zero_x = &self.x * &self.z;
let non_zero_y = &self.y * &self.z;
// 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 * &z_inv;
let non_zero_y = &self.y * &z_inv;
let x = infinity.select(&zero_x, &non_zero_x)?; let x = infinity.select(&zero_x, &non_zero_x)?;
let y = infinity.select(&zero_y, &non_zero_y)?; let y = infinity.select(&zero_y, &non_zero_y)?;

Loading…
Cancel
Save