diff --git a/ed448-goldilocks/src/edwards/affine.rs b/ed448-goldilocks/src/edwards/affine.rs index 9aadffdc4..d4c4213d3 100644 --- a/ed448-goldilocks/src/edwards/affine.rs +++ b/ed448-goldilocks/src/edwards/affine.rs @@ -388,39 +388,37 @@ impl CompressedEdwardsY { /// /// Returns `None` if the input is not the \\(y\\)-coordinate of a /// curve point. + // See https://www.rfc-editor.org/rfc/rfc8032.html#section-5.2.3. pub fn decompress_unchecked(&self) -> CtOption { // Safe to unwrap here as the underlying data structure is a slice let (sign, b) = self.0.split_last().expect("slice is non-empty"); let mut y_bytes: [u8; 56] = [0; 56]; y_bytes.copy_from_slice(b); - - // Recover x using y + // TODO: this should fail if unreduced. let y = FieldElement::from_bytes(&y_bytes); - let yy = y.square(); - let dyy = FieldElement::EDWARDS_D * yy; - let numerator = FieldElement::ONE - yy; - let denominator = FieldElement::ONE - dyy; - let (mut x, is_res) = FieldElement::sqrt_ratio(&numerator, &denominator); + // x^2 = (y^2 - 1) / (d y^2 - 1) + let yy = y.square(); + let u = yy - FieldElement::ONE; + let v = FieldElement::EDWARDS_D * yy - FieldElement::ONE; + let (mut x, is_square) = FieldElement::sqrt_ratio(&u, &v); // Compute correct sign of x let compressed_sign_bit = Choice::from(sign >> 7); let is_negative = x.is_negative(); x.conditional_negate(compressed_sign_bit ^ is_negative); - CtOption::new(AffinePoint { x, y }, is_res) + CtOption::new(AffinePoint { x, y }, is_square) } /// Attempt to decompress to an `AffinePoint`. /// /// Returns `None`: /// - if the input is not the \\(y\\)-coordinate of a curve point. - /// - if the input point is not on the curve. /// - if the input point has nonzero torsion component. pub fn decompress(&self) -> CtOption { self.decompress_unchecked() - .and_then(|pt| CtOption::new(pt, pt.is_on_curve() & pt.to_edwards().is_torsion_free())) } /// View this `CompressedEdwardsY` as an array of bytes. diff --git a/ed448-goldilocks/src/edwards/extended.rs b/ed448-goldilocks/src/edwards/extended.rs index f914abf43..95372af5a 100644 --- a/ed448-goldilocks/src/edwards/extended.rs +++ b/ed448-goldilocks/src/edwards/extended.rs @@ -961,8 +961,8 @@ mod tests { "13b6714c7a5f53101bbec88f2f17cd30f42e37fae363a5474efb4197ed6005df5861ae178a0c2c16ad378b7befed0d0904b7ced35e9f674180" ); let compressed = CompressedEdwardsY(bytes); - let decompressed = compressed.decompress(); - assert_eq!(decompressed.is_none().unwrap_u8(), 1u8); + let decompressed = compressed.decompress().unwrap(); + assert_eq!(decompressed.to_edwards().is_torsion_free().unwrap_u8(), 0u8); } #[test]